From 72a1098e21f5b7d797655afe7ddb275969a192bd Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Wed, 28 Jun 2006 16:46:49 +0000 Subject: Major improvements in PJSIP to support TCP. The changes fall into these categories: (1) the TCP transport implementation itself (*.[hc]), (2) bug-fix in SIP transaction when using reliable transports, (3) support for TCP transport in PJSUA-LIB/PJSUA, and (4) changes in PJSIP-TEST to support TCP testing. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@563 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/src/pjsua-lib/pjsua_acc.c | 34 ++++++----- pjsip/src/pjsua-lib/pjsua_core.c | 121 +++++++++++++++++++++++++++++++-------- 2 files changed, 115 insertions(+), 40 deletions(-) (limited to 'pjsip/src/pjsua-lib') diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 57c6d33f..8e11f2a2 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -77,18 +77,18 @@ static void update_acc_contact(unsigned acc_id, unsigned tp_id) { pjsua_acc *acc = &pjsua_var.acc[acc_id]; - pjsip_transport *tp = pjsua_var.tpdata[tp_id].tp; + struct transport_data *t = &pjsua_var.tpdata[tp_id]; char uri[80]; /* Transport must be valid */ - pj_assert(tp != NULL); + pj_assert(t->data.ptr != NULL); /* Build URI for the account */ pj_ansi_sprintf(uri, "", - (int)tp->local_name.host.slen, - tp->local_name.host.ptr, - tp->local_name.port, - pjsip_transport_get_type_name(tp->key.type)); + (int)t->local_name.host.slen, + t->local_name.host.ptr, + t->local_name.port, + pjsip_transport_get_type_name(t->type)); pj_strdup2(pjsua_var.pool, &acc->real_contact, uri); @@ -144,7 +144,7 @@ static pj_status_t initialize_acc(unsigned acc_id) } PJ_TODO(attach_account_to_transport); - if (pjsua_var.tpdata[0].tp) + if (pjsua_var.tpdata[0].data.ptr) update_acc_contact(acc_id, 0); /* Build account route-set from outbound proxies and route set from @@ -220,7 +220,8 @@ PJ_DEF(pj_status_t) pjsua_acc_add( const pjsua_acc_config *cfg, PJ_ETOOMANY); /* Must have a transport */ - PJ_ASSERT_RETURN(pjsua_var.tpdata[0].tp != NULL, PJ_EINVALIDOP); + PJ_TODO(associate_acc_with_transport); + PJ_ASSERT_RETURN(pjsua_var.tpdata[0].data.ptr != NULL, PJ_EINVALIDOP); PJSUA_LOCK(); @@ -281,20 +282,23 @@ PJ_DEF(pj_status_t) pjsua_acc_add_local( pjsua_transport_id tid, pjsua_acc_id *p_acc_id) { pjsua_acc_config cfg; - pjsip_transport *tp; + struct transport_data *t = &pjsua_var.tpdata[tid]; char uri[62]; + /* ID must be valid */ + PJ_ASSERT_RETURN(tid>=0 && tiddata.ptr != NULL, PJ_EINVAL); pjsua_acc_config_default(&cfg); /* Build URI for the account */ - pj_ansi_sprintf(uri, "", - (int)tp->local_name.host.slen, - tp->local_name.host.ptr, - tp->local_name.port); + pj_ansi_sprintf(uri, "", + (int)t->local_name.host.slen, + t->local_name.host.ptr, + t->local_name.port, + pjsip_transport_get_type_name(t->type)); cfg.id = pj_str(uri); diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 72c14c00..30bfdd9a 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -729,7 +729,7 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, /* Find empty transport slot */ for (id=0; id < PJ_ARRAY_SIZE(pjsua_var.tpdata); ++id) { - if (pjsua_var.tpdata[id].tp == NULL) + if (pjsua_var.tpdata[id].data.ptr == NULL) break; } @@ -741,7 +741,9 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, /* Create the transport */ if (type == PJSIP_TRANSPORT_UDP) { - + /* + * Create UDP transport. + */ pjsua_transport_config config; pj_sock_t sock = PJ_INVALID_SOCKET; pj_sockaddr_in pub_addr; @@ -773,14 +775,56 @@ PJ_DEF(pj_status_t) pjsua_transport_create( pjsip_transport_type_e type, goto on_return; } + + /* Save the transport */ + pjsua_var.tpdata[id].type = type; + pjsua_var.tpdata[id].local_name = tp->local_name; + pjsua_var.tpdata[id].data.tp = tp; + + } else if (type == PJSIP_TRANSPORT_TCP) { + /* + * Create TCP transport. + */ + pjsua_transport_config config; + pjsip_tpfactory *tcp; + pj_sockaddr_in local_addr; + + /* Supply default config if it's not specified */ + if (cfg == NULL) { + pjsua_transport_config_default(&config); + cfg = &config; + } + + /* Init local address */ + pj_sockaddr_in_init(&local_addr, 0, 0); + + if (cfg->port) + local_addr.sin_port = pj_htons((pj_uint16_t)cfg->port); + + if (cfg->ip_addr.s_addr) + local_addr.sin_addr.s_addr = cfg->ip_addr.s_addr; + + /* Create the TCP transport */ + status = pjsip_tcp_transport_start(pjsua_var.endpt, &local_addr, 1, + &tcp); + + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Error creating SIP TCP listener", + status); + goto on_return; + } + + /* Save the transport */ + pjsua_var.tpdata[id].type = type; + pjsua_var.tpdata[id].local_name = tcp->addr_name; + pjsua_var.tpdata[id].data.factory = tcp; + } else { status = PJSIP_EUNSUPTRANSPORT; pjsua_perror(THIS_FILE, "Error creating transport", status); goto on_return; } - /* Save the transport */ - pjsua_var.tpdata[id].tp = tp; /* Return the ID */ if (p_id) *p_id = id; @@ -807,7 +851,7 @@ PJ_DEF(pj_status_t) pjsua_transport_register( pjsip_transport *tp, /* Find empty transport slot */ for (id=0; id < PJ_ARRAY_SIZE(pjsua_var.tpdata); ++id) { - if (pjsua_var.tpdata[id].tp == NULL) + if (pjsua_var.tpdata[id].data.ptr == NULL) break; } @@ -818,7 +862,9 @@ PJ_DEF(pj_status_t) pjsua_transport_register( pjsip_transport *tp, } /* Save the transport */ - pjsua_var.tpdata[id].tp = tp; + pjsua_var.tpdata[id].type = tp->key.type; + pjsua_var.tpdata[id].local_name = tp->local_name; + pjsua_var.tpdata[id].data.tp = tp; /* Return the ID */ if (p_id) *p_id = id; @@ -842,7 +888,7 @@ PJ_DEF(pj_status_t) pjsua_enum_transports( pjsua_transport_id id[], for (i=0, count=0; i=0 && iddata.tp; + + if (tp == NULL) { + PJSUA_UNLOCK(); + return PJ_EINVALIDOP; + } + + info->id = id; + info->type = tp->key.type; + info->type_name = pj_str(tp->type_name); + info->info = pj_str(tp->info); + info->flag = tp->flag; + info->addr_len = tp->addr_len; + info->local_addr = tp->local_addr; + info->local_name = tp->local_name; + info->usage_count = pj_atomic_get(tp->ref_cnt); + + } else if (pjsua_var.tpdata[id].type == PJSIP_TRANSPORT_TCP) { + + pjsip_tpfactory *factory = t->data.factory; + + if (factory == NULL) { + PJSUA_UNLOCK(); + return PJ_EINVALIDOP; + } - info->id = id; - info->type = tp->key.type; - info->type_name = pj_str(tp->type_name); - info->info = pj_str(tp->info); - info->flag = tp->flag; - info->addr_len = tp->addr_len; - info->local_addr = tp->local_addr; - info->local_name = tp->local_name; - info->usage_count = pj_atomic_get(tp->ref_cnt); + info->id = id; + info->type = t->type; + info->type_name = pj_str("TCP"); + info->info = pj_str("TCP transport"); + info->flag = factory->flag; + info->addr_len = sizeof(factory->local_addr); + info->local_addr = factory->local_addr; + info->local_name = factory->addr_name; + info->usage_count = 0; + + } + PJSUA_UNLOCK(); @@ -906,7 +977,7 @@ PJ_DEF(pj_status_t) pjsua_transport_set_enable( pjsua_transport_id id, PJ_ASSERT_RETURN(id>=0 && id=0 && id