summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-07-18 00:33:02 +0000
committerBenny Prijono <bennylp@teluu.com>2006-07-18 00:33:02 +0000
commit65035358b4b7f51b4183a0937e9e93ff130d7525 (patch)
treed38d458e390fd2ac04e91f90bac5b856f4089c4c
parentcbb6c140cf6e47e65b31b93009cfe39916933009 (diff)
More intelligent PJSUA-LIB in selecting the appropriate address for Contact header
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@611 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/include/pjsip/sip_transport.h28
-rw-r--r--pjsip/include/pjsip/sip_uri.h17
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h35
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h2
-rw-r--r--pjsip/src/pjsip/sip_transport.c83
-rw-r--r--pjsip/src/pjsip/sip_uri.c13
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c233
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c27
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c1
-rw-r--r--pjsip/src/pjsua-lib/pjsua_im.c22
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c24
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) {