nua_handle_t * subscribe_to_nua(char const *event, tag_type_t tag, tag_value_t value, ...) { ta_list ta; struct event *subscribe; struct message *response; nua_handle_t *nh; nua_set_params(nua, NUTAG_APPL_METHOD("SUBSCRIBE"), SIPTAG_ALLOW_EVENTS_STR(event), TAG_END()); fail_unless_event(nua_r_set_params, 200); ta_start(ta, tag, value); s2_sip_request_to(dialog, SIP_METHOD_SUBSCRIBE, NULL, SIPTAG_EVENT_STR(event), ta_tags(ta)); ta_end(ta); subscribe = s2_wait_for_event(nua_i_subscribe, 100); nh = subscribe->nh; nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_SAVED(subscribe->event), TAG_END()); s2_free_event(subscribe); response = s2_sip_wait_for_response(202, SIP_METHOD_SUBSCRIBE); s2_sip_update_dialog(dialog, response); fail_unless(response->sip->sip_expires != NULL); s2_sip_free_message(response); return nh; }
static void mrcp_sofia_task_initialize(apt_task_t *task) { mrcp_sofia_agent_t *sofia_agent = apt_task_object_get(task); /* Initialize Sofia-SIP library and create event loop */ su_init(); sofia_agent->root = su_root_create(NULL); /* Create a user agent instance. The stack will call the 'event_callback()' * callback when events such as succesful registration to network, * an incoming call, etc, occur. */ sofia_agent->nua = nua_create( sofia_agent->root, /* Event loop */ mrcp_sofia_event_callback, /* Callback for processing events */ sofia_agent, /* Additional data to pass to callback */ NUTAG_URL(sofia_agent->sip_bind_str), /* Address to bind to */ TAG_END()); /* Last tag should always finish the sequence */ if(sofia_agent->nua) { nua_set_params( sofia_agent->nua, NUTAG_AUTOANSWER(0), NUTAG_APPL_METHOD("OPTIONS"), SIPTAG_USER_AGENT_STR(sofia_agent->config->user_agent_name), TAG_END()); } }
END_TEST START_TEST(client_2_0_1) { nta_outgoing_t *orq; struct message *request; struct event *response; S2_CASE("client-2.0.1", "Send MESSAGE", "Basic non-INVITE transaction with " "numeric per-transaction outbound proxy"); orq = nta_outgoing_tcreate(s2->default_leg, s2_nta_orq_callback, NULL, (url_string_t *)s2sip->contact->m_url, SIP_METHOD_MESSAGE, URL_STRING_MAKE("sip:test2.0.example.org"), SIPTAG_FROM_STR("<sip:[email protected]>"), TAG_END()); fail_unless(orq != NULL); request = s2_sip_wait_for_request(SIP_METHOD_MESSAGE); fail_unless(request != NULL); s2_sip_respond_to(request, NULL, 200, "OK 2.0.1", TAG_END()); response = s2_nta_wait_for(wait_for_orq, orq, wait_for_status, 200, 0); s2_sip_free_message(request); s2_nta_free_event(response); nta_outgoing_destroy(orq); }
static void nth_authentication_result(void *ai0, auth_status_t *as) { struct auth_info *ai = ai0; nth_request_t *req = ai->req; int status; if (as->as_status != 0) { assert(as->as_status >= 300); nth_request_treply(req, status = as->as_status, as->as_phrase, HTTPTAG_HEADER((http_header_t *)as->as_response), TAG_END()); } else { req->req_in_callback = 1; status = ai->site->site_callback(ai->site->site_magic, ai->site, ai->req, ai->http, ai->path); req->req_in_callback = 0; if (status != 0 && (status < 100 || status >= 600)) status = 500; if (status != 0 && req->req_status < 200) { nth_request_treply(req, status, NULL, TAG_END()); } } if (status >= 200 || req->req_destroyed) nth_request_destroy(req); }
END_TEST START_TEST(subscribe_6_1_3) { nua_handle_t *nh; struct message *response; struct event *notify, *event; S2_CASE("6.1.3", "Subscription terminated by notifier", "NUA sends SUBSCRIBE, waits for NOTIFY, " "gets NOTIFY terminating the subscription,"); nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END()); nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END()); notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END()); s2_free_event(notify); fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL, SIPTAG_EVENT_STR(event_type), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"), TAG_END())); event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event); fail_unless(s2_check_substate(event, nua_substate_terminated)); s2_free_event(event); response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY); fail_if(!response); s2_sip_free_message(response); nua_handle_destroy(nh); }
END_TEST START_TEST(fetch_6_2_3) { nua_handle_t *nh; struct message *subscribe; struct event *event; S2_CASE("6.2.3", "Event fetch - no NOTIFY", "NUA sends SUBSCRIBE with Expires 0, waits for NOTIFY, times out"); nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END()); nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END()); subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE); s2_sip_respond_to(subscribe, dialog, SIP_202_ACCEPTED, SIPTAG_EXPIRES_STR("0"), TAG_END()); s2_sip_free_message(subscribe); event = s2_wait_for_event(nua_r_subscribe, 202); fail_if(!event); fail_unless(s2_check_substate(event, nua_substate_embryonic)); s2_free_event(event); s2_nua_fast_forward(600, s2base->root); event = s2_wait_for_event(nua_i_notify, 408); fail_if(!event); fail_unless(s2_check_substate(event, nua_substate_terminated)); s2_free_event(event); nua_handle_destroy(nh); }
static void unsubscribe_by_nua(nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...) { struct message *subscribe, *response; struct event *event; nua_unsubscribe(nh, TAG_END()); subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE); s2_sip_respond_to(subscribe, dialog, SIP_200_OK, SIPTAG_EXPIRES_STR("0"), TAG_END()); event = s2_wait_for_event(nua_r_unsubscribe, 200); fail_if(!event); fail_unless(s2_check_substate(event, nua_substate_active)); s2_free_event(event); fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL, SIPTAG_EVENT(subscribe->sip->sip_event), SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=timeout"), SIPTAG_CONTENT_TYPE_STR(event_mime_type), SIPTAG_PAYLOAD_STR(event_state), TAG_END())); event = s2_wait_for_event(nua_i_notify, 200); fail_if(!event); fail_unless(s2_check_substate(event, nua_substate_terminated)); s2_free_event(event); response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY); fail_if(!response); s2_sip_free_message(response); s2_sip_free_message(subscribe); }
/** Register NUA user. * * <pre> * A B * |-----REGISTER---->| * |<-----200 OK------| * | | * </pre> */ void s2_register_setup(void) { nua_handle_t *nh; struct message *m; assert(s2 && s2->nua); assert(!s2->registration->nh); nh = nua_handle(s2->nua, NULL, TAG_END()); nua_register(nh, TAG_END()); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); assert(m); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), TAG_END()); s2_sip_free_message(m); assert(s2->registration->contact != NULL); fail_unless_event(nua_r_register, 200); s2->registration->nh = nh; }
END_TEST START_TEST(register_1_3_2_2) { nua_handle_t *nh = nua_handle(nua, NULL, TAG_END()); struct message *m; S2_CASE("1.3.2.2", "Register behind NAT with TCP", "Detect NAT over TCP using rport. " "Authenticate, detect NAT, " "close TCP at server, wait for re-REGISTERs."); nua_set_params(nua, NTATAG_TCP_RPORT(1), TAG_END()); fail_unless_event(nua_r_set_params, 200); mark_point(); s2->registration->nh = nh; make_auth_natted_register( nh, NUTAG_PROXY(s2sip->tcp.contact->m_url), NUTAG_OUTBOUND("no-options-keepalive, no-validate"), TAG_END()); fail_if(!tport_is_tcp(s2->registration->tport)); tport_shutdown(s2->registration->tport, 2); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_authorization); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted)), TAG_END()); s2_sip_free_message(m); /* The "NAT binding" changed when new TCP connection is established */ /* => NUA re-REGISTERs with newly detected contact */ fail_unless_event(nua_r_register, 100); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_authorization); fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted)), TAG_END()); s2_sip_free_message(m); fail_unless_event(nua_r_register, 200); fail_unless(s2->registration->contact != NULL); fail_if(s2->registration->contact->m_next != NULL); s2_register_teardown(); }
static void client_setup(void) { s2_nta_setup("NTA", NULL, TAG_END()); s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL, NTATAG_DEFAULT_PROXY("sip:example.org"), TAG_END()); }
static void pingpong_setup(void) { nua = s2_nua_setup("register with pingpong", TPTAG_PINGPONG(20000), TPTAG_KEEPALIVE(10000), TAG_END()); tport_set_params(s2sip->tcp.tport, TPTAG_PONG2PING(1), TAG_END()); }
END_TEST START_TEST(register_1_2_2_3) { nua_handle_t *nh = nua_handle(nua, NULL, TAG_END()); struct message *m; S2_CASE("1.2.2.3", "Register behind NAT", "Authenticate, outbound activated, " "detect NAT binding change when re-REGISTERing"); mark_point(); make_auth_natted_register(nh, NUTAG_OUTBOUND("no-options-keepalive, no-validate"), TAG_END()); s2->registration->nh = nh; s2_nua_fast_forward(3600, s2base->root); mark_point(); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_authorization); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted2)), TAG_END()); s2_sip_free_message(m); fail_unless_event(nua_r_register, 100); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_authorization); fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted2)), TAG_END()); s2_sip_free_message(m); fail_unless(s2->registration->contact != NULL); fail_if(s2->registration->contact->m_next != NULL); fail_unless_event(nua_r_register, 200); s2_register_teardown(); }
/** Set UAS flag value. * * The function nta_agent_set_uas() is used to set or clear User Agent * Server flag. * * Currently, the flag determines how the agent handles 2XX replies to an * incoming INVITE request. If flag is set, the agent resends the 2XX final * responses to an INVITE. * * @deprecated Use nta_agent_set_params() and NTATAG_UA() instead. */ int nta_agent_set_uas(nta_agent_t *agent, int value) { int retval = 1; nta_agent_set_params(agent, NTATAG_UA(value != 0), TAG_END()); nta_agent_get_params(agent, NTATAG_UA_REF(retval), TAG_END()); return retval; }
END_TEST /* ---------------------------------------------------------------------- */ START_TEST(register_1_3_1) { nua_handle_t *nh; struct message *m; S2_CASE("1.3.1", "Register over TCP via NAT", "REGISTER via TCP, detect NTA, re-REGISTER"); nh = nua_handle(nua, NULL, TAG_END()); nua_register(nh, NUTAG_PROXY(s2sip->tcp.contact->m_url), TAG_END()); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_contact || m->sip->sip_contact->m_next); fail_if(!tport_is_tcp(m->tport)); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted)), TAG_END()); s2_sip_free_message(m); assert(s2->registration->contact != NULL); fail_unless_event(nua_r_register, 100); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_contact || !m->sip->sip_contact->m_next); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted)), TAG_END()); s2_sip_free_message(m); fail_unless(s2->registration->contact != NULL); fail_if(s2->registration->contact->m_next != NULL); fail_unless( url_has_param(s2->registration->contact->m_url, "transport=tcp")); fail_unless_event(nua_r_register, 200); s2->registration->nh = nh; s2_register_teardown(); }
static void client_setup_tcp_only_server(void) { char const * const transports[] = { "tcp", NULL }; s2_nta_setup("NTA", transports, TAG_END()); s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL, NTATAG_DEFAULT_PROXY(s2sip->contact->m_url), TAG_END()); }
/** Set branch key. * * @deprecated Use nta_agent_set_params() and NTATAG_BRANCH_KEY() instead. */ msg_param_t nta_agent_set_branch(nta_agent_t *agent, msg_param_t branch) { msg_param_t retval = ""; nta_agent_set_params(agent, NTATAG_BRANCH_KEY(branch), TAG_END()); nta_agent_get_params(agent, NTATAG_BRANCH_KEY_REF(retval), TAG_END()); return retval; }
/** @internal Create a handle for processing incoming request */ nua_handle_t *nua_stack_incoming_handle(nua_t *nua, nta_incoming_t *irq, sip_t const *sip, int create_dialog) { nua_handle_t *nh; url_t const *url; sip_to_t to[1]; sip_from_t from[1]; assert(sip && sip->sip_from && sip->sip_to); if (sip->sip_contact) url = sip->sip_contact->m_url; else url = sip->sip_from->a_url; /* Strip away parameters */ sip_from_init(from)->a_display = sip->sip_to->a_display; *from->a_url = *sip->sip_to->a_url; sip_to_init(to)->a_display = sip->sip_from->a_display; *to->a_url = *sip->sip_from->a_url; nh = nh_create(nua, NUTAG_URL((url_string_t *)url), /* Remote target */ SIPTAG_TO(to), /* Local AoR */ SIPTAG_FROM(from), /* Remote AoR */ TAG_END()); if (nh && nua_stack_init_handle(nua, nh, NULL) < 0) nh_destroy(nua, nh), nh = NULL; if (nh && create_dialog) { struct nua_dialog_state *ds = nh->nh_ds; nua_dialog_store_peer_info(nh, ds, sip); ds->ds_leg = nta_leg_tcreate(nua->nua_nta, nua_stack_process_request, nh, SIPTAG_CALL_ID(sip->sip_call_id), SIPTAG_FROM(sip->sip_to), SIPTAG_TO(sip->sip_from), NTATAG_REMOTE_CSEQ(sip->sip_cseq->cs_seq), TAG_END()); if (!ds->ds_leg || !nta_leg_tag(ds->ds_leg, nta_incoming_tag(irq, NULL))) nh_destroy(nua, nh), nh = NULL; } if (nh) nua_dialog_uas_route(nh, nh->nh_ds, sip, 1); return nh; }
static struct event * subscription_by_nua(nua_handle_t *nh, enum nua_substate current, tag_type_t tag, tag_value_t value, ...) { struct message *subscribe; struct event *notify, *event; ta_list ta; enum nua_substate substate = nua_substate_active; char const *substate_str = subscription_state; char const *expires = "600"; subscribe = s2_sip_wait_for_request(SIP_METHOD_SUBSCRIBE); if (event_type) fail_if(!subscribe->sip->sip_event || strcmp(event_type, subscribe->sip->sip_event->o_type)); if (subscribe->sip->sip_expires && subscribe->sip->sip_expires->ex_delta == 0) { substate = nua_substate_terminated; substate_str = "terminated;reason=timeout"; expires = "0"; } ta_start(ta, tag, value); if (send_notify_before_response) { s2_sip_save_uas_dialog(dialog, subscribe->sip); notify = notify_to_nua(substate, SIPTAG_EVENT(subscribe->sip->sip_event), SIPTAG_SUBSCRIPTION_STATE_STR(substate_str), ta_tags(ta)); event = respond_to_subscribe(subscribe, nua_r_subscribe, substate, SIP_200_OK, SIPTAG_EXPIRES_STR(expires), TAG_END()); s2_free_event(event); } else { event = respond_to_subscribe(subscribe, nua_r_subscribe, current, SIP_202_ACCEPTED, SIPTAG_EXPIRES_STR(expires), TAG_END()); s2_free_event(event); notify = notify_to_nua(substate, SIPTAG_EVENT(subscribe->sip->sip_event), SIPTAG_SUBSCRIPTION_STATE_STR(substate_str), ta_tags(ta)); } s2_sip_free_message(subscribe); return notify; }
END_TEST static nua_handle_t *make_auth_natted_register( nua_handle_t *nh, tag_type_t tag, tag_value_t value, ...) { struct message *m; ta_list ta; ta_start(ta, tag, value); nua_register(nh, ta_tags(ta)); ta_end(ta); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); s2_sip_respond_to(m, NULL, SIP_401_UNAUTHORIZED, SIPTAG_WWW_AUTHENTICATE_STR(s2_auth_digest_str), SIPTAG_VIA(natted_via(m, receive_natted)), TAG_END()); s2_sip_free_message(m); fail_unless_event(nua_r_register, 401); /* NAT detected event */ fail_unless_event(nua_i_outbound, 101); nua_authenticate(nh, NUTAG_AUTH(s2_auth_credentials), TAG_END()); m = s2_sip_wait_for_request(SIP_METHOD_REGISTER); fail_if(!m); fail_if(!m->sip->sip_authorization); /* should not unregister the previous contact * as it has not been successfully registered */ fail_if(!m->sip->sip_contact); fail_if(m->sip->sip_contact->m_next); s2_save_register(m); s2_sip_respond_to(m, NULL, SIP_200_OK, SIPTAG_CONTACT(s2->registration->contact), SIPTAG_VIA(natted_via(m, receive_natted)), TAG_END()); s2_sip_free_message(m); assert(s2->registration->contact != NULL); fail_unless_event(nua_r_register, 200); return nh; }
/** Refresh subscription */ static void nua_subscribe_usage_refresh(nua_handle_t *nh, nua_dialog_state_t *ds, nua_dialog_usage_t *du, sip_time_t now) { nua_client_request_t *cr = du->du_cr; struct event_usage *eu = nua_dialog_usage_private(du); assert(eu); if (eu->eu_final_wait) { /* Did not receive NOTIFY for fetch */ sip_event_t const *o = du->du_event; char const *id = o ? o->o_id : NULL; SU_DEBUG_3(("nua(%p): event %s%s%s fetch timeouts\n", (void *)nh, o ? o->o_type : "(empty)", id ? "; id=" : "", id ? id : "")); nua_stack_tevent(nh->nh_nua, nh, NULL, nua_i_notify, 408, "Fetch Timeouts without NOTIFY", NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_EVENT(du->du_event), TAG_END()); nua_dialog_usage_remove(nh, ds, du, NULL, NULL); return; } if (cr) { if (nua_client_resend_request(cr, 0) >= 0) return; } else if (eu->eu_refer) { /* * XXX - If we have received a NOTIFY, we should try to terminate * subscription */ } if (!eu->eu_unsolicited) nua_stack_tevent(nh->nh_nua, nh, NULL, nua_i_notify, NUA_ERROR_AT(__FILE__, __LINE__), NUTAG_SUBSTATE(nua_substate_terminated), SIPTAG_EVENT(du->du_event), TAG_END()); nua_dialog_usage_remove(nh, ds, du, NULL, NULL); }
int nth_engine_get_params(nth_engine_t const *he, tag_type_t tag, tag_value_t value, ...) { int n; ta_list ta; msg_mclass_t const *mclass; if (he == NULL) return (errno = EINVAL), -1; if (he->he_mclass != http_default_mclass()) mclass = he->he_mclass; else mclass = NULL; ta_start(ta, tag, value); n = tl_tgets(ta_args(ta), NTHTAG_ERROR_MSG(he->he_error_msg), NTHTAG_MCLASS(mclass), NTHTAG_MFLAGS(he->he_mflags), NTHTAG_EXPIRES(he->he_expires), NTHTAG_STREAMING(he->he_streaming), NTHTAG_PROXY((url_string_t *) he->he_default_proxy), TAG_END()); ta_end(ta); return n; }
static apt_bool_t mrcp_sofia_session_offer(mrcp_session_t *session, mrcp_session_descriptor_t *descriptor) { char sdp_str[2048]; char *local_sdp_str = NULL; mrcp_sofia_session_t *sofia_session = session->obj; if(!sofia_session || !sofia_session->nh) { return FALSE; } if(session->signaling_agent) { mrcp_sofia_agent_t *sofia_agent = session->signaling_agent->obj; if(sofia_agent && sofia_agent->config->origin) { apt_string_set(&descriptor->origin,sofia_agent->config->origin); } } if(sdp_string_generate_by_mrcp_descriptor(sdp_str,sizeof(sdp_str),descriptor,TRUE) > 0) { local_sdp_str = sdp_str; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Local SDP\n%s", local_sdp_str); } nua_invite(sofia_session->nh, TAG_IF(local_sdp_str,SOATAG_USER_SDP_STR(local_sdp_str)), TAG_END()); return TRUE; }
int nth_site_get_params(nth_site_t const *site, tag_type_t tag, tag_value_t value, ...) { int n; ta_list ta; server_t *server; int master; msg_mclass_t const *mclass; if (site == NULL) return (errno = EINVAL), -1; server = site->site_server; master = site == server->srv_sites; if (master && server->srv_mclass != http_default_mclass()) mclass = server->srv_mclass; else mclass = NULL; ta_start(ta, tag, value); n = tl_tgets(ta_args(ta), TAG_IF(master, NTHTAG_MCLASS(mclass)), TAG_IF(master, NTHTAG_MFLAGS(server->srv_mflags)), TAG_END()); ta_end(ta); return n; }
int nth_engine_set_params(nth_engine_t * he, tag_type_t tag, tag_value_t value, ...) { int n; ta_list ta; unsigned expires; int error_msg; msg_mclass_t const *mclass; int mflags; int streaming; url_string_t const *proxy; if (he == NULL) return (errno = EINVAL), -1; ta_start(ta, tag, value); expires = he->he_expires; error_msg = he->he_error_msg; mclass = he->he_mclass; mflags = he->he_mflags; streaming = he->he_streaming; proxy = (void *) he->he_default_proxy; n = tl_gets(ta_args(ta), NTHTAG_EXPIRES_REF(expires), NTHTAG_ERROR_MSG_REF(error_msg), NTHTAG_MCLASS_REF(mclass), NTHTAG_MFLAGS_REF(mflags), NTHTAG_STREAMING_REF(streaming), NTHTAG_PROXY_REF(proxy), TAG_END()); if (n > 0) { if (proxy->us_url != he->he_default_proxy) { url_t *copy = url_hdup(he->he_home, proxy->us_url); if (proxy && !copy) { n = -1; } else { su_free(he->he_home, (void *) he->he_default_proxy); he->he_default_proxy = copy; } } } if (n > 0) { he->he_expires = expires; he->he_error_msg = error_msg != 0; if (mclass) he->he_mclass = mclass; else he->he_mclass = http_default_mclass(); he->he_mflags = mflags; he->he_streaming = streaming != 0; } ta_end(ta); return n; }
static void mrcp_sofia_on_session_ready( int status, mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh, mrcp_sofia_session_t *sofia_session, sip_t const *sip, tagi_t tags[]) { const char *local_sdp_str = NULL, *remote_sdp_str = NULL; mrcp_session_descriptor_t *descriptor = NULL; tl_gets(tags, SOATAG_LOCAL_SDP_STR_REF(local_sdp_str), SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str), TAG_END()); if(remote_sdp_str) { sdp_parser_t *parser = NULL; sdp_session_t *sdp = NULL; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Remote SDP\n%s", remote_sdp_str); parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0); sdp = sdp_session(parser); descriptor = mrcp_descriptor_generate_by_sdp_session(sdp,sofia_session->session->pool); sdp_parser_free(parser); } mrcp_session_answer(sofia_session->session,descriptor); }
/** * 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; }
static void mrcp_sofia_on_state_change( int status, mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh, mrcp_sofia_session_t *sofia_session, sip_t const *sip, tagi_t tags[]) { int nua_state = nua_callstate_init; tl_gets(tags, NUTAG_CALLSTATE_REF(nua_state), TAG_END()); if(!sofia_session || !sofia_session->session) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"SIP Call State [%s]", nua_callstate_name(nua_state)); return; } apt_obj_log(APT_LOG_MARK,APT_PRIO_NOTICE,sofia_session->session->log_obj,"SIP Call State %s [%s]", sofia_session->session->name, nua_callstate_name(nua_state)); switch(nua_state) { case nua_callstate_ready: mrcp_sofia_on_session_ready(status,sofia_agent,nh,sofia_session,sip,tags); break; case nua_callstate_terminated: mrcp_sofia_on_session_terminate(status,sofia_agent,nh,sofia_session,sip,tags); break; } sofia_session->nua_state = nua_state; }
static int soa_static_set_params(soa_session_t *ss, tagi_t const *tags) { soa_static_session_t *sss = (soa_static_session_t *)ss; char const *audio_aux = sss->sss_audio_aux; int ordered_user = sss->sss_ordered_user; int reuse_rejected = sss->sss_reuse_rejected; int n, m; n = tl_gets(tags, SOATAG_AUDIO_AUX_REF(audio_aux), SOATAG_ORDERED_USER_REF(ordered_user), SOATAG_REUSE_REJECTED_REF(reuse_rejected), TAG_END()); if (n > 0 && !su_casematch(audio_aux, sss->sss_audio_aux)) { char *s = su_strdup(ss->ss_home, audio_aux), *tbf = sss->sss_audio_aux; if (s == NULL && audio_aux != NULL) return -1; sss->sss_audio_aux = s; if (tbf) su_free(ss->ss_home, tbf); } sss->sss_ordered_user = ordered_user != 0; sss->sss_reuse_rejected = reuse_rejected != 0; m = soa_base_set_params(ss, tags); if (m < 0) return m; return n + m; }
static void mrcp_sofia_on_resource_discover( int status, mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh, mrcp_sofia_session_t *sofia_session, sip_t const *sip, tagi_t tags[]) { mrcp_session_t *session = sofia_session->session; if(session) { const char *remote_sdp_str = NULL; mrcp_session_descriptor_t *descriptor = NULL; tl_gets(tags, SOATAG_REMOTE_SDP_STR_REF(remote_sdp_str), TAG_END()); if(remote_sdp_str) { sdp_parser_t *parser = NULL; sdp_session_t *sdp = NULL; apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Resource Discovery SDP %s\n%s", session->name, remote_sdp_str); parser = sdp_parse(sofia_session->home,remote_sdp_str,(int)strlen(remote_sdp_str),0); sdp = sdp_session(parser); descriptor = mrcp_descriptor_generate_by_sdp_session(sdp,NULL,session->pool); sdp_parser_free(parser); } mrcp_session_discover_response(session,descriptor); } }
static void mrcp_sofia_on_state_change( int status, mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh, mrcp_sofia_session_t *sofia_session, sip_t const *sip, tagi_t tags[]) { int ss_state = nua_callstate_init; tl_gets(tags, NUTAG_CALLSTATE_REF(ss_state), TAG_END()); apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"SIP Call State %s [%s]", sofia_session ? sofia_session->session->name : "", nua_callstate_name(ss_state)); switch(ss_state) { case nua_callstate_ready: mrcp_sofia_on_session_ready(status,sofia_agent,nh,sofia_session,sip,tags); break; case nua_callstate_terminated: mrcp_sofia_on_session_terminate(status,sofia_agent,nh,sofia_session,sip,tags); break; } }