summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-04-28 22:19:49 +0000
committerBenny Prijono <bennylp@teluu.com>2009-04-28 22:19:49 +0000
commit00ed64489de3c39a6a452e11bb43b2c1090c9307 (patch)
treee871adbe53ea5daa64515cdb0feb1102df7e34cc /pjsip
parent7a0ee1a7208ddfe8575d1f1179f66fda2fa99339 (diff)
Ticket #760: Enhancements to PUBLISH management (thanks Johan Lantz for the suggestion)
- Changes in PJSUA-LIB - retry with fresh request on 412/Conditional Request Failed response - changed default Expires in PUBLISH request to none (we will not put Expires), to avoid getting 423/Interval Too Brief response - if the PUBLISH fails for any reason, it will be retried on every PJSUA_PRES_TIMER (default 300 seconds), similar to how failed SUBSCRIBE will be retried - Changes to publish.h: - added API to add headers in every PUBLISH request - Added test scenario in Python unit tests git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2661 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip-simple/publish.h23
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h5
-rw-r--r--pjsip/src/pjsip-simple/publishc.c38
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c30
4 files changed, 88 insertions, 8 deletions
diff --git a/pjsip/include/pjsip-simple/publish.h b/pjsip/include/pjsip-simple/publish.h
index ebbd1cf1..3c7c7d55 100644
--- a/pjsip/include/pjsip-simple/publish.h
+++ b/pjsip/include/pjsip-simple/publish.h
@@ -78,7 +78,9 @@ struct pjsip_publishc_cbparam
int code; /**< SIP status code received. */
pj_str_t reason; /**< SIP reason phrase received. */
pjsip_rx_data *rdata; /**< The complete received response. */
- int expiration;/**< Next expiration interval. */
+ int expiration;/**< Next expiration interval. If the
+ value is -1, it means the session
+ will not renew itself. */
};
@@ -190,6 +192,25 @@ PJ_DECL(pj_status_t) pjsip_publishc_set_route_set(pjsip_publishc *pubc,
/**
+ * Set list of headers to be added to each PUBLISH request generated by
+ * the client publication session. Note that application can also add
+ * the headers to the request after calling #pjsip_publishc_publish()
+ * or #pjsip_publishc_unpublish(), but the benefit of this function is
+ * the headers will also be added to requests generated internally by
+ * the session, such as during session renewal/refresh.
+ *
+ * Note that calling this function will clear the previously added list
+ * of headers.
+ *
+ * @param pubc The client publication structure.
+ * @param hdr_list The list of headers.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_publishc_set_headers(pjsip_publishc *pubc,
+ const pjsip_hdr *hdr_list);
+
+/**
* Create PUBLISH request for the specified client publication structure.
* Application can use this function to both create initial publication
* or to modify existing publication.
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 99869344..e17a7f64 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -2037,7 +2037,7 @@ PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id,
* Default PUBLISH expiration
*/
#ifndef PJSUA_PUBLISH_EXPIRATION
-# define PJSUA_PUBLISH_EXPIRATION 600
+# define PJSUA_PUBLISH_EXPIRATION PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED
#endif
@@ -3493,7 +3493,8 @@ PJ_DECL(pj_status_t) pjsua_call_dump(pjsua_call_id call_id,
/**
* This specifies how long the library should retry resending SUBSCRIBE
- * if the previous SUBSCRIBE failed.
+ * if the previous SUBSCRIBE failed. This also controls the duration
+ * before failed PUBLISH request will be retried.
*
* Default: 300 seconds
*/
diff --git a/pjsip/src/pjsip-simple/publishc.c b/pjsip/src/pjsip-simple/publishc.c
index 6840d028..2f5b415e 100644
--- a/pjsip/src/pjsip-simple/publishc.c
+++ b/pjsip/src/pjsip-simple/publishc.c
@@ -81,6 +81,7 @@ struct pjsip_publishc
pjsip_expires_hdr *expires_hdr;
pj_uint32_t expires;
pjsip_route_hdr route_set;
+ pjsip_hdr usr_hdr;
/* Authorization sessions. */
pjsip_auth_clt_sess auth_sess;
@@ -157,6 +158,7 @@ PJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt,
return status;
pj_list_init(&pubc->route_set);
+ pj_list_init(&pubc->usr_hdr);
/* Done */
*p_pubc = pubc;
@@ -186,7 +188,9 @@ PJ_DEF(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc)
static void set_expires( pjsip_publishc *pubc, pj_uint32_t expires)
{
- if (expires != pubc->expires) {
+ if (expires != pubc->expires &&
+ expires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED)
+ {
pubc->expires_hdr = pjsip_expires_hdr_create(pubc->pool, expires);
} else {
pubc->expires_hdr = NULL;
@@ -281,6 +285,23 @@ PJ_DEF(pj_status_t) pjsip_publishc_set_route_set( pjsip_publishc *pubc,
return PJ_SUCCESS;
}
+PJ_DEF(pj_status_t) pjsip_publishc_set_headers( pjsip_publishc *pubc,
+ const pjsip_hdr *hdr_list)
+{
+ const pjsip_hdr *h;
+
+ PJ_ASSERT_RETURN(pubc && hdr_list, PJ_EINVAL);
+
+ pj_list_init(&pubc->usr_hdr);
+ h = hdr_list->next;
+ while (h != hdr_list) {
+ pj_list_push_back(&pubc->usr_hdr, pjsip_hdr_clone(pubc->pool, h));
+ h = h->next;
+ }
+
+ return PJ_SUCCESS;
+}
+
static pj_status_t create_request(pjsip_publishc *pubc,
pjsip_tx_data **p_tdata)
{
@@ -345,6 +366,19 @@ static pj_status_t create_request(pjsip_publishc *pubc,
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
}
+ /* Add user headers */
+ if (!pj_list_empty(&pubc->usr_hdr)) {
+ const pjsip_hdr *hdr;
+
+ hdr = pubc->usr_hdr.next;
+ while (hdr != &pubc->usr_hdr) {
+ pjsip_hdr *new_hdr = (pjsip_hdr*)
+ pjsip_hdr_shallow_clone(tdata->pool, hdr);
+ pjsip_msg_add_hdr(tdata->msg, new_hdr);
+ hdr = hdr->next;
+ }
+ }
+
/* Done. */
*p_tdata = tdata;
@@ -530,7 +564,7 @@ static void tsx_callback(void *token, pjsip_event *event)
expires = (pjsip_expires_hdr*)
pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL);
- if (expires)
+ if (pubc->auto_refresh && expires)
expiration = expires->ivalue;
if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) {
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index d619dd47..d980e617 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -961,6 +961,10 @@ static void publish_cb(struct pjsip_publishc_cbparam *param)
pjsua_acc *acc = (pjsua_acc*) param->token;
if (param->code/100 != 2 || param->status != PJ_SUCCESS) {
+
+ pjsip_publishc_destroy(param->pubc);
+ acc->publish_sess = NULL;
+
if (param->status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
@@ -968,6 +972,12 @@ static void publish_cb(struct pjsip_publishc_cbparam *param)
PJ_LOG(1,(THIS_FILE,
"Client publication (PUBLISH) failed, status=%d, msg=%s",
param->status, errmsg));
+ } else if (param->code == 412) {
+ /* 412 (Conditional Request Failed)
+ * The PUBLISH refresh has failed, retry with new one.
+ */
+ pjsua_pres_init_publish_acc(acc->index);
+
} else {
PJ_LOG(1,(THIS_FILE,
"Client publication (PUBLISH) failed (%d/%.*s)",
@@ -975,8 +985,14 @@ static void publish_cb(struct pjsip_publishc_cbparam *param)
param->reason.ptr));
}
- pjsip_publishc_destroy(param->pubc);
- acc->publish_sess = NULL;
+ } else {
+ if (param->expiration == -1) {
+ /* Could happen if server "forgot" to include Expires header
+ * in the response. We will not renew, so destroy the pubc.
+ */
+ pjsip_publishc_destroy(param->pubc);
+ acc->publish_sess = NULL;
+ }
}
}
@@ -1091,7 +1107,7 @@ pj_status_t pjsua_pres_init_publish_acc(int acc_id)
status = pjsip_publishc_init(acc->publish_sess, &STR_PRESENCE,
&acc_cfg->id, &acc_cfg->id,
&acc_cfg->id,
- PJSUA_PRES_TIMER);
+ PJSUA_PUBLISH_EXPIRATION);
if (status != PJ_SUCCESS) {
acc->publish_sess = NULL;
return status;
@@ -1606,8 +1622,16 @@ static void refresh_client_subscriptions(void)
static void pres_timer_cb(pj_timer_heap_t *th,
pj_timer_entry *entry)
{
+ unsigned i;
pj_time_val delay = { PJSUA_PRES_TIMER, 0 };
+ /* Retry failed PUBLISH requests */
+ for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) {
+ pjsua_acc *acc = &pjsua_var.acc[i];
+ if (acc->cfg.publish_enabled && acc->publish_sess==NULL)
+ pjsua_pres_init_publish_acc(acc->index);
+ }
+
entry->id = PJ_FALSE;
refresh_client_subscriptions();