/** * Create a new leg object for incoming request message. * * @param agent agent object * @param callback function which is called for each * incoming request belonging to this leg * @param magic call leg context * @param msg a request message * * @note The ownership of @a msg will pass back to NTA upon successful call * to the function nta_msg_leg(). In other words, if the call to @a * nta_msg_leg() is successful, the application may not do anything with @a * msg anymore. Instead of that, NTA will create of a new incoming request * object for the @a msg and eventually return the request to application by * calling the @a callback function. * * @deprecated Use nta_leg_stateful() instead. */ nta_leg_t *nta_msg_leg(nta_agent_t *agent, msg_t *msg, nta_request_f *callback, nta_leg_magic_t *magic, ...) { nta_leg_t *leg; sip_t *sip = sip_object(msg); SU_DEBUG_9(("\tnta_msg_leg(): called\n")); assert(msg && sip && sip->sip_request); if (!msg || !sip || !sip->sip_request || !callback) return NULL; leg = nta_leg_tcreate(agent, callback, magic, SIPTAG_CALL_ID(sip->sip_call_id), SIPTAG_FROM(sip->sip_to), /* local address */ SIPTAG_TO(sip->sip_from), /* remote address */ TAG_END()); if (!leg) /* xyzzy */; else if (nta_leg_server_route(leg, sip->sip_record_route, sip->sip_contact) < 0) nta_leg_destroy(leg), leg = NULL; else if (nta_leg_stateful(leg, msg) < 0) nta_leg_destroy(leg), leg = NULL; SU_DEBUG_9(("\tnta_msg_leg(): returns %p\n", leg)); return leg; }
/**@internal * UAS tag and route. * * Update dialog tags and route on the UAS side. * * @param own dialog owner * @param ds dialog state * @param sip SIP message containing response used to update dialog * @param rtag if true, set remote tag within the leg */ void nua_dialog_uas_route(nua_owner_t *own, nua_dialog_state_t *ds, sip_t const *sip, int rtag) { int established = nua_dialog_is_established(ds); if (!established && sip->sip_from->a_tag) ds->ds_remote_tag = su_strdup(own, sip->sip_from->a_tag); if (ds->ds_leg == NULL) return; nta_leg_server_route(ds->ds_leg, sip->sip_record_route, sip->sip_contact); ds->ds_route = ds->ds_route || sip->sip_record_route || sip->sip_contact; if (rtag && !established && sip->sip_from->a_tag) nta_leg_rtag(ds->ds_leg, sip->sip_from->a_tag); }
int DrachtioController::processRequestOutsideDialog( nta_leg_t* defaultLeg, nta_incoming_t* irq, sip_t const *sip) { DR_LOG(log_debug) << "processRequestOutsideDialog" << endl ; int rc = validateSipMessage( sip ) ; if( 0 != rc ) { return rc ; } switch (sip->sip_request->rq_method ) { case sip_method_invite: { /* TODO: should support optional config to only allow invites from defined addresses */ /* system-wide minimum session-expires is 90 seconds */ if( sip->sip_session_expires && sip->sip_session_expires->x_delta < 90 ) { nta_incoming_treply( irq, SIP_422_SESSION_TIMER_TOO_SMALL, SIPTAG_MIN_SE_STR("90"), TAG_END() ) ; return 0; } string transactionId ; generateUuid( transactionId ) ; nta_incoming_treply( irq, SIP_100_TRYING, TAG_END() ) ; if( !m_pClientController->route_request_outside_dialog( irq, sip, transactionId ) ) { DR_LOG(log_error) << "No providers available for invite" << endl ; return 503 ; } nta_leg_t* leg = nta_leg_tcreate(m_nta, legCallback, this, SIPTAG_CALL_ID(sip->sip_call_id), SIPTAG_CSEQ(sip->sip_cseq), SIPTAG_TO(sip->sip_from), SIPTAG_FROM(sip->sip_to), TAG_END()); if( NULL == leg ) { DR_LOG(log_error) << "Error creating a leg for origination" << endl ; //TODO: we got a client out there with a dead INVITE now... return 500 ; } boost::shared_ptr<SipDialog> dlg = boost::make_shared<SipDialog>( leg, irq, sip ) ; dlg->setTransactionId( transactionId ) ; string contactStr ; generateOutgoingContact( sip->sip_contact, contactStr ) ; nta_leg_server_route( leg, sip->sip_record_route, sip->sip_contact ) ; m_pDialogController->addIncomingInviteTransaction( leg, irq, sip, transactionId, dlg ) ; } break ; case sip_method_ack: /* success case: call has been established */ nta_incoming_destroy( irq ) ; return 0 ; case sip_method_register: case sip_method_message: case sip_method_options: case sip_method_notify: { string transactionId ; generateUuid( transactionId ) ; if( !m_pClientController->route_request_outside_dialog( irq, sip, transactionId ) ) { DR_LOG(log_error) << "No providers available for register" << endl ; return 503 ; } m_pDialogController->addIncomingRequestTransaction( irq, transactionId ) ; return 0 ; } case sip_method_bye: case sip_method_cancel: DR_LOG(log_error) << "Received BYE or CANCEL for unknown dialog: " << sip->sip_call_id->i_id << endl ; return 481 ; default: DR_LOG(log_error) << "DrachtioController::processRequestOutsideDialog - unsupported method type: " << sip->sip_request->rq_method_name << ": " << sip->sip_call_id->i_id << endl ; return 501 ; break ; } return 0 ; }