⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nta.docs

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 DOCS
📖 第 1 页 / 共 2 页
字号:
 *  *     if (!fork)爗 *       handle error; *     } *     call = fork; *   }				        * @endcode *  * 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 *  * 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. *  * @subsection client_nta_leg_t Creating the Call Leg *  * 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 *  * 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. *  * The @a call_id may be @c NULL or left out. In that case, NTA generates a * new call ID. *  * 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 * @CSeq structure as parameter). * * The additional parameters (after @a to) are included in outgoing messages * using this leg. Currently, only @c SIPTAG_ROUTE() is supported. *  * @note Additional tagged parameters are ignored. *  * @subsection nta_outgoing_t Outgoing requests *  * 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 *  * NTA invokes the callback function response_to_register() each time a * provisional answer is received, and when a final answer is received. *  * @note There may be multiple final answers to the INVITE request. *  * If NTA does not receive answer in timely manner, it will generate a * @e 408 @e Timeout response and hand that back to the application.  *  * @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. *  * 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(). *  * @subsection nta_ack Acknowledging Answers to INVITE *  * 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 * answers.  *  * 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 *  * @note The ACK transaction should be sent to the @Contact specified in the  * 2xx reply.   *  * <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 * application-specific context pointer (in this case, @a registrar) and a * pointer to the NTA agent (@a agent) as its arguments: *  * @code  * int process_message(nta_agent_context_t *registrar, * 		       nta_agent_t *agent, * 		       msg_t *msg, * 		       sip_t *sip); * @endcode *  * The application has three functions that can be used to process the * messages in stateless manner: * @li nta_msg_discard() ignores and destroys the message, * @li nta_msg_tsend() forwards a request or response message, and * @li nta_msg_treply() replies to a request message in a stateless way. *  * 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. *  * A simple redirect server could have a message callback function as * follows. * * @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; *  * @endcode * * The incoming response messages are simply ignored. The @b ACK requests can * safely be discarded, too, because the redirect server keeps no state. *  * @code *   if (!sip->sip_request || sip->sip_request->rq_method == sip_method_ack) { *     nta_msg_discard(agent, msg);  *     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) { *     nta_msg_treply(agent, msg, SIP_420_BAD_EXTENSION,  *                    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 * *  All other requests are answered normally with a 302 response.  *  The location service is *  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) { *     nta_msg_treply(agent, msg, SIP_302_MOVED_TEMPORARILY,  *                    SIPTAG_CONTACT(m), *                    TAG_END()); *   }  * @endcode * *   Otherwise, @e 404 @e Not @e Found is sent: * @code *   else { *     nta_msg_treply(agent, msg, SIP_404_NOT_FOUND, TAG_END()); *   } *  *   return 0; * } * @endcode *  *//**@page internal NTA Semantics and Internal Data Flows *  * NTA implements simple state machines at transaction level. The figure * below illustrates how a message is processed by NTA. *  * @image html nta-receiving-message.gif "NTA processing incoming messages."  * @image latex nta-receiving-message.eps "NTA processing incoming messages."  *  *  */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;  if (!call->has_dialog &&       (status >= 200 || (status > 100 && sip->sip_rseq))) {    nta_leg_t *early =       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());    nta_leg_client_route(early, 			 sip->sip_record_route,			 sip->sip_contact);    fork = call_fork(call, leg = early);    if (!fork)爗      handle error;    }    call = fork;  }				           if (status > 100 && status < 200 && sip->sip_rseq) {    nta_outgoing_t *prack =       nta_outgoing_prack(leg, orq, NULL, NULL, NULL,			 sip, 			 TAG_END());    nta_outgoing_destroy(prack);    return 0;  }    ...}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -