diff options
Diffstat (limited to 'tinyDEMO/common.c')
-rwxr-xr-x | tinyDEMO/common.c | 1408 |
1 files changed, 694 insertions, 714 deletions
diff --git a/tinyDEMO/common.c b/tinyDEMO/common.c index 386fed3..92e19c7 100755 --- a/tinyDEMO/common.c +++ b/tinyDEMO/common.c @@ -2,19 +2,19 @@ * Copyright (C) 2009 Mamadou Diop. * * Contact: Mamadou Diop <diopmamadou(at)doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. * @@ -56,544 +56,524 @@ int session_tostring(const session_t* session); /* our SIP callback function */ int stack_callback(const tsip_event_t *_event) { - int ret = 0; + int ret = 0; - if(!_event){ /* should never happen ...but who know? */ - TSK_DEBUG_WARN("Null SIP event."); - return -1; - } + if(!_event) { /* should never happen ...but who know? */ + TSK_DEBUG_WARN("Null SIP event."); + return -1; + } #if 0 - tsk_safeobj_lock(ctx); + tsk_safeobj_lock(ctx); #endif - switch(_event->type){ - case tsip_event_register: - { /* REGISTER */ - ret = register_handle_event(_event); - break; - } - case tsip_event_invite: - { /* INVITE */ - ret = invite_handle_event(_event); - break; - } - case tsip_event_message: - { /* MESSAGE */ - ret = message_handle_event(_event); - break; - } - case tsip_event_options: - { /* OPTIONS */ - ret = options_handle_event(_event); - break; - } - case tsip_event_publish: - { /* PUBLISH */ - ret = publish_handle_event(_event); - break; - } - case tsip_event_subscribe: - { /* SUBSCRIBE */ - ret = subscribe_handle_event(_event); - break; - } - - case tsip_event_dialog: - { /* Common to all dialogs */ - ret = session_handle_event(_event); - break; - } - - case tsip_event_stack: - { - switch(_event->code){ - case tsip_event_code_stack_started: - TSK_DEBUG_INFO("Stack started"); - break; - case tsip_event_code_stack_stopped: - TSK_DEBUG_INFO("Stack stopped"); - break; - case tsip_event_code_stack_failed_to_start: - TSK_DEBUG_INFO("Stack failed to start"); - break; - case tsip_event_code_stack_failed_to_stop: - TSK_DEBUG_INFO("Stack failed to stop"); - break; - } - break; - } - - default: - { /* Unsupported */ - TSK_DEBUG_WARN("%d not supported as SIP event.", _event->type); - ret = -3; - break; - } - } + switch(_event->type) { + case tsip_event_register: { + /* REGISTER */ + ret = register_handle_event(_event); + break; + } + case tsip_event_invite: { + /* INVITE */ + ret = invite_handle_event(_event); + break; + } + case tsip_event_message: { + /* MESSAGE */ + ret = message_handle_event(_event); + break; + } + case tsip_event_options: { + /* OPTIONS */ + ret = options_handle_event(_event); + break; + } + case tsip_event_publish: { + /* PUBLISH */ + ret = publish_handle_event(_event); + break; + } + case tsip_event_subscribe: { + /* SUBSCRIBE */ + ret = subscribe_handle_event(_event); + break; + } + + case tsip_event_dialog: { + /* Common to all dialogs */ + ret = session_handle_event(_event); + break; + } + + case tsip_event_stack: { + switch(_event->code) { + case tsip_event_code_stack_started: + TSK_DEBUG_INFO("Stack started"); + break; + case tsip_event_code_stack_stopped: + TSK_DEBUG_INFO("Stack stopped"); + break; + case tsip_event_code_stack_failed_to_start: + TSK_DEBUG_INFO("Stack failed to start"); + break; + case tsip_event_code_stack_failed_to_stop: + TSK_DEBUG_INFO("Stack failed to stop"); + break; + } + break; + } + + default: { + /* Unsupported */ + TSK_DEBUG_WARN("%d not supported as SIP event.", _event->type); + ret = -3; + break; + } + } #if 0 - tsk_safeobj_unlock(ctx); + tsk_safeobj_unlock(ctx); #endif - return ret; + return ret; } /* ================================================================== - ========================== Context ================================= + ========================== Context ================================= */ ctx_t* ctx_create() { - return tsk_object_new(ctx_def_t); + return tsk_object_new(ctx_def_t); } static tsk_object_t* ctx_ctor(tsk_object_t * self, va_list * app) { - ctx_t *ctx = self; - if(ctx){ - /* stack */ - ctx->stack = tsip_stack_create(stack_callback, DEFAULT_REALM, DEFAULT_IMPI, DEFAULT_IMPU, /* Mandatory parameters */ - TSIP_STACK_SET_LOCAL_IP(DEFAULT_LOCAL_IP), /* local IP */ - TSIP_STACK_SET_NULL() /* Mandatory */); - - /* SIP Sessions */ - ctx->sessions = tsk_list_create(); - - /* user's parameters */ - ctx->params = tsk_list_create(); - - /* init internal mutex */ - tsk_safeobj_init(ctx); - } - return self; + ctx_t *ctx = self; + if(ctx) { + /* stack */ + ctx->stack = tsip_stack_create(stack_callback, DEFAULT_REALM, DEFAULT_IMPI, DEFAULT_IMPU, /* Mandatory parameters */ + TSIP_STACK_SET_LOCAL_IP(DEFAULT_LOCAL_IP), /* local IP */ + TSIP_STACK_SET_NULL() /* Mandatory */); + + /* SIP Sessions */ + ctx->sessions = tsk_list_create(); + + /* user's parameters */ + ctx->params = tsk_list_create(); + + /* init internal mutex */ + tsk_safeobj_init(ctx); + } + return self; } static tsk_object_t* ctx_dtor(tsk_object_t * self) -{ - ctx_t *ctx = self; - if(ctx){ - /* Stop the stack (as sessions are alive, you will continue to receive callbacks)*/ - tsip_stack_stop(ctx->stack); - - /* sessions : should be freed before the stack as explained on the Programmer's Guide - * As all dialogs have been hanged up, the list should be empty ...but who know?*/ - TSK_OBJECT_SAFE_FREE(ctx->sessions); - - /* Destroy the stack */ - TSK_OBJECT_SAFE_FREE(ctx->stack); - - /* Identity */ - TSK_FREE(ctx->identity.display_name); - TSK_FREE(ctx->identity.impu); - TSK_FREE(ctx->identity.preferred); - TSK_FREE(ctx->identity.impi); - TSK_FREE(ctx->identity.password); - - /* Network */ - TSK_FREE(ctx->network.local_ip); - TSK_FREE(ctx->network.proxy_cscf); - TSK_FREE(ctx->network.proxy_cscf_trans); - TSK_FREE(ctx->network.realm); - - /* Security */ - TSK_FREE(ctx->security.operator_id); - - /* Params */ - TSK_OBJECT_SAFE_FREE(ctx->params); - - /* deinit internal mutex */ - tsk_safeobj_deinit(ctx); - } - - return self; +{ + ctx_t *ctx = self; + if(ctx) { + /* Stop the stack (as sessions are alive, you will continue to receive callbacks)*/ + tsip_stack_stop(ctx->stack); + + /* sessions : should be freed before the stack as explained on the Programmer's Guide + * As all dialogs have been hanged up, the list should be empty ...but who know?*/ + TSK_OBJECT_SAFE_FREE(ctx->sessions); + + /* Destroy the stack */ + TSK_OBJECT_SAFE_FREE(ctx->stack); + + /* Identity */ + TSK_FREE(ctx->identity.display_name); + TSK_FREE(ctx->identity.impu); + TSK_FREE(ctx->identity.preferred); + TSK_FREE(ctx->identity.impi); + TSK_FREE(ctx->identity.password); + + /* Network */ + TSK_FREE(ctx->network.local_ip); + TSK_FREE(ctx->network.proxy_cscf); + TSK_FREE(ctx->network.proxy_cscf_trans); + TSK_FREE(ctx->network.realm); + + /* Security */ + TSK_FREE(ctx->security.operator_id); + + /* Params */ + TSK_OBJECT_SAFE_FREE(ctx->params); + + /* deinit internal mutex */ + tsk_safeobj_deinit(ctx); + } + + return self; } -static const tsk_object_def_t ctx_def_s = -{ - sizeof(ctx_t), - ctx_ctor, - ctx_dtor, - tsk_null, +static const tsk_object_def_t ctx_def_s = { + sizeof(ctx_t), + ctx_ctor, + ctx_dtor, + tsk_null, }; const tsk_object_def_t *ctx_def_t = &ctx_def_s; /* ================================================================== - ========================== Stack ================================= + ========================== Stack ================================= */ int stack_dump() { - const tsk_list_item_t* item; + const tsk_list_item_t* item; - tsk_list_foreach(item, ctx->sessions){ - session_tostring(item->data); - } - return 0; + tsk_list_foreach(item, ctx->sessions) { + session_tostring(item->data); + } + return 0; } int stack_config(const opts_L_t* opts) { - const tsk_list_item_t* item; - const opt_t* opt; - int ret = 0; - tsk_param_t* param; - tsk_bool_t pcscf_changed = tsk_false; - tsk_bool_t stun_done = tsk_false; - - if(!opts){ - return -1; - } - - tsk_list_foreach(item, opts){ - opt = item->data; - - /* Stack-level option */ - if(opt->lv != lv_none && opt->lv != lv_stack){ - continue; - } - - switch(opt->type){ - case opt_amf: - { - break; - } - case opt_dhcpv4: - case opt_dhcpv6: - { - tsip_stack_set(ctx->stack, - TSIP_STACK_SET_DISCOVERY_DHCP(tsk_true), - TSIP_STACK_SET_NULL()); - break; - } - case opt_dname: - { - break; - } - case opt_dns_naptr: - { - tsip_stack_set(ctx->stack, - TSIP_STACK_SET_DISCOVERY_NAPTR(tsk_true), - TSIP_STACK_SET_NULL()); - break; - } - case opt_header: - { - if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))){ - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_HEADER(param->name, param->value), - TSIP_STACK_SET_NULL()); - TSK_OBJECT_SAFE_FREE(param); - } - break; - } - case opt_impi: - { - tsk_strupdate(&ctx->identity.impi, opt->value); - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_IMPI(ctx->identity.impi), - TSIP_STACK_SET_NULL()); - break; - } - case opt_impu: - { - tsk_strupdate(&ctx->identity.impu, opt->value); - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_IMPU(ctx->identity.impu), - TSIP_STACK_SET_NULL()); - break; - } - case opt_ipv6: - { - pcscf_changed = tsk_true; - ctx->network.ipv6 = tsk_true; - break; - } - case opt_local_ip: - { - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_LOCAL_IP(opt->value), - TSIP_STACK_SET_NULL()); - break; - } - case opt_local_port: - { - unsigned port = (unsigned)atoi(opt->value); - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_LOCAL_PORT(port), - TSIP_STACK_SET_NULL()); - break; - } - case opt_opid: - { - break; - } - case opt_password: - { - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_PASSWORD(opt->value), - TSIP_STACK_SET_NULL()); - break; - } - case opt_pcscf_ip: - { - pcscf_changed = tsk_true; - tsk_strupdate(&ctx->network.proxy_cscf, opt->value); - break; - } - case opt_pcscf_port: - { - pcscf_changed = tsk_true; - ctx->network.proxy_cscf_port = atoi(opt->value); - break; - } - case opt_pcscf_trans: - { - pcscf_changed = tsk_true; - tsk_strupdate(&ctx->network.proxy_cscf_trans, opt->value); - break; - } - case opt_realm: - { - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_REALM(opt->value), - TSIP_STACK_SET_NULL()); - break; - } - - case opt_sigcomp_id: - { /* add compartment */ - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_SIGCOMP_NEW_COMPARTMENT(opt->value), - TSIP_STACK_SET_NULL()); - break; - } - - case opt_stun_ip: - case opt_stun_pwd: - case opt_stun_port: - case opt_stun_usr: - { - if(!stun_done){ - const opt_t* _opt; - const char* ip = tsk_null, *usr = tsk_null, *pwd = tsk_null; - unsigned port = 0; - - if((_opt = opt_get_by_type(opts, opt_stun_ip))){ - ip = _opt->value; - } - if((_opt = opt_get_by_type(opts, opt_stun_port))){ - port = atoi(_opt->value); - } - if((_opt = opt_get_by_type(opts, opt_stun_usr))){ - usr = _opt->value; - } - if((_opt = opt_get_by_type(opts, opt_stun_pwd))){ - pwd = _opt->value; - } - - if(ip && port){ - tsip_stack_set(ctx->stack, - TSIP_STACK_SET_STUN_SERVER(ip, port), - TSIP_STACK_SET_NULL()); - } - if(usr){ - tsip_stack_set(ctx->stack, - TSIP_STACK_SET_STUN_CRED(usr, pwd), - TSIP_STACK_SET_NULL()); - } - - stun_done = tsk_true; - } - break; - } - - }/* switch */ - - } /* foreach */ - - /* whether Proxy-CSCF config has changed */ - if(pcscf_changed){ - ret = tsip_stack_set(ctx->stack, - TSIP_STACK_SET_PROXY_CSCF(ctx->network.proxy_cscf, ctx->network.proxy_cscf_port, ctx->network.proxy_cscf_trans, ctx->network.ipv6 ? "ipv6" : "ipv4"), - TSIP_STACK_SET_NULL()); - } - - return ret; + const tsk_list_item_t* item; + const opt_t* opt; + int ret = 0; + tsk_param_t* param; + tsk_bool_t pcscf_changed = tsk_false; + tsk_bool_t stun_done = tsk_false; + + if(!opts) { + return -1; + } + + tsk_list_foreach(item, opts) { + opt = item->data; + + /* Stack-level option */ + if(opt->lv != lv_none && opt->lv != lv_stack) { + continue; + } + + switch(opt->type) { + case opt_amf: { + break; + } + case opt_dhcpv4: + case opt_dhcpv6: { + tsip_stack_set(ctx->stack, + TSIP_STACK_SET_DISCOVERY_DHCP(tsk_true), + TSIP_STACK_SET_NULL()); + break; + } + case opt_dname: { + break; + } + case opt_dns_naptr: { + tsip_stack_set(ctx->stack, + TSIP_STACK_SET_DISCOVERY_NAPTR(tsk_true), + TSIP_STACK_SET_NULL()); + break; + } + case opt_header: { + if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))) { + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_HEADER(param->name, param->value), + TSIP_STACK_SET_NULL()); + TSK_OBJECT_SAFE_FREE(param); + } + break; + } + case opt_impi: { + tsk_strupdate(&ctx->identity.impi, opt->value); + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_IMPI(ctx->identity.impi), + TSIP_STACK_SET_NULL()); + break; + } + case opt_impu: { + tsk_strupdate(&ctx->identity.impu, opt->value); + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_IMPU(ctx->identity.impu), + TSIP_STACK_SET_NULL()); + break; + } + case opt_ipv6: { + pcscf_changed = tsk_true; + ctx->network.ipv6 = tsk_true; + break; + } + case opt_local_ip: { + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_LOCAL_IP(opt->value), + TSIP_STACK_SET_NULL()); + break; + } + case opt_local_port: { + unsigned port = (unsigned)atoi(opt->value); + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_LOCAL_PORT(port), + TSIP_STACK_SET_NULL()); + break; + } + case opt_opid: { + break; + } + case opt_password: { + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_PASSWORD(opt->value), + TSIP_STACK_SET_NULL()); + break; + } + case opt_pcscf_ip: { + pcscf_changed = tsk_true; + tsk_strupdate(&ctx->network.proxy_cscf, opt->value); + break; + } + case opt_pcscf_port: { + pcscf_changed = tsk_true; + ctx->network.proxy_cscf_port = atoi(opt->value); + break; + } + case opt_pcscf_trans: { + pcscf_changed = tsk_true; + tsk_strupdate(&ctx->network.proxy_cscf_trans, opt->value); + break; + } + case opt_realm: { + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_REALM(opt->value), + TSIP_STACK_SET_NULL()); + break; + } + + case opt_sigcomp_id: { + /* add compartment */ + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_SIGCOMP_NEW_COMPARTMENT(opt->value), + TSIP_STACK_SET_NULL()); + break; + } + + case opt_stun_ip: + case opt_stun_pwd: + case opt_stun_port: + case opt_stun_usr: { + if(!stun_done) { + const opt_t* _opt; + const char* ip = tsk_null, *usr = tsk_null, *pwd = tsk_null; + unsigned port = 0; + + if((_opt = opt_get_by_type(opts, opt_stun_ip))) { + ip = _opt->value; + } + if((_opt = opt_get_by_type(opts, opt_stun_port))) { + port = atoi(_opt->value); + } + if((_opt = opt_get_by_type(opts, opt_stun_usr))) { + usr = _opt->value; + } + if((_opt = opt_get_by_type(opts, opt_stun_pwd))) { + pwd = _opt->value; + } + + if(ip && port) { + tsip_stack_set(ctx->stack, + TSIP_STACK_SET_STUN_SERVER(ip, port), + TSIP_STACK_SET_NULL()); + } + if(usr) { + tsip_stack_set(ctx->stack, + TSIP_STACK_SET_STUN_CRED(usr, pwd), + TSIP_STACK_SET_NULL()); + } + + stun_done = tsk_true; + } + break; + } + + }/* switch */ + + } /* foreach */ + + /* whether Proxy-CSCF config has changed */ + if(pcscf_changed) { + ret = tsip_stack_set(ctx->stack, + TSIP_STACK_SET_PROXY_CSCF(ctx->network.proxy_cscf, ctx->network.proxy_cscf_port, ctx->network.proxy_cscf_trans, ctx->network.ipv6 ? "ipv6" : "ipv4"), + TSIP_STACK_SET_NULL()); + } + + return ret; } int stack_run(const opts_L_t* opts) { - if(!ctx->stack){ - TSK_DEBUG_ERROR("Stack is Null."); - return -1; - } - else{ - return tsip_stack_start(ctx->stack); - } + if(!ctx->stack) { + TSK_DEBUG_ERROR("Stack is Null."); + return -1; + } + else { + return tsip_stack_start(ctx->stack); + } } /* ================================================================== - ========================== Session ================================= + ========================== Session ================================= */ /* Find SIP session by id */ int pred_find_session_by_id(const tsk_list_item_t *item, const void* id) { - const session_t* session; - if(item && item->data){ - session = item->data; - return (int)(tsip_ssession_get_id(session->handle) - - *((tsip_ssession_id_t*)id)); - } - return -1; + const session_t* session; + if(item && item->data) { + session = item->data; + return (int)(tsip_ssession_get_id(session->handle) + - *((tsip_ssession_id_t*)id)); + } + return -1; } session_t* session_create(session_type_t type, tsip_ssession_handle_t* handle) { - session_t* session = tsk_object_new(session_def_t, type, handle); - if(!session){ - TSK_DEBUG_ERROR("Failed to create new SIP session"); - return tsk_null; - } - - switch(type){ - case st_invite: - { /* Enable all features (QoS, Session timers, SigComp, ...) */ - tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_USERDATA(session), - /*=== MEDIA */ - TSIP_SSESSION_SET_MEDIA( - // 100rel - TSIP_MSESSION_SET_100rel(tsk_false), - // Session timers - TSIP_MSESSION_SET_TIMERS(3600, "uac"), - // QoS - TSIP_MSESSION_SET_QOS(tmedia_qos_stype_segmented, tmedia_qos_strength_optional), - // close media params - TSIP_MSESSION_SET_NULL() - ), - - TSIP_SSESSION_SET_NULL()); - break; - } - default: - break; - } - return session; + session_t* session = tsk_object_new(session_def_t, type, handle); + if(!session) { + TSK_DEBUG_ERROR("Failed to create new SIP session"); + return tsk_null; + } + + switch(type) { + case st_invite: { + /* Enable all features (QoS, Session timers, SigComp, ...) */ + tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_USERDATA(session), + /*=== MEDIA */ + TSIP_SSESSION_SET_MEDIA( + // 100rel + TSIP_MSESSION_SET_100rel(tsk_false), + // Session timers + TSIP_MSESSION_SET_TIMERS(3600, "uac"), + // QoS + TSIP_MSESSION_SET_QOS(tmedia_qos_stype_segmented, tmedia_qos_strength_optional), + // close media params + TSIP_MSESSION_SET_NULL() + ), + + TSIP_SSESSION_SET_NULL()); + break; + } + default: + break; + } + return session; } const session_t* session_get_by_sid(const sessions_L_t* sessions, tsip_ssession_id_t sid) { - const tsk_list_item_t* item; - if((item = tsk_list_find_item_by_pred(sessions, pred_find_session_by_id, &sid))){ - return item->data; - } - else{ - return tsk_null; - } + const tsk_list_item_t* item; + if((item = tsk_list_find_item_by_pred(sessions, pred_find_session_by_id, &sid))) { + return item->data; + } + else { + return tsk_null; + } } int session_tostring(const session_t* session) { - //char* temp = tsk_null; - printf("== Session: "); - if(session){ - /* Session Id */ - printf("sid=%llu", tsip_ssession_get_id(session->handle)); - /* Type */ - printf(" type="); - switch(session->type){ - case st_invite: - printf("INVITE"); - break; - case st_message: - printf("MESSAGE"); - break; - case st_publish: - printf("PUBLISH"); - break; - case st_register: - printf("REGISTER"); - break; - case st_subscribe: - printf("SUBSCRIBE"); - break; - default: - printf("(null)"); - break; - } - /* From */ - printf(" from=%s", session->from ? session->from : ctx->identity.impu); - /* From */ - printf(" to=%s", session->to ? session->to : ctx->identity.impu); - } - else{ - printf("(invalid)"); - } - printf("\n"); - return -1; + //char* temp = tsk_null; + printf("== Session: "); + if(session) { + /* Session Id */ + printf("sid=%llu", tsip_ssession_get_id(session->handle)); + /* Type */ + printf(" type="); + switch(session->type) { + case st_invite: + printf("INVITE"); + break; + case st_message: + printf("MESSAGE"); + break; + case st_publish: + printf("PUBLISH"); + break; + case st_register: + printf("REGISTER"); + break; + case st_subscribe: + printf("SUBSCRIBE"); + break; + default: + printf("(null)"); + break; + } + /* From */ + printf(" from=%s", session->from ? session->from : ctx->identity.impu); + /* From */ + printf(" to=%s", session->to ? session->to : ctx->identity.impu); + } + else { + printf("(invalid)"); + } + printf("\n"); + return -1; } /* handle events -common to all sessions */ int session_handle_event(const tsip_event_t *_event) { - const session_t* session; - - /* Find associated session */ - if(!(session = session_get_by_sid(ctx->sessions, tsip_ssession_get_id(_event->ss)))){ - /* Silentky ignore */ - return 0; - } - switch(_event->code) - { - /* === 7xx ==> errors === */ - case tsip_event_code_dialog_transport_error: - case tsip_event_code_dialog_global_error: - case tsip_event_code_dialog_message_error: - /* do not guess that the dialog is terminated, wait for "tsip_event_code_dialog_terminated" event */ - break; - - /* === 8xx ==> success === */ - case tsip_event_code_dialog_request_incoming: - case tsip_event_code_dialog_request_cancelled: - case tsip_event_code_dialog_request_sent: - break; - - /* === 9xx ==> Informational === */ - case tsip_event_code_dialog_terminated: - { /* we no longer need the session - * -> remove and destroy the session */ - TSK_DEBUG_INFO("Dialog Terminated --> %s", _event->phrase); - tsk_list_remove_item_by_data(ctx->sessions, session); - break; - } - - case tsip_event_code_dialog_connected: - ((session_t*)session)->connected = tsk_true; - break; - case tsip_event_code_dialog_terminating: - break; - } - return 0; + const session_t* session; + + /* Find associated session */ + if(!(session = session_get_by_sid(ctx->sessions, tsip_ssession_get_id(_event->ss)))) { + /* Silentky ignore */ + return 0; + } + switch(_event->code) { + /* === 7xx ==> errors === */ + case tsip_event_code_dialog_transport_error: + case tsip_event_code_dialog_global_error: + case tsip_event_code_dialog_message_error: + /* do not guess that the dialog is terminated, wait for "tsip_event_code_dialog_terminated" event */ + break; + + /* === 8xx ==> success === */ + case tsip_event_code_dialog_request_incoming: + case tsip_event_code_dialog_request_cancelled: + case tsip_event_code_dialog_request_sent: + break; + + /* === 9xx ==> Informational === */ + case tsip_event_code_dialog_terminated: { + /* we no longer need the session + * -> remove and destroy the session */ + TSK_DEBUG_INFO("Dialog Terminated --> %s", _event->phrase); + tsk_list_remove_item_by_data(ctx->sessions, session); + break; + } + + case tsip_event_code_dialog_connected: + ((session_t*)session)->connected = tsk_true; + break; + case tsip_event_code_dialog_terminating: + break; + } + return 0; } /* handle commands -common to all sessions */ const session_t* session_handle_cmd(cmd_type_t cmd, const opts_L_t* opts) { - const session_t* session = tsk_null; - const opt_t* opt; - const tsk_list_item_t* item; - tsk_param_t* param; - int ret = 0; - - /* Check if there is a session with is Id */ - if((opt = opt_get_by_type(opts, opt_sid))){ - tsip_ssession_id_t sid = atoi(opt->value); - session = session_get_by_sid(ctx->sessions, sid); - } + const session_t* session = tsk_null; + const opt_t* opt; + const tsk_list_item_t* item; + tsk_param_t* param; + int ret = 0; + + /* Check if there is a session with is Id */ + if((opt = opt_get_by_type(opts, opt_sid))) { + tsip_ssession_id_t sid = atoi(opt->value); + session = session_get_by_sid(ctx->sessions, sid); + } #define TYPE_FROM_CMD(_CMD) \ ((_CMD==cmd_audio || _CMD==cmd_video || _CMD==cmd_audiovideo || _CMD==cmd_file || _CMD==cmd_large_message) ? st_invite : \ @@ -602,227 +582,228 @@ const session_t* session_handle_cmd(cmd_type_t cmd, const opts_L_t* opts) (_CMD==cmd_publish ? st_publish : \ (_CMD==cmd_register ? st_register : \ (_CMD==cmd_subscribe ? st_subscribe : st_none)))))) - - /* === Command === */ - switch(cmd){ - case cmd_audio: case cmd_video: case cmd_audiovideo: case cmd_file: case cmd_large_message: - case cmd_message: - case cmd_sms: - case cmd_options: - case cmd_publish: - case cmd_register: - case cmd_subscribe: - { - if(!session){ /* Create "client-side-session" */ - session_t* _session; - if((_session = session_client_create(TYPE_FROM_CMD(cmd))) && (session = _session)){ - tsk_list_push_back_data(ctx->sessions, (void**)&_session); - } - } - break; - } - default: - { - if(session){ - /* hold, resume, refer, update, ...all in-dialog commands */ - break; - } - else{ - TSK_DEBUG_WARN("Session handling: Cannot handle this command [%d]", cmd); - goto bail; - } - } - } /* switch */ - - if(!session){ - TSK_DEBUG_ERROR("SIP Session is Null"); - goto bail; - } - - /* === User Options === */ - tsk_list_foreach(item, opts){ - opt = item->data; - - /* Session-level option? */ - if(opt->lv != lv_none && opt->lv != lv_session){ - continue; - } - - switch(opt->type){ - case opt_caps: - { - if(!tsk_strnullORempty(opt->value)){ - if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))){ - ret = tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_CAPS(param->name, param->value), - TSIP_SSESSION_SET_NULL()); - TSK_OBJECT_SAFE_FREE(param); - } - } - break; - } - case opt_expires: - { - if(!tsk_strnullORempty(opt->value)){ - unsigned expires = atoi(opt->value); - ret = tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_EXPIRES(expires), - TSIP_SSESSION_SET_NULL()); - } - break; - } - case opt_from: - { /* You should use TSIP_SSESSION_SET_OPTION(TSIP_SSESSION_OPTION_FROM, value) - instead of TSIP_SSESSION_SET_HEADER() to set the destination URI. */ - break; - } - case opt_header: - { - if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))){ - ret = tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_HEADER(param->name, param->value), - TSIP_SSESSION_SET_NULL()); - TSK_OBJECT_SAFE_FREE(param); - } - break; - } - case opt_payload: - { /* Will be handled by the caller */ - break; - } - case opt_silent: - { /* valueless option */ - ret = tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_SILENT_HANGUP(tsk_true), - TSIP_SSESSION_SET_NULL()); - break; - } - case opt_sigcomp_id: - { /* sigcomp-id */ - ret = tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_SIGCOMP_COMPARTMENT(opt->value), - TSIP_SSESSION_SET_NULL()); - break; - } - case opt_to: - { /* You should use TSIP_SSESSION_SET_OPTION(TSIP_SSESSION_OPTION_TO, value) - instead of TSIP_SSESSION_SET_HEADER() to set the destination URI. */ - if((cmd != cmd_sms) && (cmd != cmd_ect) && !tsk_strnullORempty(opt->value)){ /* SMS will use SMSC Address as Request URI */ - ret = tsip_ssession_set(session->handle, - TSIP_SSESSION_SET_TO(opt->value), - TSIP_SSESSION_SET_NULL()); - } - break; - } - default: - { - /* will be handled by the caller */ - break; - } - } - - } /* foreach */ + + /* === Command === */ + switch(cmd) { + case cmd_audio: + case cmd_video: + case cmd_audiovideo: + case cmd_file: + case cmd_large_message: + case cmd_message: + case cmd_sms: + case cmd_options: + case cmd_publish: + case cmd_register: + case cmd_subscribe: { + if(!session) { /* Create "client-side-session" */ + session_t* _session; + if((_session = session_client_create(TYPE_FROM_CMD(cmd))) && (session = _session)) { + tsk_list_push_back_data(ctx->sessions, (void**)&_session); + } + } + break; + } + default: { + if(session) { + /* hold, resume, refer, update, ...all in-dialog commands */ + break; + } + else { + TSK_DEBUG_WARN("Session handling: Cannot handle this command [%d]", cmd); + goto bail; + } + } + } /* switch */ + + if(!session) { + TSK_DEBUG_ERROR("SIP Session is Null"); + goto bail; + } + + /* === User Options === */ + tsk_list_foreach(item, opts) { + opt = item->data; + + /* Session-level option? */ + if(opt->lv != lv_none && opt->lv != lv_session) { + continue; + } + + switch(opt->type) { + case opt_caps: { + if(!tsk_strnullORempty(opt->value)) { + if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))) { + ret = tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_CAPS(param->name, param->value), + TSIP_SSESSION_SET_NULL()); + TSK_OBJECT_SAFE_FREE(param); + } + } + break; + } + case opt_expires: { + if(!tsk_strnullORempty(opt->value)) { + unsigned expires = atoi(opt->value); + ret = tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_EXPIRES(expires), + TSIP_SSESSION_SET_NULL()); + } + break; + } + case opt_from: { + /* You should use TSIP_SSESSION_SET_OPTION(TSIP_SSESSION_OPTION_FROM, value) + instead of TSIP_SSESSION_SET_HEADER() to set the destination URI. */ + break; + } + case opt_header: { + if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))) { + ret = tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_HEADER(param->name, param->value), + TSIP_SSESSION_SET_NULL()); + TSK_OBJECT_SAFE_FREE(param); + } + break; + } + case opt_payload: { + /* Will be handled by the caller */ + break; + } + case opt_silent: { + /* valueless option */ + ret = tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_SILENT_HANGUP(tsk_true), + TSIP_SSESSION_SET_NULL()); + break; + } + case opt_sigcomp_id: { + /* sigcomp-id */ + ret = tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_SIGCOMP_COMPARTMENT(opt->value), + TSIP_SSESSION_SET_NULL()); + break; + } + case opt_to: { + /* You should use TSIP_SSESSION_SET_OPTION(TSIP_SSESSION_OPTION_TO, value) + instead of TSIP_SSESSION_SET_HEADER() to set the destination URI. */ + if((cmd != cmd_sms) && (cmd != cmd_ect) && !tsk_strnullORempty(opt->value)) { /* SMS will use SMSC Address as Request URI */ + ret = tsip_ssession_set(session->handle, + TSIP_SSESSION_SET_TO(opt->value), + TSIP_SSESSION_SET_NULL()); + } + break; + } + default: { + /* will be handled by the caller */ + break; + } + } + + } /* foreach */ bail: - return session; + return session; } int session_hangup(tsip_ssession_id_t sid) { - const session_t* session; - if((session = session_get_by_sid(ctx->sessions, sid))){ - switch(session->type){ - case st_invite: - tsip_api_invite_send_bye(session->handle, - /* You can add your parameters */ - TSIP_ACTION_SET_NULL()); - break; - case st_message: - break; - case st_publish: - tsip_api_publish_send_unpublish(session->handle, - /* You can add your parameters */ - TSIP_ACTION_SET_NULL()); - break; - case st_register: - tsip_api_register_send_unregister(session->handle, - /* You can add your parameters */ - TSIP_ACTION_SET_NULL()); - break; - case st_subscribe: - tsip_api_subscribe_send_unsubscribe(session->handle, - /* You can add your parameters */ - TSIP_ACTION_SET_NULL()); - break; - default: - TSK_DEBUG_WARN("Cannot hangup session with this type [%d]", session->type); - return -2; - } - return 0; - } - else{ - TSK_DEBUG_WARN("Failed to find session with sid=%llu", sid); - return -1; - } + const session_t* session; + if((session = session_get_by_sid(ctx->sessions, sid))) { + switch(session->type) { + case st_invite: + tsip_api_invite_send_bye(session->handle, + /* You can add your parameters */ + TSIP_ACTION_SET_NULL()); + break; + case st_message: + break; + case st_publish: + tsip_api_publish_send_unpublish(session->handle, + /* You can add your parameters */ + TSIP_ACTION_SET_NULL()); + break; + case st_register: + tsip_api_register_send_unregister(session->handle, + /* You can add your parameters */ + TSIP_ACTION_SET_NULL()); + break; + case st_subscribe: + tsip_api_subscribe_send_unsubscribe(session->handle, + /* You can add your parameters */ + TSIP_ACTION_SET_NULL()); + break; + default: + TSK_DEBUG_WARN("Cannot hangup session with this type [%d]", session->type); + return -2; + } + return 0; + } + else { + TSK_DEBUG_WARN("Failed to find session with sid=%llu", sid); + return -1; + } } static tsk_object_t* session_ctor(tsk_object_t * self, va_list * app) { - session_t *session = self; - if(session){ - session->type = va_arg(*app, session_type_t); - if((session->handle = va_arg(*app, tsip_ssession_handle_t*))){ - int ret; - /* "server-side-session" */ - if((ret = tsip_ssession_take_ownership(session->handle))){ - TSK_DEBUG_ERROR("Failed to take ownership [%d]", ret); - } - } - else{ - /* "client-side-session" */ - session->handle = tsip_ssession_create(ctx->stack, - TSIP_SSESSION_SET_NULL()); - } - } - return self; + session_t *session = self; + if(session) { + session->type = va_arg(*app, session_type_t); + if((session->handle = va_arg(*app, tsip_ssession_handle_t*))) { + int ret; + /* "server-side-session" */ + if((ret = tsip_ssession_take_ownership(session->handle))) { + TSK_DEBUG_ERROR("Failed to take ownership [%d]", ret); + } + } + else { + /* "client-side-session" */ + session->handle = tsip_ssession_create(ctx->stack, + TSIP_SSESSION_SET_NULL()); + } + } + return self; } static tsk_object_t* session_dtor(tsk_object_t * self) -{ - session_t *session = self; - if(session){ - TSK_OBJECT_SAFE_FREE(session->handle); +{ + session_t *session = self; + if(session) { + TSK_OBJECT_SAFE_FREE(session->handle); - TSK_FREE(session->to); - TSK_FREE(session->from); - } + TSK_FREE(session->to); + TSK_FREE(session->from); + } - return self; + return self; } static int session_cmp(const tsk_object_t *_ss1, const tsk_object_t *_ss2) { - const session_t *ss1 = _ss1; - const session_t *ss2 = _ss2; - - if(ss1 && ss1){ - if(ss1->handle && ss2->handle){ - return tsk_object_cmp(ss1->handle, ss2->handle); - } - else{ - return (ss2 - ss1); - } - } - else if(!ss1 && !ss2) return 0; - else return -1; + const session_t *ss1 = _ss1; + const session_t *ss2 = _ss2; + + if(ss1 && ss1) { + if(ss1->handle && ss2->handle) { + return tsk_object_cmp(ss1->handle, ss2->handle); + } + else { + return (ss2 - ss1); + } + } + else if(!ss1 && !ss2) { + return 0; + } + else { + return -1; + } } -static const tsk_object_def_t session_def_s = -{ - sizeof(session_t), - session_ctor, - session_dtor, - session_cmp, +static const tsk_object_def_t session_def_s = { + sizeof(session_t), + session_ctor, + session_dtor, + session_cmp, }; const tsk_object_def_t *session_def_t = &session_def_s; @@ -830,51 +811,50 @@ const tsk_object_def_t *session_def_t = &session_def_s; tsip_action_handle_t* action_get_config(const opts_L_t* opts) { - const opt_t* opt; - const tsk_list_item_t* item; - tsip_action_handle_t* action_config = tsk_null; - tsk_param_t* param; - - if(TSK_LIST_IS_EMPTY(opts)){ - return tsk_null; - } - - tsk_list_foreach(item, opts){ - opt = item->data; - - /* action level? */ - if(opt->lv != lv_action){ - continue; - } - - /* create new action */ - if(!action_config && !(action_config = tsip_action_create(tsip_atype_config, - TSIP_ACTION_SET_NULL()))) break; - - switch(opt->type){ - case opt_header: - { - if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))){ - tsip_action_set(action_config, - TSIP_ACTION_SET_HEADER(param->name, param->value), - TSIP_ACTION_SET_NULL()); - TSK_OBJECT_SAFE_FREE(param); - } - break; - } - case opt_payload: - { - tsip_action_set(action_config, - TSIP_ACTION_SET_PAYLOAD(opt->value, tsk_strlen(opt->value)), - TSIP_ACTION_SET_NULL()); - break; - } - default: - { - break; - } - } - } - - return action_config; + const opt_t* opt; + const tsk_list_item_t* item; + tsip_action_handle_t* action_config = tsk_null; + tsk_param_t* param; + + if(TSK_LIST_IS_EMPTY(opts)) { + return tsk_null; + } + + tsk_list_foreach(item, opts) { + opt = item->data; + + /* action level? */ + if(opt->lv != lv_action) { + continue; + } + + /* create new action */ + if(!action_config && !(action_config = tsip_action_create(tsip_atype_config, + TSIP_ACTION_SET_NULL()))) { + break; + } + + switch(opt->type) { + case opt_header: { + if((param = tsk_params_parse_param(opt->value, tsk_strlen(opt->value)))) { + tsip_action_set(action_config, + TSIP_ACTION_SET_HEADER(param->name, param->value), + TSIP_ACTION_SET_NULL()); + TSK_OBJECT_SAFE_FREE(param); + } + break; + } + case opt_payload: { + tsip_action_set(action_config, + TSIP_ACTION_SET_PAYLOAD(opt->value, tsk_strlen(opt->value)), + TSIP_ACTION_SET_NULL()); + break; + } + default: { + break; + } + } + } + + return action_config; } |