summaryrefslogtreecommitdiff
path: root/pjsip/include/pjsip/sip_transaction.h
blob: c0627aab0016d0d2327287d9fc28ca220f404d8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/* $Id$ */
/* 
 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#ifndef __PJSIP_SIP_TRANSACTION_H__
#define __PJSIP_SIP_TRANSACTION_H__

/**
 * @file sip_transaction.h
 * @brief SIP Transaction
 */

#include <pjsip/sip_msg.h>
#include <pjsip/sip_resolve.h>
#include <pj/timer.h>

PJ_BEGIN_DECL

/**
 * @defgroup PJSIP_TRANSACT SIP Transaction
 * @ingroup PJSIP
 * @{
 */

/* Forward decl. */
struct pjsip_transaction;


/**
 * Transaction state.
 */
typedef enum pjsip_tsx_state_e
{
    PJSIP_TSX_STATE_NULL,
    PJSIP_TSX_STATE_CALLING,
    PJSIP_TSX_STATE_TRYING,
    PJSIP_TSX_STATE_PROCEEDING,
    PJSIP_TSX_STATE_COMPLETED,
    PJSIP_TSX_STATE_CONFIRMED,
    PJSIP_TSX_STATE_TERMINATED,
    PJSIP_TSX_STATE_DESTROYED,
    PJSIP_TSX_STATE_MAX,
} pjsip_tsx_state_e;


/**
 * State of the transport in the transaction.
 * The transport is progressing independently of the transaction.
 */
typedef enum pjsip_tsx_transport_state_e
{
    PJSIP_TSX_TRANSPORT_STATE_NULL,
    PJSIP_TSX_TRANSPORT_STATE_RESOLVING,
    PJSIP_TSX_TRANSPORT_STATE_CONNECTING,
    PJSIP_TSX_TRANSPORT_STATE_FINAL,
} pjsip_tsx_transport_state_e;


/**
 * Transaction state.
 */
struct pjsip_transaction
{
    /*
     * Administrivia
     */
    pj_pool_t		       *pool;           /**< Pool owned by the tsx. */
    pjsip_endpoint	       *endpt;          /**< Endpoint instance.     */
    pj_mutex_t		       *mutex;          /**< Mutex for this tsx.    */
    char			obj_name[PJ_MAX_OBJ_NAME];  /**< Tsx name.  */
    int                         tracing;        /**< Tracing enabled?       */

    /*
     * Transaction identification.
     */
    pjsip_role_e		role;           /**< Role (UAS or UAC)      */
    pjsip_method		method;         /**< The method.            */
    int				cseq;           /**< The CSeq               */
    pj_str_t			transaction_key;/**< hash table key.        */
    pj_str_t			branch;         /**< The branch Id.         */

    /*
     * State and status.
     */
    int				status_code;    /**< Last status code seen. */
    pjsip_tsx_state_e		state;          /**< State.                 */
    int				handle_ack;     /**< Should we handle ACK?  */

    /** Handler according to current state. */
    pj_status_t (*state_handler)(struct pjsip_transaction *, pjsip_event *);

    /*
     * Transport.
     */
    pjsip_tsx_transport_state_e	transport_state;/**< Transport's state.     */
    pjsip_host_info		dest_name;      /**< Destination address.   */
    pjsip_server_addresses	remote_addr;    /**< Addresses resolved.    */
    int				current_addr;   /**< Address currently used. */

    pjsip_transport	       *transport;      /**< Transport to use.      */

    /*
     * Messages and timer.
     */
    pjsip_tx_data	       *last_tx;        /**< Msg kept for retrans.  */
    int				has_unsent_msg; /**< Non-zero if tsx need to 
                                                     transmit msg once resolver
                                                     completes.             */
    int				retransmit_count;/**< Retransmission count. */
    pj_timer_entry		retransmit_timer;/**< Retransmit timer.     */
    pj_timer_entry		timeout_timer;  /**< Timeout timer.         */

    /** Module specific data. */
    void		       *module_data[PJSIP_MAX_MODULE];
};


/**
 * Create new transaction. Application would normally use 
 * #pjsip_endpt_create_tsx rather than this function.
 *
 * @param pool	    Pool to use by the transaction.
 * @param endpt	    Endpoint.
 * @param p_tsx	    Pointer to return the transaction.
 *
 * @return	    PJ_SUCCESS or the appropriate error code.
 *
 * @see pjsip_endpt_create_tsx
 *
 */
PJ_DEF(pj_status_t) pjsip_tsx_create( pj_pool_t *pool,
				      pjsip_endpoint *endpt,
				      pjsip_transaction **p_tsx);

/** 
 * Init transaction as UAC from the specified transmit data (\c tdata).
 * The transmit data must have a valid \c Request-Line and \c CSeq header.
 * If \c Route headers are present, it will be used to calculate remote
 * destination.
 *
 * If \c Via header does not exist, it will be created along with a unique
 * \c branch parameter. If it exists and contains branch parameter, then
 * the \c branch parameter will be used as is as the transaction key.
 *
 * The \c Route headers in the transmit data, if present, are used to 
 * calculate remote destination.
 *
 * At the end of the function, the transaction will start resolving the
 * addresses of remote server to contact. Transport will be acquired as soon
 * as the resolving job completes.
 *
 * @param tsx       The transaction.
 * @param tdata     The transmit data.
 *
 * @return          PJ_SUCCESS if successfull.
 */
PJ_DECL(pj_status_t) pjsip_tsx_init_uac( pjsip_transaction *tsx, 
					 pjsip_tx_data *tdata);

/**
 * Init transaction as UAS.
 *
 * @param tsx       The transaction to be initialized.
 * @param rdata     The received incoming request.
 *
 * @return PJ_SUCCESS if successfull.
 */
PJ_DECL(pj_status_t) pjsip_tsx_init_uas( pjsip_transaction *tsx,
					 pjsip_rx_data *rdata);

/**
 * Process incoming message for this transaction.
 *
 * @param tsx       The transaction.
 * @param rdata     The incoming message.
 */
PJ_DECL(void) pjsip_tsx_on_rx_msg( pjsip_transaction *tsx,
				   pjsip_rx_data *rdata);

/**
 * Transmit message with this transaction.
 *
 * @param tsx       The transaction.
 * @param tdata     The outgoing message.
 */
PJ_DECL(void) pjsip_tsx_on_tx_msg( pjsip_transaction *tsx,
				   pjsip_tx_data *tdata);


/**
 * Transmit ACK message for 2xx/INVITE with this transaction. The ACK for
 * non-2xx/INVITE is automatically sent by the transaction.
 * This operation is only valid if the transaction is configured to handle ACK
 * (tsx->handle_ack is non-zero). If this attribute is not set, then the
 * transaction will comply with RFC-3261, i.e. it will set itself to 
 * TERMINATED state when it receives 2xx/INVITE.
 *
 * @param tsx       The transaction.
 * @param tdata     The ACK request.
 */
PJ_DECL(void) pjsip_tsx_on_tx_ack( pjsip_transaction *tsx,
				   pjsip_tx_data *tdata);

/**
 * Force terminate transaction.
 *
 * @param tsx       The transaction.
 * @param code      The status code to report.
 */
PJ_DECL(void) pjsip_tsx_terminate( pjsip_transaction *tsx,
				   int code );

/**
 * Create transaction key, which is used to match incoming requests 
 * or response (retransmissions) against transactions.
 *
 * @param pool      The pool
 * @param key       Output key.
 * @param role      The role of the transaction.
 * @param method    The method to be put as a key. 
 * @param rdata     The received data to calculate.
 *
 * @return          PJ_SUCCESS or the appropriate error code.
 */
PJ_DECL(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool,
				           pj_str_t *key,
				           pjsip_role_e role,
				           const pjsip_method *method,
				           const pjsip_rx_data *rdata );


/**
 * @}
 */

/*
 * Internal.
 */

/*
 * Get the string name for the state.
 */
PJ_DECL(const char *) pjsip_tsx_state_str(pjsip_tsx_state_e state);

/*
 * Get the role name.
 */
PJ_DECL(const char *) pjsip_role_name(pjsip_role_e role);


/* Thread Local Storage ID for transaction lock (initialized by endpoint) */
extern long pjsip_tsx_lock_tls_id;

PJ_END_DECL

#endif	/* __PJSIP_TRANSACT_H__ */