diff options
-rw-r--r-- | pjsip/include/pjsip/sip_transport.h | 28 | ||||
-rw-r--r-- | pjsip/include/pjsip/sip_uri.h | 17 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 35 | ||||
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua_internal.h | 2 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 83 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_uri.c | 13 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_acc.c | 233 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_call.c | 27 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 1 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_im.c | 22 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_pres.c | 24 |
11 files changed, 421 insertions, 64 deletions
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h index 002061cf..2f8f679f 100644 --- a/pjsip/include/pjsip/sip_transport.h +++ b/pjsip/include/pjsip/sip_transport.h @@ -62,7 +62,9 @@ enum pjsip_transport_flags_e { PJSIP_TRANSPORT_RELIABLE = 1, /**< Transport is reliable. */ PJSIP_TRANSPORT_SECURE = 2, /**< Transport is secure. */ - PJSIP_TRANSPORT_DATAGRAM = 4, /**< Datagram based transport. */ + PJSIP_TRANSPORT_DATAGRAM = 4, /**< Datagram based transport. + (it's also assumed to be + connectionless) */ }; /** @@ -786,6 +788,30 @@ PJ_DECL(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, /** + * Find out the appropriate local address info (IP address and port) to + * advertise in Contact header based on the remote address to be + * contacted. The local address info would be the address name of the + * transport or listener which will be used to send the request. + * + * In this implementation, it will only select the transport based on + * the transport type in the request. + * + * @param tpmgr The transport manager. + * @param pool Pool to allocate memory for the IP address. + * @param h Destination address to contact. + * @param ip_addr Pointer to receive the IP address. + * @param port Pointer to receive the port number. + * + * @return PJ_SUCCESS, or the appropriate error code. + */ +PJ_DECL(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, + pj_pool_t *pool, + pjsip_transport_type_e type, + pj_str_t *ip_addr, + int *port); + + +/** * Destroy transport manager. */ PJ_DECL(pj_status_t) pjsip_tpmgr_destroy(pjsip_tpmgr *mgr); diff --git a/pjsip/include/pjsip/sip_uri.h b/pjsip/include/pjsip/sip_uri.h index e5bc4180..e5981f67 100644 --- a/pjsip/include/pjsip/sip_uri.h +++ b/pjsip/include/pjsip/sip_uri.h @@ -359,24 +359,27 @@ typedef struct pjsip_name_addr /** * Create new SIP URL and initialize all fields with zero or NULL. * @param pool The pool. - * @param secure Tlag to indicate whether secure transport should be used. + * @param secure Flag to indicate whether secure transport should be used. * @return SIP URL. */ -PJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, int secure ); +PJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, + pj_bool_t secure ); /** - * Create new SIPS URL and initialize all fields with zero or NULL. - * @param pool The pool. - * @return SIPS URL. + * Change the SIP URI scheme to sip or sips based on the secure flag. + * This would not change anything except the scheme. + * @param uri The URI + * @param secure Non-zero if sips is wanted. */ -PJ_DECL(pjsip_sip_uri*) pjsip_sips_uri_create( pj_pool_t *pool ); +PJ_DECL(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *uri, + pj_bool_t secure ); /** * Initialize SIP URL (all fields are set to NULL or zero). * @param url The URL. * @param secure Create sips URI? */ -PJ_DECL(void) pjsip_sip_uri_init(pjsip_sip_uri *url, int secure); +PJ_DECL(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure); /** * Perform full assignment to the SIP URL. diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index f8a9aff1..7ae37eed 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1303,6 +1303,41 @@ PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_outgoing(const pj_str_t *url); PJ_DECL(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata); +/** + * Create a suitable URI to be put as Contact based on the specified + * target URI for the specified account. + * + * @param pool Pool to allocate memory for the string. + * @param contact The string where the Contact URI will be stored. + * @param acc_id Account ID. + * @param uri Destination URI of the request. + * + * @return PJ_SUCCESS on success, other on error. + */ +PJ_DECL(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, + pj_str_t *contact, + pjsua_acc_id acc_id, + const pj_str_t *uri); + + + +/** + * Create a suitable URI to be put as Contact based on the information + * in the incoming request. + * + * @param pool Pool to allocate memory for the string. + * @param contact The string where the Contact URI will be stored. + * @param acc_id Account ID. + * @param rdata Incoming request. + * + * @return PJ_SUCCESS on success, other on error. + */ +PJ_DECL(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, + pj_str_t *contact, + pjsua_acc_id acc_id, + pjsip_rx_data *rdata ); + + /** * @} diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h index a0f52189..fe57b451 100644 --- a/pjsip/include/pjsua-lib/pjsua_internal.h +++ b/pjsip/include/pjsua-lib/pjsua_internal.h @@ -79,8 +79,8 @@ typedef struct pjsua_acc pj_bool_t valid; /**< Is this account valid? */ int index; /**< Index in accounts array. */ + pj_str_t display; /**< Display name, if any. */ pj_str_t user_part; /**< User part of local URI. */ - pj_str_t real_contact; /**< Real contact address. */ pj_str_t srv_domain; /**< Host part of reg server. */ int srv_port; /**< Port number of reg server. */ diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 0103527b..ebd80259 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -81,6 +81,13 @@ struct pjsip_tpmgr pj_status_t (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*); }; +/* Key for looking up hash table */ +struct transport_key +{ + pjsip_transport_type_e type; + pj_sockaddr addr; +}; + /***************************************************************************** * * GENERAL TRANSPORT (NAMES, TYPES, ETC.) @@ -817,6 +824,76 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, return PJ_SUCCESS; } + + +/* + * Find out the appropriate local address info (IP address and port) to + * advertise in Contact header based on the remote address to be + * contacted. The local address info would be the address name of the + * transport or listener which will be used to send the request. + * + * In this implementation, it will only select the transport based on + * the transport type in the request. + */ +PJ_DEF(pj_status_t) pjsip_tpmgr_find_local_addr( pjsip_tpmgr *tpmgr, + pj_pool_t *pool, + pjsip_transport_type_e type, + pj_str_t *ip_addr, + int *port) +{ + pj_status_t status = PJSIP_EUNSUPTRANSPORT; + unsigned flag; + + /* Sanity checks */ + PJ_ASSERT_RETURN(tpmgr && pool && ip_addr && port, PJ_EINVAL); + + ip_addr->slen = 0; + *port = 0; + + flag = pjsip_transport_get_flag_from_type(type); + + if ((flag & PJSIP_TRANSPORT_DATAGRAM) != 0) { + + pj_sockaddr_in remote; + pjsip_transport *tp; + + pj_sockaddr_in_init(&remote, NULL, 0); + status = pjsip_tpmgr_acquire_transport(tpmgr, type, &remote, + sizeof(remote), &tp); + + if (status == PJ_SUCCESS) { + pj_strdup(pool, ip_addr, &tp->local_name.host); + *port = tp->local_name.port; + status = PJ_SUCCESS; + + pjsip_transport_dec_ref(tp); + } + + } else { + /* For connection oriented transport, enum the factories */ + pjsip_tpfactory *f; + + pj_lock_acquire(tpmgr->lock); + + f = tpmgr->factory_list.next; + while (f != &tpmgr->factory_list) { + if (f->type == type) + break; + f = f->next; + } + + if (f != &tpmgr->factory_list) { + pj_strdup(pool, ip_addr, &f->addr_name.host); + *port = f->addr_name.port; + status = PJ_SUCCESS; + } + pj_lock_release(tpmgr->lock); + } + + return PJ_SUCCESS; +} + + /* * pjsip_tpmgr_destroy() * @@ -1061,11 +1138,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_acquire_transport(pjsip_tpmgr *mgr, int addr_len, pjsip_transport **tp) { - struct transport_key - { - pjsip_transport_type_e type; - pj_sockaddr addr; - } key; + struct transport_key key; int key_len; pjsip_transport *transport; pjsip_tpfactory *factory; diff --git a/pjsip/src/pjsip/sip_uri.c b/pjsip/src/pjsip/sip_uri.c index ddb1e68a..97fb90b3 100644 --- a/pjsip/src/pjsip/sip_uri.c +++ b/pjsip/src/pjsip/sip_uri.c @@ -206,16 +206,23 @@ static void *pjsip_name_addr_get_uri( pjsip_name_addr *name ) return name->uri; } -PJ_DEF(void) pjsip_sip_uri_init(pjsip_sip_uri *url, int secure) +PJ_DEF(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *url, + pj_bool_t secure ) +{ + url->vptr = secure ? &sips_url_vptr : &sip_url_vptr; +} + +PJ_DEF(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure) { pj_bzero(url, sizeof(*url)); url->ttl_param = -1; - url->vptr = secure ? &sips_url_vptr : &sip_url_vptr; + pjsip_sip_uri_set_secure(url, secure); pj_list_init(&url->other_param); pj_list_init(&url->header_param); } -PJ_DEF(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, int secure ) +PJ_DEF(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool, + pj_bool_t secure ) { pjsip_sip_uri *url = pj_pool_alloc(pool, sizeof(pjsip_sip_uri)); pjsip_sip_uri_init(url, secure); diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index 65288f10..61b4096a 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -71,46 +71,23 @@ static void copy_acc_config(pj_pool_t *pool, /* - * Update account's real contact address. - */ -static void update_acc_contact(unsigned acc_id, - unsigned tp_id) -{ - pjsua_acc *acc = &pjsua_var.acc[acc_id]; - struct transport_data *t = &pjsua_var.tpdata[tp_id]; - char uri[80]; - - /* Transport must be valid */ - pj_assert(t->data.ptr != NULL); - - /* Build URI for the account */ - pj_ansi_sprintf(uri, "<sip:%.*s:%d;transport=%s>", - (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); -} - - -/* * Initialize a new account (after configuration is set). */ static pj_status_t initialize_acc(unsigned acc_id) { pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; pjsua_acc *acc = &pjsua_var.acc[acc_id]; - pjsip_uri *uri; + pjsip_name_addr *name_addr; pjsip_sip_uri *sip_uri, *sip_reg_uri; unsigned i; /* Need to parse local_uri to get the elements: */ - uri = pjsip_parse_uri(pjsua_var.pool, acc_cfg->id.ptr, - acc_cfg->id.slen, 0); - if (uri == NULL) { + name_addr = (pjsip_name_addr*) + pjsip_parse_uri(pjsua_var.pool, acc_cfg->id.ptr, + acc_cfg->id.slen, + PJSIP_PARSE_URI_AS_NAMEADDR); + if (name_addr == NULL) { pjsua_perror(THIS_FILE, "Invalid local URI", PJSIP_EINVALIDURI); return PJSIP_EINVALIDURI; @@ -118,8 +95,8 @@ static pj_status_t initialize_acc(unsigned acc_id) /* Local URI MUST be a SIP or SIPS: */ - if (!PJSIP_URI_SCHEME_IS_SIP(uri) && - !PJSIP_URI_SCHEME_IS_SIPS(uri)) + if (!PJSIP_URI_SCHEME_IS_SIP(name_addr) && + !PJSIP_URI_SCHEME_IS_SIPS(name_addr)) { pjsua_perror(THIS_FILE, "Invalid local URI", PJSIP_EINVALIDSCHEME); @@ -128,7 +105,7 @@ static pj_status_t initialize_acc(unsigned acc_id) /* Get the SIP URI object: */ - sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(uri); + sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(name_addr); /* Parse registrar URI, if any */ @@ -162,6 +139,7 @@ static pj_status_t initialize_acc(unsigned acc_id) /* Save the user and domain part. These will be used when finding an * account for incoming requests. */ + acc->display = name_addr->display; acc->user_part = sip_uri->user; acc->srv_domain = sip_uri->host; acc->srv_port = 0; @@ -175,10 +153,6 @@ static pj_status_t initialize_acc(unsigned acc_id) // acc_cfg->contact = acc_cfg->id; //} - PJ_TODO(attach_account_to_transport); - if (pjsua_var.tpdata[0].data.ptr) - update_acc_contact(acc_id, 0); - /* Build account route-set from outbound proxies and route set from * account configuration. */ @@ -376,6 +350,8 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id, const pjsua_acc_config *cfg) { PJ_TODO(pjsua_acc_modify); + PJ_UNUSED_ARG(acc_id); + PJ_UNUSED_ARG(cfg); return PJ_EINVALIDOP; } @@ -461,6 +437,7 @@ static void regc_cb(struct pjsip_regc_cbparam *param) static pj_status_t pjsua_regc_init(int acc_id) { pjsua_acc *acc; + pj_str_t contact; pj_status_t status; acc = &pjsua_var.acc[acc_id]; @@ -481,11 +458,20 @@ static pj_status_t pjsua_regc_init(int acc_id) return status; } + status = pjsua_acc_create_uac_contact( pjsua_var.pool, &contact, + acc_id, &acc->cfg.reg_uri); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate suitable Contact header" + " for registration", + status); + return status; + } + status = pjsip_regc_init( acc->regc, &acc->cfg.reg_uri, &acc->cfg.id, &acc->cfg.id, - 1, &acc->real_contact, + 1, &contact, acc->cfg.reg_timeout); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, @@ -822,3 +808,176 @@ PJ_DEF(pjsua_acc_id) pjsua_acc_find_for_incoming(pjsip_rx_data *rdata) return pjsua_var.default_acc; } + +PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, + pj_str_t *contact, + pjsua_acc_id acc_id, + const pj_str_t *suri) +{ + pjsua_acc *acc; + pjsip_sip_uri *sip_uri; + pj_status_t status; + pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; + pj_str_t local_addr; + unsigned flag; + int secure; + int local_port; + + acc = &pjsua_var.acc[acc_id]; + + /* If route-set is configured for the account, then URI is the + * first entry of the route-set. + */ + if (!pj_list_empty(&acc->route_set)) { + sip_uri = (pjsip_sip_uri*) acc->route_set.next->name_addr.uri; + } else { + pj_str_t tmp; + pjsip_uri *uri; + + pj_strdup_with_null(pool, &tmp, suri); + + uri = pjsip_parse_uri(pool, tmp.ptr, tmp.slen, 0); + if (uri == NULL) + return PJSIP_EINVALIDURI; + + /* For non-SIP scheme, route set should be configured */ + if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) + return PJSIP_EINVALIDREQURI; + + sip_uri = (pjsip_sip_uri*)uri; + } + + /* Get transport type of the URI */ + if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) + tp_type = PJSIP_TRANSPORT_TLS; + else if (sip_uri->transport_param.slen == 0) { + tp_type = PJSIP_TRANSPORT_UDP; + } else + tp_type = pjsip_transport_get_type_from_name(&sip_uri->transport_param); + + if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED) + return PJSIP_EUNSUPTRANSPORT; + + flag = pjsip_transport_get_flag_from_type(tp_type); + secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; + + /* Get local address suitable to send request from */ + status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), + pool, tp_type, &local_addr, &local_port); + if (status != PJ_SUCCESS) + return status; + + /* Create the contact header */ + contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE); + contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE, + "%.*s%s<%s:%.*s%s%.*s:%d;transport=%s>", + (int)acc->display.slen, + acc->display.ptr, + (acc->display.slen?" " : ""), + (secure ? "sips" : "sip"), + (int)acc->user_part.slen, + acc->user_part.ptr, + (acc->user_part.slen?"@":""), + (int)local_addr.slen, + local_addr.ptr, + local_port, + pjsip_transport_get_type_name(tp_type)); + + return PJ_SUCCESS; +} + + + +PJ_DEF(pj_status_t) pjsua_acc_create_uas_contact( pj_pool_t *pool, + pj_str_t *contact, + pjsua_acc_id acc_id, + pjsip_rx_data *rdata ) +{ + /* + * Section 12.1.1, paragraph about using SIPS URI in Contact. + * If the request that initiated the dialog contained a SIPS URI + * in the Request-URI or in the top Record-Route header field value, + * if there was any, or the Contact header field if there was no + * Record-Route header field, the Contact header field in the response + * MUST be a SIPS URI. + */ + pjsua_acc *acc; + pjsip_sip_uri *sip_uri; + pj_status_t status; + pjsip_transport_type_e tp_type = PJSIP_TRANSPORT_UNSPECIFIED; + pj_str_t local_addr; + unsigned flag; + int secure; + int local_port; + + acc = &pjsua_var.acc[acc_id]; + + /* If Record-Route is present, then URI is the top Record-Route. */ + if (rdata->msg_info.record_route) { + sip_uri = (pjsip_sip_uri*) rdata->msg_info.record_route->name_addr.uri; + } else { + pjsip_contact_hdr *h_contact; + pjsip_uri *uri = NULL; + + /* Otherwise URI is Contact URI */ + h_contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, + NULL); + if (h_contact) + uri = pjsip_uri_get_uri(h_contact->uri); + + + /* Or if Contact URI is not present, take the remote URI from + * the From URI. + */ + if (uri == NULL) + uri = pjsip_uri_get_uri(rdata->msg_info.from->uri); + + + /* Can only do sip/sips scheme at present. */ + if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) + return PJSIP_EINVALIDREQURI; + + sip_uri = (pjsip_sip_uri*)uri; + } + + /* Get transport type of the URI */ + if (PJSIP_URI_SCHEME_IS_SIPS(sip_uri)) + tp_type = PJSIP_TRANSPORT_TLS; + else if (sip_uri->transport_param.slen == 0) { + tp_type = PJSIP_TRANSPORT_UDP; + } else + tp_type = pjsip_transport_get_type_from_name(&sip_uri->transport_param); + + if (tp_type == PJSIP_TRANSPORT_UNSPECIFIED) + return PJSIP_EUNSUPTRANSPORT; + + flag = pjsip_transport_get_flag_from_type(tp_type); + secure = (flag & PJSIP_TRANSPORT_SECURE) != 0; + + /* Get local address suitable to send request from */ + status = pjsip_tpmgr_find_local_addr(pjsip_endpt_get_tpmgr(pjsua_var.endpt), + pool, tp_type, &local_addr, &local_port); + if (status != PJ_SUCCESS) + return status; + + /* Create the contact header */ + contact->ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE); + contact->slen = pj_ansi_snprintf(contact->ptr, PJSIP_MAX_URL_SIZE, + "%.*s%s<%s:%.*s%s%.*s:%d;transport=%s>", + (int)acc->display.slen, + acc->display.ptr, + (acc->display.slen?" " : ""), + (secure ? "sips" : "sip"), + (int)acc->user_part.slen, + acc->user_part.ptr, + (acc->user_part.slen?"@":""), + (int)local_addr.slen, + local_addr.ptr, + local_port, + pjsip_transport_get_type_name(tp_type)); + + return PJ_SUCCESS; +} + + + diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index affe787b..e7455e80 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -191,6 +191,7 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, pjsua_acc *acc; pjsua_call *call; unsigned call_id; + pj_str_t contact; pjsip_tx_data *tdata; pj_status_t status; @@ -232,9 +233,18 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id, /* Reset first response time */ call->res_time.sec = 0; + /* Create suitable Contact header */ + status = pjsua_acc_create_uac_contact(pjsua_var.pool, &contact, + acc_id, dest_uri); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); + PJSUA_UNLOCK(); + return status; + } + /* Create outgoing dialog: */ status = pjsip_dlg_create_uac( pjsip_ua_instance(), - &acc->cfg.id, &acc->real_contact, + &acc->cfg.id, &contact, dest_uri, dest_uri, &dlg); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Dialog creation failed", status); @@ -345,6 +355,7 @@ on_error: */ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) { + pj_str_t contact; pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata); pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata); pjsip_msg *msg = rdata->msg_info.msg; @@ -439,10 +450,19 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata) */ acc_id = pjsua_acc_find_for_incoming(rdata); + /* Get suitable Contact header */ + status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact, + acc_id, rdata); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); + pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, + NULL, NULL); + return PJ_TRUE; + } + /* Create dialog: */ status = pjsip_dlg_create_uas( pjsip_ua_instance(), rdata, - &pjsua_var.acc[acc_id].real_contact, - &dlg); + &contact, &dlg); if (status != PJ_SUCCESS) { pjsip_endpt_respond_stateless(pjsua_var.endpt, rdata, 500, NULL, NULL, NULL); @@ -921,6 +941,7 @@ PJ_DEF(pj_status_t) pjsua_call_reinvite( pjsua_call_id call_id, } /* Create SDP */ + PJ_TODO(create_active_inactive_sdp_based_on_unhold_arg); status = pjmedia_endpt_create_sdp( pjsua_var.med_endpt, call->inv->pool, 1, &call->skinfo, &sdp); if (status != PJ_SUCCESS) { diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index f8b32fae..98480b9a 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -986,6 +986,7 @@ PJ_DEF(pj_status_t) pjsua_transport_set_enable( pjsua_transport_id id, /* To be done!! */ PJ_TODO(pjsua_transport_set_enable); + PJ_UNUSED_ARG(enabled); return PJ_EINVALIDOP; } diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c index ae35e9f4..434ec10e 100644 --- a/pjsip/src/pjsua-lib/pjsua_im.c +++ b/pjsip/src/pjsua-lib/pjsua_im.c @@ -417,6 +417,7 @@ PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, const pj_str_t STR_CONTACT = { "Contact", 7 }; pjsip_media_type media_type; pjsua_im_data *im_data; + pj_str_t contact; pj_status_t status; /* To and message body must be specified. */ @@ -437,10 +438,16 @@ PJ_DEF(pj_status_t) pjsua_im_send( pjsua_acc_id acc_id, (pjsip_hdr*)pjsua_im_create_accept(tdata->pool)); /* Add contact. */ + status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); + pjsip_tx_data_dec_ref(tdata); + return status; + } + pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, - &STR_CONTACT, - &pjsua_var.acc[acc_id].real_contact)); + &STR_CONTACT, &contact)); /* Create IM data to keep message details and give it back to * application on the callback @@ -500,6 +507,7 @@ PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, const pj_str_t STR_CONTACT = { "Contact", 7 }; pjsua_im_data *im_data; pjsip_tx_data *tdata; + pj_str_t contact; pj_status_t status; /* Create request. */ @@ -518,10 +526,16 @@ PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id, /* Add contact. */ + status = pjsua_acc_create_uac_contact(tdata->pool, &contact, acc_id, to); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); + pjsip_tx_data_dec_ref(tdata); + return status; + } + pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, - &STR_CONTACT, - &pjsua_var.acc[acc_id].real_contact)); + &STR_CONTACT, &contact)); /* Create "application/im-iscomposing+xml" msg body. */ diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index 4af2b6e0..cba0724c 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -440,6 +440,7 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) { int acc_id; pjsua_acc *acc; + pj_str_t contact; pjsip_method *req_method = &rdata->msg_info.msg->line.req.method; pjsua_srv_pres *uapres; pjsip_evsub *sub; @@ -463,10 +464,18 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata) PJ_LOG(4,(THIS_FILE, "Creating server subscription, using account %d", acc_id)); + /* Create suitable Contact header */ + status = pjsua_acc_create_uas_contact(rdata->tp_info.pool, &contact, + acc_id, rdata); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); + PJSUA_UNLOCK(); + return PJ_TRUE; + } + /* Create UAS dialog: */ status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, - &acc->real_contact, - &dlg); + &contact, &dlg); if (status != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Unable to create UAS dialog for subscription", @@ -761,6 +770,7 @@ static void subscribe_buddy_presence(unsigned index) pjsua_buddy *buddy; int acc_id; pjsua_acc *acc; + pj_str_t contact; pjsip_dialog *dlg; pjsip_tx_data *tdata; pj_status_t status; @@ -773,10 +783,18 @@ static void subscribe_buddy_presence(unsigned index) PJ_LOG(4,(THIS_FILE, "Using account %d for buddy %d subscription", acc_id, index)); + /* Generate suitable Contact header */ + status = pjsua_acc_create_uac_contact(pjsua_var.pool, &contact, + acc_id, &buddy->uri); + if (status != PJ_SUCCESS) { + pjsua_perror(THIS_FILE, "Unable to generate Contact header", status); + return; + } + /* Create UAC dialog */ status = pjsip_dlg_create_uac( pjsip_ua_instance(), &acc->cfg.id, - &acc->real_contact, + &contact, &buddy->uri, NULL, &dlg); if (status != PJ_SUCCESS) { |