Fixed #1965: Add support to specify Contact params specific to REGISTER requests

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@5455 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Sauw Ming 2016-10-07 07:42:22 +00:00
parent 594c1bd214
commit 9160ae5ad7
4 changed files with 71 additions and 22 deletions

View File

@ -2953,6 +2953,17 @@ typedef struct pjsua_acc_config
*/
pjsip_hdr reg_hdr_list;
/**
* Additional parameters that will be appended in the Contact header
* for this account. This will only affect REGISTER requests and
* will be appended after \a contact_params;
*
* The parameters should be preceeded by semicolon, and all strings must
* be properly escaped. Example:
* ";my-param=X;another-param=Hi%20there"
*/
pj_str_t reg_contact_params;
/**
* The optional custom SIP headers to be put in the presence
* subscription request.

View File

@ -69,6 +69,17 @@ struct AccountRegConfig : public PersistentObject
*/
SipHeaderVector headers;
/**
* Additional parameters that will be appended in the Contact header
* of the registration requests. This will be appended after
* \a AccountSipConfig.contactParams;
*
* The parameters should be preceeded by semicolon, and all strings must
* be properly escaped. Example:
* ";my-param=X;another-param=Hi%20there"
*/
string contactParams;
/**
* Optional interval for registration, in seconds. If the value is zero,
* default interval will be used (PJSUA_REG_INTERVAL, 300 seconds).

View File

@ -87,6 +87,8 @@ PJ_DEF(void) pjsua_acc_config_dup( pj_pool_t *pool,
pj_strdup_with_null(pool, &dst->id, &src->id);
pj_strdup_with_null(pool, &dst->reg_uri, &src->reg_uri);
pj_strdup_with_null(pool, &dst->force_contact, &src->force_contact);
pj_strdup_with_null(pool, &dst->reg_contact_params,
&src->reg_contact_params);
pj_strdup_with_null(pool, &dst->contact_params, &src->contact_params);
pj_strdup_with_null(pool, &dst->contact_uri_params,
&src->contact_uri_params);
@ -994,6 +996,13 @@ PJ_DEF(pj_status_t) pjsua_acc_modify( pjsua_acc_id acc_id,
unreg_first = PJ_TRUE;
}
/* Register contact params */
if (pj_strcmp(&acc->cfg.reg_contact_params, &cfg->reg_contact_params)) {
pj_strdup_with_null(acc->pool, &acc->cfg.reg_contact_params,
&cfg->reg_contact_params);
update_reg = PJ_TRUE;
}
/* Contact param */
if (pj_strcmp(&acc->cfg.contact_params, &cfg->contact_params)) {
pj_strdup_with_null(acc->pool, &acc->cfg.contact_params,
@ -1477,35 +1486,49 @@ static void update_regc_contact(pjsua_acc *acc)
need_outbound = PJ_TRUE;
done:
if (!need_outbound) {
/* Outbound is not needed/wanted for the account. acc->reg_contact
* is set to the same as acc->contact.
*/
acc->reg_contact = acc->contact;
acc->rfc5626_status = OUTBOUND_NA;
} else {
/* Need to use outbound, append the contact with +sip.instance and
* reg-id parameters.
*/
{
pj_ssize_t len;
pj_str_t reg_contact;
acc->rfc5626_status = OUTBOUND_WANTED;
len = acc->contact.slen + acc->rfc5626_instprm.slen +
acc->rfc5626_regprm.slen;
reg_contact.ptr = (char*) pj_pool_alloc(acc->pool, len);
len = acc->contact.slen + acc->cfg.reg_contact_params.slen +
(need_outbound?
(acc->rfc5626_instprm.slen + acc->rfc5626_regprm.slen): 0);
if (len > acc->contact.slen) {
reg_contact.ptr = (char*) pj_pool_alloc(acc->pool, len);
pj_strcpy(&reg_contact, &acc->contact);
pj_strcat(&reg_contact, &acc->rfc5626_regprm);
pj_strcat(&reg_contact, &acc->rfc5626_instprm);
pj_strcpy(&reg_contact, &acc->contact);
if (need_outbound) {
acc->rfc5626_status = OUTBOUND_WANTED;
acc->reg_contact = reg_contact;
/* Need to use outbound, append the contact with
* +sip.instance and reg-id parameters.
*/
pj_strcat(&reg_contact, &acc->rfc5626_regprm);
pj_strcat(&reg_contact, &acc->rfc5626_instprm);
} else {
acc->rfc5626_status = OUTBOUND_NA;
}
PJ_LOG(4,(THIS_FILE,
"Contact for acc %d updated for SIP outbound: %.*s",
acc->index,
(int)acc->reg_contact.slen,
acc->reg_contact.ptr));
pj_strcat(&reg_contact, &acc->cfg.reg_contact_params);
acc->reg_contact = reg_contact;
PJ_LOG(4,(THIS_FILE,
"Contact for acc %d updated: %.*s",
acc->index,
(int)acc->reg_contact.slen,
acc->reg_contact.ptr));
} else {
/* Outbound is not needed/wanted for the account and there's
* no custom registration Contact params. acc->reg_contact
* is set to the same as acc->contact.
*/
acc->reg_contact = acc->contact;
acc->rfc5626_status = OUTBOUND_NA;
}
}
}

View File

@ -43,6 +43,7 @@ void AccountRegConfig::readObject(const ContainerNode &node) throw(Error)
NODE_READ_BOOL (this_node, dropCallsOnFail);
NODE_READ_UNSIGNED (this_node, unregWaitMsec);
NODE_READ_UNSIGNED (this_node, proxyUse);
NODE_READ_STRING (this_node, contactParams);
readSipHeaders(this_node, "headers", headers);
}
@ -61,6 +62,7 @@ void AccountRegConfig::writeObject(ContainerNode &node) const throw(Error)
NODE_WRITE_BOOL (this_node, dropCallsOnFail);
NODE_WRITE_UNSIGNED (this_node, unregWaitMsec);
NODE_WRITE_UNSIGNED (this_node, proxyUse);
NODE_WRITE_STRING (this_node, contactParams);
writeSipHeaders(this_node, "headers", headers);
}
@ -329,6 +331,7 @@ void AccountConfig::toPj(pjsua_acc_config &ret) const
ret.drop_calls_on_reg_fail = regConfig.dropCallsOnFail;
ret.unreg_timeout = regConfig.unregWaitMsec;
ret.reg_use_proxy = regConfig.proxyUse;
ret.reg_contact_params = str2Pj(regConfig.contactParams);
for (i=0; i<regConfig.headers.size(); ++i) {
pj_list_push_back(&ret.reg_hdr_list, &regConfig.headers[i].toPj());
}
@ -463,6 +466,7 @@ void AccountConfig::fromPj(const pjsua_acc_config &prm,
regConfig.dropCallsOnFail = PJ2BOOL(prm.drop_calls_on_reg_fail);
regConfig.unregWaitMsec = prm.unreg_timeout;
regConfig.proxyUse = prm.reg_use_proxy;
regConfig.contactParams = pj2Str(prm.reg_contact_params);
regConfig.headers.clear();
hdr = prm.reg_hdr_list.next;
while (hdr != &prm.reg_hdr_list) {