nta.docs 21.7 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2
/* -*- c -*- */

3
/**@MODULEPAGE "nta" - SIP Transactions Module
Pekka Pessi's avatar
Pekka Pessi committed
4 5 6 7 8
 *
 * @section nta_meta Module Meta Information
 *
 * Sofia SIP Transaction API (nta) provides simple interface to the SIP
 * transaction, transport and message handling. The @b nta interface is
9 10 11
 * intended for both network and user elements. The public interface for @b
 * nta is mostly defined in <sofia-sip/nta.h>, but tag parameters are
 * defined in <sofia-sip/nta_tag.h>.
Pekka Pessi's avatar
Pekka Pessi committed
12 13 14
 *
 * @CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>
 *
15
 * @STATUS @SofiaSIP Core library
Pekka Pessi's avatar
Pekka Pessi committed
16 17 18 19
 *
 * @LICENSE LGPL
 *
 * @section nta_objects NTA Objects
20
 *
Pekka Pessi's avatar
Pekka Pessi committed
21 22 23 24
 * The NTA deals with a few kinds of objects: @e agent (#nta_agent_t), @e
 * call @e legs (#nta_leg_t), @e outgoing @e client @e requests
 * (#nta_outgoing_t), and @e incoming @e server @e requests
 * (#nta_incoming_t).
25
 *
Pekka Pessi's avatar
Pekka Pessi committed
26
 * NTA also uses SIP message objects #msg_t and #sip_t for handling
27 28 29
 * messages, as defined in <sofia-sip/msg.h> and <sofia-sip/sip.h>,
 * respectively. The various SIP headers are also defined in
 * <sofia-sip/sip.h>.
30
 *
Pekka Pessi's avatar
Pekka Pessi committed
31
 * @section nta_agent_t Creating an NTA Agent
32
 *
Pekka Pessi's avatar
Pekka Pessi committed
33 34 35
 * Most of the SIP entities, like @e user @e agent or @e proxy, consist of a
 * SIP server and a SIP client working together.  The NTA provides a simple
 * interface to SIP server and client with the #nta_agent_t objects.
36
 *
Pekka Pessi's avatar
Pekka Pessi committed
37 38
 * The #nta_agent_t object is created by calling nta_agent_create(). The
 * object listens for incoming connections, receives messages, parses them,
39 40
 * and pass them to the application. It also takes care of resolving the
 * domain names and sending the messages.
41
 *
Pekka Pessi's avatar
Pekka Pessi committed
42 43 44 45 46 47 48
 * The agent needs a #su_root_t object to schedule its execution. A root
 * object is used to wait for the network events, schedule the timer
 * routines, and pass messages asyncronously. A root object can be created
 * by, e.g., the function su_root_create(). The root object can be have its
 * own thread, or its main loop can be executed by an application thread by
 * calling the function su_root_run(). The main loop can be terminated by
 * calling the function su_root_break().
49
 *
Pekka Pessi's avatar
Pekka Pessi committed
50 51 52
 * A simple agent could be created as follows:
 * @code
 *  registrar->reg_root = su_root_create(NULL);
53
 *
Pekka Pessi's avatar
Pekka Pessi committed
54 55 56 57 58 59
 *  if (registrar->reg_root) {
 *    registrar->reg_agent = nta_agent_create(registrar->reg_root,
 *                                            (url_string_t*)argv[1],
 *                                            NULL,
 *                                            NULL,
 *                                            NULL);
60
 *
Pekka Pessi's avatar
Pekka Pessi committed
61 62 63 64
 *    if (registrar->reg_agent) {
 *      su_root_run(registrar->reg_root);
 *      nta_agent_destroy(registrar->reg_agent);
 *    }
65
 *
Pekka Pessi's avatar
Pekka Pessi committed
66 67 68
 *    su_root_destroy(registrar->reg_root);
 *  }
 * @endcode
69
 *
Pekka Pessi's avatar
Pekka Pessi committed
70
 * @section nta_server SIP Server Action
71
 *
Pekka Pessi's avatar
Pekka Pessi committed
72 73 74
 * A SIP server responds to the transactions sent by a client. The SIP
 * server can operate in two modes; it can be stateless or stateful. This
 * section describes how a stateful SIP server uses NTA.
75
 *
Pekka Pessi's avatar
Pekka Pessi committed
76
 * @subsection nta_leg_t The NTA Legs
77
 *
Pekka Pessi's avatar
Pekka Pessi committed
78 79 80 81
 * A leg is required for stateful transaction processing.  A default
 * leg is created like this:
 * @code
 * default_leg = nta_leg_tcreate(agent, process_requests, context,
82
 *                               URLTAG_URL(url),
Pekka Pessi's avatar
Pekka Pessi committed
83 84
 *                               NTATAG_NO_DIALOG(1),
 *                               TAG_END());
85 86
 * @endcode
 *
Pekka Pessi's avatar
Pekka Pessi committed
87 88 89 90
 * The @a url parameter is used to specify which URLs match to the leg. If
 * it is given, only requests with requestURI matching are processed by the
 * leg. The nta_leg_tcreate() is a @ref tagarg "tagarg" function, taking a
 * tagged argument list as its arguments.
91
 *
Pekka Pessi's avatar
Pekka Pessi committed
92 93 94
 * Other, ordinary legs can be used to match incoming requests with existing
 * dialogs, calls or transaction contexts, or to provide outgoing requests
 * with consistent headers. When a call leg is created, it is provided with
95 96
 * @From and @To headers, and optionally with other headers like
 * @CallID, @Route, or @CSeq.
97
 *
Pekka Pessi's avatar
Pekka Pessi committed
98 99 100 101 102
 * A new call leg can be created as follows:
 * @code
 * call_leg = nta_leg_tcreate(agent,
 *                            process_call_requests, call_context,
 *                            SIPTAG_CALL_ID(sip->sip_call_id),
103
 *                            SIPTAG_TO(sip->sip_from),
Pekka Pessi's avatar
Pekka Pessi committed
104 105 106 107
 *                            SIPTAG_FROM(sip->sip_to),
 *                            TAG_END());
 * @endcode
 *
108 109 110
 * @note In the example above, the @From and @To are reversed. This
 * happens if the headers are taken from an incoming request; the @From
 * and @To headers change direction when an outgoing request is initiated.
Pekka Pessi's avatar
Pekka Pessi committed
111 112 113 114
 *
 * @note An existing leg can be used in any direction, however.  If the leg
 * was created for an incoming INVITE transaction, it is also possible to
 * use the leg for an outgoing BYE transaction.
115
 *
Pekka Pessi's avatar
Pekka Pessi committed
116
 * @subsection nta_leg_tag Tagging the Call Leg
117
 *
118 119 120 121 122 123 124 125 126 127 128
 * All the SIP UAS elements are required to tag the @To header in their
 * final responses. The function nta_leg_tag() adds a tag to the leg's local
 * address. Local address is used as the @To header in the reply messages,
 * and as the @From header in the requests. The function nta_incoming_tag()
 * adds a tag to a incoming transaction. They are usually used in together,
 * using the tag from initial response to the dialog, too:
 * e.g.,
 * @code
 *   if (!nta_leg_tag(leg, nta_incoming_tag(irq, NULL)))
 *    nta_incoming_treply(irq, SIP_500_INTERNAL_SERVER_ERROR, TAG_END());
 * @endcode
129
 *
Pekka Pessi's avatar
Pekka Pessi committed
130
 * @subsection nta_incoming_t Incoming Transactions
131
 *
Pekka Pessi's avatar
Pekka Pessi committed
132 133
 * An incoming transaction object (nta_incoming_t) is created by NTA for
 * each unique incoming request message. When NTA has created the incoming
134 135 136
 * transaction object, it invokes the callback function provided with
 * nta_leg_tcreate().
 *
Pekka Pessi's avatar
Pekka Pessi committed
137 138 139 140
 * The simplest way to reply to the request is to return a valid status code
 * from the callback function. Valid status codes are in range of 100 to
 * 699, inclusive.  If no automatic response is desired, the callback
 * function should return 0.
141
 *
Pekka Pessi's avatar
Pekka Pessi committed
142 143 144
 * @note If the status code is final, the incoming transaction object will
 * be destroyed immediately after the callback function returns. It can not
 * be used afterwards.
145
 *
Pekka Pessi's avatar
Pekka Pessi committed
146 147
 * @note It is not possible to respond with a 2xx status code to an incoming
 * INVITE transaction by returning the status code from the callback.
148
 *
Pekka Pessi's avatar
Pekka Pessi committed
149 150 151
 * Valid return values for callback function are as follows:
 * @li 0, 100 .. 699 for requests other than INVITE, and
 * @li 0, 100 .. 199, 300..699 for INVITE requests.
152
 *
Pekka Pessi's avatar
Pekka Pessi committed
153 154 155
 * All other return codes are interpreted as 500, that is, a @e 500 @e
 * Internal @e Server @e Error reply message is sent back to the client and
 * the request is immediately destroyed.
156
 *
Pekka Pessi's avatar
Pekka Pessi committed
157 158 159 160 161 162 163 164 165
 * The simple registrar/redirect server may have a incoming request callback
 * as follows:
 * @code
 * int process_request(server_t *server,
 * 	               nta_leg_t *leg,
 * 	     	       nta_incoming_t *irq,
 * 	     	       sip_t const *sip)
 * {
 *   sip_contact_t *m;
166
 *
Pekka Pessi's avatar
Pekka Pessi committed
167 168 169
 *   switch (sip->sip_request->rq_method) {
 *   case sip_method_register:
 *     return registrar_add(server, leg, reply, sip);
170
 *
Pekka Pessi's avatar
Pekka Pessi committed
171 172
 *   case sip_method_ack:
 *     return 500;
173
 *
Pekka Pessi's avatar
Pekka Pessi committed
174 175
 *   case sip_method_cancel:
 *     return 200;
176
 *
Pekka Pessi's avatar
Pekka Pessi committed
177 178
 *   default:
 *     if (registrar_find(server, sip->sip_request->rq_url, &m) {
179
 *       nta_incoming_treply(irq, SIP_302_MOVED_TEMPORARILY,
Pekka Pessi's avatar
Pekka Pessi committed
180 181 182 183 184 185 186 187 188 189
 *                           SIPTAG_CONTACT(m), TAG_END());
 *       return 302;
 *     }
 *     else {
 *       nta_incoming_treply(irq, SIP_404_NOT_FOUND, TAG_END());
 *       return 404;
 *     }
 *   }
 * }
 * @endcode
190
 *
Pekka Pessi's avatar
Pekka Pessi committed
191
 * The default reply message will contain the status line with default
192
 * phrase, then @Via, @To, @From, @CallID, @CSeq, and @ContentLength headers.
Pekka Pessi's avatar
Pekka Pessi committed
193
 * If a more complex response message is required, the application should
194
 * respond using the function nta_incoming_treply():
Pekka Pessi's avatar
Pekka Pessi committed
195
 * @code
196
 * nta_incoming_treply(reply, SIP_200_OK,
Pekka Pessi's avatar
Pekka Pessi committed
197 198 199 200 201
 *                     SIPTAG_CONTACT(contact),
 *                     SIPTAG_CONTENT_TYPE_STR("application/sdp"),
 *                     SIPTAG_PAYLOAD(sdp),
 *                     TAG_END());
 * @endcode
202
 *
Pekka Pessi's avatar
Pekka Pessi committed
203 204
 * The nta_incoming_treply() is a @ref tagarg "tagarg" function, taking a
 * tagged argument list as its argument.
205
 *
Pekka Pessi's avatar
Pekka Pessi committed
206 207 208 209 210
 * @note It is possible to send provisional replies (containing 1xx status
 * codes) several times with nta_incoming_treply(), but only one final
 * reply (containing status codes 2xx..6xx) can be sent. However, with
 * INVITE requests, a proxy can send a final 2xx reply even after an error
 * reply (3xx..6xx).
211
 *
Pekka Pessi's avatar
Pekka Pessi committed
212
 * @section nta_100rel Reliable Provisional Responses - "100rel"
213
 *
Pekka Pessi's avatar
Pekka Pessi committed
214 215 216 217
 * The <A href="../specs/rfc3262.txt"><B>100rel</B></A> SIP extension
 * provides reliable provisional responses, provisional responses that are
 * retransmitted until a special acknowledgement request, PRACK, is
 * received. In addition the PRACK method, the extension defines two
218
 * headers, @RSeq and @RAck, that are used to identify different
Pekka Pessi's avatar
Pekka Pessi committed
219
 * response messages. PRACK method is usable on INVITE requests only.
220
 *
Pekka Pessi's avatar
Pekka Pessi committed
221
 * Using reliable responses is negotiated using the "100rel" option tag. The
222 223
 * UAC (party sending the INVITE) can include the option tag to the
 * @Supported or @Require header. In the first case, the UAC just
Pekka Pessi's avatar
Pekka Pessi committed
224 225 226 227 228
 * announces support for reliable responses, in the second case, the UAC
 * requires that the UAS (party responding to the call) always sends
 * provisional responses in reliable manner.
 *
 * When reliable responses are enabled with NTATAG_REL100() tag, the @b nta
229
 * engine automatically inserts the "100rel" option tag to the @Supported
Pekka Pessi's avatar
Pekka Pessi committed
230 231 232 233 234 235 236 237 238
 * header in the INVITE requests.
 *
 * @subsection nta_reliable_t Responding Reliably
 *
 * When a UAS wants to respond reliably to a INVITE request, instead of
 * familiar nta_incoming_treply() or nta_incoming_mreply() it uses the
 * functions nta_reliable_treply() or nta_reliable_mreply(). These functions
 * return a pointer to a special object, nta_reliable_t, that is used to
 * keep track of unacknowledged responses and respond to the the PRACK
239 240
 * acknowledgement request.
 *
Pekka Pessi's avatar
Pekka Pessi committed
241 242
 * Both the functions nta_reliable_treply () and nta_reliable_mreply() take
 * a callback funtion pointer and an application context pointer as their
243
 * arguments. The callback function is similar to the leg callback function.
Pekka Pessi's avatar
Pekka Pessi committed
244 245 246 247 248
 * The callback is invoked when a corresponding PRACK request is received,
 * or when there is a timeout.
 *
 * The @b nta takes care of assigning a serial number to each reliable
 * response and resending them if no PRACK request is received. It also
249
 * automatically adds the 100rel option tag to the @Require header.
Pekka Pessi's avatar
Pekka Pessi committed
250
 *
251
 * Also, if a request with 100rel in @Require header is responded with usual
Pekka Pessi's avatar
Pekka Pessi committed
252 253 254
 * nta_incoming_treply()/nta_incoming_mreply() functions, the @b nta creates
 * a reliable response object for each provisional response in behalf of
 * application. As the application can not provide a PRACK callback function
255
 * to @b nta, the PRACK requests are not delivered to the application.
Pekka Pessi's avatar
Pekka Pessi committed
256 257 258
 *
 * @subsection early_dialog UAC Receives a Reliable Response
 *
259
 * When a UAC receives a provisional response with a @RSeq header, it is
Pekka Pessi's avatar
Pekka Pessi committed
260 261 262 263
 * required to acknowledge it. In order to do that, it must establish an @e
 * early @e dialog with the UAS. In another view, a reliable response is
 * used to establish the early dialog. UAC establishes a leg object for the
 * early dialog by calling nta_leg_tcreate() with the parameters derived
264
 * from the response message.
Pekka Pessi's avatar
Pekka Pessi committed
265 266 267 268 269 270 271
 *
 * @code
 * int invite_callback(call_t *call,
 * 		    nta_outgoing_t *orq,
 * 		    sip_t const *sip)
 * {
 *   int status = sip->sip_status->st_status;
272 273
 *
 *   if (!call->has_dialog &&
Pekka Pessi's avatar
Pekka Pessi committed
274
 *       (status >= 200 || (status > 100 && sip->sip_rseq))) {
275
 *     nta_leg_t *early =
Pekka Pessi's avatar
Pekka Pessi committed
276 277 278 279 280 281
 *       nta_leg_tcreate(call->nta_agent, mid_dialog_request, call,
 * 		      SIPTAG_TO(sip->sip_to),
 * 		      SIPTAG_FROM(sip->sip_from),
 * 		      SIPTAG_CALL_ID(sip->sip_call_id),
 * 		      SIPTAG_CSEQ(sip->sip_cseq),
 * 		      TAG_END());
282 283
 *
 *     nta_leg_client_route(early,
Pekka Pessi's avatar
Pekka Pessi committed
284 285
 * 			 sip->sip_record_route,
 * 			 sip->sip_contact);
286
 *
Pekka Pessi's avatar
Pekka Pessi committed
287
 *     fork = call_fork(call, leg = early);
288
 *
Pekka Pessi's avatar
Pekka Pessi committed
289 290 291 292
 *     if (!fork) {
 *       handle error;
 *     }
 *     call = fork;
293
 *   }
Pekka Pessi's avatar
Pekka Pessi committed
294
 * @endcode
295
 *
Pekka Pessi's avatar
Pekka Pessi committed
296 297 298 299 300 301 302 303 304 305 306 307 308
 * The original dialog object and client transaction object are used to
 * process other call forks. For instance, if the early dialog is
 * established with an announcement server it will never lead to an fully
 * established call, but an another dialog will be used when the call is
 * completed.
 *
 * @subsection nta_prack Acknowledging Reliable Response
 *
 * After an early dialog has been established, acknowledging the reliable
 * response is trivial. The application can create a PRACK client
 * transaction object by calling nta_outgoing_prack()
 *
 * @section nta_client SIP Client Action
309
 *
Pekka Pessi's avatar
Pekka Pessi committed
310 311 312 313
 * A SIP client initiates the transactions. In some cases, a SIP client is
 * also required to invoke additional transactions, like @b ACK or @b
 * CANCEL, to finalize the original transaction. This section describes how
 * a SIP client uses NTA to make transactions.
314
 *
Pekka Pessi's avatar
Pekka Pessi committed
315
 * @subsection client_nta_leg_t Creating the Call Leg
316
 *
Pekka Pessi's avatar
Pekka Pessi committed
317 318 319 320 321 322 323 324 325 326
 * If the client does not have a suitable call leg, it must create it by
 * calling the function nta_leg_tcreate():
 * @code
 * context->leg = nta_leg_tcreate(agent,
 *                                callback, context,
 *                                SIPTAG_CALL_ID(call_id),
 *                                SIPTAG_FROM(from),
 *                                SIPTAG_TO(to),
 *                                TAG_END());
 * @endcode
327
 *
Pekka Pessi's avatar
Pekka Pessi committed
328 329 330 331
 * The @p callback function and @p context pointer are used for incoming
 * transactions, and they may be @c NULL if no such transactions are
 * expected.  If the callback is @c NULL, NTA responds to incoming
 * transactions with status @e 403 @e Forbidden.
332
 *
Pekka Pessi's avatar
Pekka Pessi committed
333 334
 * The @a call_id may be @c NULL or left out. In that case, NTA generates a
 * new call ID.
335
 *
Pekka Pessi's avatar
Pekka Pessi committed
336 337 338 339
 * The @a from and @a to are used in outgoing transactions. They are also
 * used to select which incoming messages belong to this leg.
 *
 * The initial sequence number can be supplied with SIPTAG_CSEQ() (taking a
340
 * @CSeq structure as parameter).
Pekka Pessi's avatar
Pekka Pessi committed
341 342 343
 *
 * The additional parameters (after @a to) are included in outgoing messages
 * using this leg. Currently, only @c SIPTAG_ROUTE() is supported.
344
 *
Pekka Pessi's avatar
Pekka Pessi committed
345
 * @note Additional tagged parameters are ignored.
346
 *
Pekka Pessi's avatar
Pekka Pessi committed
347
 * @subsection nta_outgoing_t Outgoing requests
348
 *
Pekka Pessi's avatar
Pekka Pessi committed
349 350 351 352 353 354 355 356 357 358
 * The outgoing request is created and sent by nta_outgoing_tcreate(). It
 * can be used as follows:
 * @code
 * oreq = nta_outgoing_tcreate(leg, response_to_register, reg,
 *                             proxy_url,
 *                             SIP_METHOD_REGISTER,
 *                             registrar_url,
 *                             SIPTAG_CONTACT(my_contact),
 *                             TAG_END());
 * @endcode
359
 *
Pekka Pessi's avatar
Pekka Pessi committed
360 361
 * NTA invokes the callback function response_to_register() each time a
 * provisional answer is received, and when a final answer is received.
362
 *
Pekka Pessi's avatar
Pekka Pessi committed
363
 * @note There may be multiple final answers to the INVITE request.
364
 *
Pekka Pessi's avatar
Pekka Pessi committed
365
 * If NTA does not receive answer in timely manner, it will generate a
366 367
 * @e 408 @e Timeout response and hand that back to the application.
 *
Pekka Pessi's avatar
Pekka Pessi committed
368 369 370
 * @note After a provisional answer to the INVITE request, no timeout will
 * occur inside NTA.  Application must itself timeout the INVITE
 * transactions if any answer has been received.
371
 *
Pekka Pessi's avatar
Pekka Pessi committed
372 373 374 375
 * The request can be destroyed with NTA function nta_outgoing_destroy().
 * If no final answer has been received, the request is cancelled when it is
 * destroyed, too.  The application can also cancel the outgoing request by
 * calling nta_outgoing_cancel().
376
 *
Pekka Pessi's avatar
Pekka Pessi committed
377
 * @subsection nta_ack Acknowledging Answers to INVITE
378
 *
Pekka Pessi's avatar
Pekka Pessi committed
379 380 381
 * The final answers to the INVITE request must be acknowledged. NTA takes
 * care of acknowledging automatically the 3xx..6xx answers; the appliction
 * must explicitly create a separate acknowledge transaction to final 2xx
382 383
 * answers.
 *
Pekka Pessi's avatar
Pekka Pessi committed
384 385 386 387 388 389 390 391 392 393
 * The final answer can be acknowledged like this:
 * @code
 *  url = sip->sip_contact ? sip->sip_contact->m_url : original_url;
 *  ack = nta_outgoing_tcreate(leg, NULL, NULL,
 *                             SIP_METHOD_ACK,
 *                             (url_string_t*)url,
 *                             SIPTAG_CSEQ(sip->sip_cseq),
 *                             SIPTAG_PAYLOAD(sdp),
 *                             TAG_END());
 * @endcode
394 395 396 397
 *
 * @note The ACK transaction should be sent to the @Contact specified in the
 * 2xx reply.
 *
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
 * <a name="nta_register_f"></a>
 * @section nta_stateless_callback Stateless Processing of SIP Messages
 *
 * When an NTA agent is created, it is possible to provide it with a
 * stateless callback function. The callback function will be called when an
 * incoming SIP request or response message does not match with an existing
 * transaction.
 *
 * Before invoking the stateless callback the agent will try to match the
 * incoming request message with an existing dialog or dialog-less leg (or
 * default leg). So, if you have created a default leg, all request messages
 * are processed statefully by it instead of being passed to the stateless
 * callback function.
 *
 * If you want to process request messages with stateless callback and still
 * use dialog-less legs (for instance, in order to look up domains with
 * nta_leg_by_uri()), you have to switch over to @em stateless @em mode by
 * including NTATAG_STATELESS(1) in nta_agent_create() or
 * nta_agent_set_params() arguments.
 *
 * Also, if a response message does not match with an existing client
 * transaction, the agent will try to use the default outgoing (client)
 * transaction. If you have created an default outgoing transaction, all
 * stray response messages are passed to it instead of the stateless
 * processing function.
 *
 * @section nta_message_f_example Stateless Callback Function
 *
 * In addition to the message (@a msg) and its
 * parsed contents (@a sip) the callback function gets the
Pekka Pessi's avatar
Pekka Pessi committed
428 429
 * application-specific context pointer (in this case, @a registrar) and a
 * pointer to the NTA agent (@a agent) as its arguments:
430 431
 *
 * @code
Pekka Pessi's avatar
Pekka Pessi committed
432 433 434 435 436
 * int process_message(nta_agent_context_t *registrar,
 * 		       nta_agent_t *agent,
 * 		       msg_t *msg,
 * 		       sip_t *sip);
 * @endcode
437
 *
Pekka Pessi's avatar
Pekka Pessi committed
438
 * The application has three functions that can be used to process the
439
 * messages in stateless manner:
Pekka Pessi's avatar
Pekka Pessi committed
440
 * @li nta_msg_discard() ignores and destroys the message,
441 442
 * @li nta_msg_tsend() forwards a request or response message, and
 * @li nta_msg_treply() replies to a request message in a stateless way.
443
 *
444 445 446 447 448 449
 * Additionally, it is possible to process a request message statefully with
 * nta_incoming_create().
 *
 * The functionality of the stateless callback function can vary greatly,
 * depending the purpose of the application. An user-agent, a proxy or a
 * registrar/redirect server each have very different callback functions.
450
 *
Pekka Pessi's avatar
Pekka Pessi committed
451 452
 * A simple redirect server could have a message callback function as
 * follows.
453
 *
Pekka Pessi's avatar
Pekka Pessi committed
454 455 456 457 458 459 460 461
 * @code
 * int process_message(redirect_t *r,
 * 		       nta_agent_t *agent,
 * 		       msg_t *msg,
 * 		       sip_t *sip)
 * {
 *   sip_contact_t *m;
 *   sip_unsupported_t *u;
462
 *
Pekka Pessi's avatar
Pekka Pessi committed
463 464
 * @endcode
 *
465
 * The incoming response messages are simply ignored. The @b ACK requests can
Pekka Pessi's avatar
Pekka Pessi committed
466
 * safely be discarded, too, because the redirect server keeps no state.
467
 *
Pekka Pessi's avatar
Pekka Pessi committed
468 469
 * @code
 *   if (!sip->sip_request || sip->sip_request->rq_method == sip_method_ack) {
470
 *     nta_msg_discard(agent, msg);
Pekka Pessi's avatar
Pekka Pessi committed
471 472 473 474 475 476 477 478 479
 *     return 0;
 *   }
 * @endcode
 *
 * Next, the redirect server first checks if processing the request requires
 * a feature that is not supported by it:
 * @code
 *   u = sip_unsupported(msg_home(msg), sip->sip_require, r->r_supported);
 *   if (u) {
480
 *     nta_msg_treply(agent, msg, SIP_420_BAD_EXTENSION,
Pekka Pessi's avatar
Pekka Pessi committed
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
 *                    SIPTAG_SUPPORTED(r->r_supported),
 *                    SIPTAG_UNSUPPORTED(u),
 *                    TAG_END());
 *     return 0;
 *   }
 * @endcode
 *
 * The @b CANCEL requests terminate a transacton. A stateless redirect
 * server does not have transactions, so it redirect replies with a @e 481
 * @e Call @e Leg/Transaction @e Does @e Not @e Exist message:
 * @code
 *   if (sip->sip_request->rq_method == sip_method_cancel) {
 *     nta_msg_treply(agent, msg, SIP_481_NO_TRANSACTION, TAG_END());
 *     return 0;
 *   }
 * @endcode
 *
498
 *  All other requests are answered normally with a 302 response.
499
 *  The location service is
Pekka Pessi's avatar
Pekka Pessi committed
500 501 502 503 504
 *  searched for the request uri, and if a matching address was found, a
 *  list of active bindings is returned to the client.
 * @code
 *   m = location_find(redirect, sip->sip_request->rq_url);
 *   if (m) {
505
 *     nta_msg_treply(agent, msg, SIP_302_MOVED_TEMPORARILY,
Pekka Pessi's avatar
Pekka Pessi committed
506 507
 *                    SIPTAG_CONTACT(m),
 *                    TAG_END());
508
 *   }
Pekka Pessi's avatar
Pekka Pessi committed
509 510 511 512 513 514 515
 * @endcode
 *
 *   Otherwise, @e 404 @e Not @e Found is sent:
 * @code
 *   else {
 *     nta_msg_treply(agent, msg, SIP_404_NOT_FOUND, TAG_END());
 *   }
516
 *
Pekka Pessi's avatar
Pekka Pessi committed
517 518 519
 *   return 0;
 * }
 * @endcode
520
 *
Pekka Pessi's avatar
Pekka Pessi committed
521 522 523
 */

/**@page internal NTA Semantics and Internal Data Flows
524
 *
Pekka Pessi's avatar
Pekka Pessi committed
525 526
 * NTA implements simple state machines at transaction level. The figure
 * below illustrates how a message is processed by NTA.
527 528 529 530 531
 *
 * @image html nta-receiving-message.gif "NTA processing incoming messages."
 * @image latex nta-receiving-message.eps "NTA processing incoming messages."
 *
 *
Pekka Pessi's avatar
Pekka Pessi committed
532 533 534 535 536 537 538 539 540
 */

int invite_callback(call_t *call,
		    nta_outgoing_t *orq,
		    sip_t const *sip)
{
  int status = sip->sip_status->st_status;
  nta_leg_t *leg = call->leg;

541
  if (!call->has_dialog &&
Pekka Pessi's avatar
Pekka Pessi committed
542
      (status >= 200 || (status > 100 && sip->sip_rseq))) {
543
    nta_leg_t *early =
Pekka Pessi's avatar
Pekka Pessi committed
544 545 546 547 548 549 550
      nta_leg_tcreate(call->nta_agent, mid_dialog_request, call,
		      SIPTAG_TO(sip->sip_to),
		      SIPTAG_FROM(sip->sip_from),
		      SIPTAG_CALL_ID(sip->sip_call_id),
		      SIPTAG_CSEQ(sip->sip_cseq),
		      TAG_END());

551
    nta_leg_client_route(early,
Pekka Pessi's avatar
Pekka Pessi committed
552 553 554 555 556 557 558 559 560
			 sip->sip_record_route,
			 sip->sip_contact);

    fork = call_fork(call, leg = early);

    if (!fork) {
      handle error;
    }
    call = fork;
561 562
  }

Pekka Pessi's avatar
Pekka Pessi committed
563
  if (status > 100 && status < 200 && sip->sip_rseq) {
564
    nta_outgoing_t *prack =
Pekka Pessi's avatar
Pekka Pessi committed
565
      nta_outgoing_prack(leg, orq, NULL, NULL, NULL,
566
			 sip,
Pekka Pessi's avatar
Pekka Pessi committed
567 568 569 570
			 TAG_END());
    nta_outgoing_destroy(prack);
    return 0;
  }
571

Pekka Pessi's avatar
Pekka Pessi committed
572 573
  ...
}