summaryrefslogtreecommitdiffstats
path: root/tinyDEMO/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDEMO/common.c')
-rwxr-xr-xtinyDEMO/common.c1408
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;
}
OpenPOWER on IntegriCloud