summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsip-simple
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-06-15 16:03:40 +0000
committerBenny Prijono <bennylp@teluu.com>2009-06-15 16:03:40 +0000
commitf44d17658e64639499d53b2c524718546bb2bd5e (patch)
tree73ab08185b3e4345eb44b197ce4dcfc6e8d465de /pjsip/src/pjsip-simple
parent95b0b178d8f25b6342f8821747404c8ac3d047e7 (diff)
Ticket #873: Include the parsed XML tuple in the pjsip_pres_status, and include it in the pjsua_buddy_info in PJSUA-LIB, in case the PIDF document contains other info that is needed by application (thanks Johan Lantz for the suggestion)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2762 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsip-simple')
-rw-r--r--pjsip/src/pjsip-simple/presence.c79
-rw-r--r--pjsip/src/pjsip-simple/presence_body.c29
2 files changed, 98 insertions, 10 deletions
diff --git a/pjsip/src/pjsip-simple/presence.c b/pjsip/src/pjsip-simple/presence.c
index 31c83fc1..24049359 100644
--- a/pjsip/src/pjsip-simple/presence.c
+++ b/pjsip/src/pjsip-simple/presence.c
@@ -73,7 +73,9 @@ struct pjsip_pres
pjsip_evsub *sub; /**< Event subscribtion record. */
pjsip_dialog *dlg; /**< The dialog. */
content_type_e content_type; /**< Content-Type. */
+ pj_pool_t *status_pool; /**< Pool for pres_status */
pjsip_pres_status status; /**< Presence status. */
+ pj_pool_t *tmp_pool; /**< Pool for tmp_status */
pjsip_pres_status tmp_status; /**< Temp, before NOTIFY is answred.*/
pjsip_evsub_user user_cb; /**< The user callback. */
};
@@ -185,6 +187,7 @@ PJ_DEF(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg,
{
pj_status_t status;
pjsip_pres *pres;
+ char obj_name[PJ_MAX_OBJ_NAME];
pjsip_evsub *sub;
PJ_ASSERT_RETURN(dlg && p_evsub, PJ_EINVAL);
@@ -204,6 +207,13 @@ PJ_DEF(pj_status_t) pjsip_pres_create_uac( pjsip_dialog *dlg,
if (user_cb)
pj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));
+ pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "pres%p", dlg->pool);
+ pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name,
+ 512, 512, NULL);
+ pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "tmpres%p", dlg->pool);
+ pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name,
+ 512, 512, NULL);
+
/* Attach to evsub */
pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);
@@ -228,6 +238,7 @@ PJ_DEF(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,
content_type_e content_type = CONTENT_TYPE_NONE;
pjsip_evsub *sub;
pjsip_pres *pres;
+ char obj_name[PJ_MAX_OBJ_NAME];
pj_status_t status;
/* Check arguments */
@@ -297,6 +308,13 @@ PJ_DEF(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,
if (user_cb)
pj_memcpy(&pres->user_cb, user_cb, sizeof(pjsip_evsub_user));
+ pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "pres%p", dlg->pool);
+ pres->status_pool = pj_pool_create(dlg->pool->factory, obj_name,
+ 512, 512, NULL);
+ pj_ansi_snprintf(obj_name, PJ_MAX_OBJ_NAME, "tmpres%p", dlg->pool);
+ pres->tmp_pool = pj_pool_create(dlg->pool->factory, obj_name,
+ 512, 512, NULL);
+
/* Attach to evsub */
pjsip_evsub_set_mod_data(sub, mod_presence.id, pres);
@@ -355,10 +373,13 @@ PJ_DEF(pj_status_t) pjsip_pres_get_status( pjsip_evsub *sub,
pres = (pjsip_pres*) pjsip_evsub_get_mod_data(sub, mod_presence.id);
PJ_ASSERT_RETURN(pres!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
- if (pres->tmp_status._is_valid)
+ if (pres->tmp_status._is_valid) {
+ PJ_ASSERT_RETURN(pres->tmp_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
pj_memcpy(status, &pres->tmp_status, sizeof(pjsip_pres_status));
- else
+ } else {
+ PJ_ASSERT_RETURN(pres->status_pool!=NULL, PJSIP_SIMPLE_ENOPRESENCE);
pj_memcpy(status, &pres->status, sizeof(pjsip_pres_status));
+ }
return PJ_SUCCESS;
}
@@ -371,6 +392,7 @@ PJ_DEF(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,
const pjsip_pres_status *status )
{
unsigned i;
+ pj_pool_t *tmp;
pjsip_pres *pres;
PJ_ASSERT_RETURN(sub && status, PJ_EINVAL);
@@ -380,7 +402,9 @@ PJ_DEF(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,
for (i=0; i<status->info_cnt; ++i) {
pres->status.info[i].basic_open = status->info[i].basic_open;
- if (status->info[i].id.slen == 0) {
+ if (pres->status.info[i].id.slen) {
+ /* Id already set */
+ } else if (status->info[i].id.slen == 0) {
pj_create_unique_string(pres->dlg->pool,
&pres->status.info[i].id);
} else {
@@ -388,17 +412,17 @@ PJ_DEF(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,
&pres->status.info[i].id,
&status->info[i].id);
}
- pj_strdup(pres->dlg->pool,
+ pj_strdup(pres->tmp_pool,
&pres->status.info[i].contact,
&status->info[i].contact);
/* Duplicate <person> */
pres->status.info[i].rpid.activity =
status->info[i].rpid.activity;
- pj_strdup(pres->dlg->pool,
+ pj_strdup(pres->tmp_pool,
&pres->status.info[i].rpid.id,
&status->info[i].rpid.id);
- pj_strdup(pres->dlg->pool,
+ pj_strdup(pres->tmp_pool,
&pres->status.info[i].rpid.note,
&status->info[i].rpid.note);
@@ -406,6 +430,12 @@ PJ_DEF(pj_status_t) pjsip_pres_set_status( pjsip_evsub *sub,
pres->status.info_cnt = status->info_cnt;
+ /* Swap pools */
+ tmp = pres->tmp_pool;
+ pres->tmp_pool = pres->status_pool;
+ pres->status_pool = tmp;
+ pj_pool_reset(pres->tmp_pool);
+
return PJ_SUCCESS;
}
@@ -572,6 +602,17 @@ static void pres_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
if (pres->user_cb.on_evsub_state)
(*pres->user_cb.on_evsub_state)(sub, event);
+
+ if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
+ if (pres->status_pool) {
+ pj_pool_release(pres->status_pool);
+ pres->status_pool = NULL;
+ }
+ if (pres->tmp_pool) {
+ pj_pool_release(pres->tmp_pool);
+ pres->tmp_pool = NULL;
+ }
+ }
}
/*
@@ -670,14 +711,14 @@ static pj_status_t pres_process_rx_notify( pjsip_pres *pres,
if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
pj_stricmp(&ctype_hdr->media.subtype, &STR_PIDF_XML)==0)
{
- status = pjsip_pres_parse_pidf( rdata, pres->dlg->pool,
+ status = pjsip_pres_parse_pidf( rdata, pres->tmp_pool,
&pres->tmp_status);
}
else
if (pj_stricmp(&ctype_hdr->media.type, &STR_APPLICATION)==0 &&
pj_stricmp(&ctype_hdr->media.subtype, &STR_XPIDF_XML)==0)
{
- status = pjsip_pres_parse_xpidf( rdata, pres->dlg->pool,
+ status = pjsip_pres_parse_xpidf( rdata, pres->tmp_pool,
&pres->tmp_status);
}
else
@@ -740,11 +781,23 @@ static void pres_on_evsub_rx_notify( pjsip_evsub *sub,
return;
} else {
+#if 1
+ /* This is the newest change, http://trac.pjsip.org/repos/ticket/873
+ * Some app want to be notified about the empty NOTIFY, e.g. to
+ * decide whether it should consider the buddy as offline.
+ * In this case, leave the buddy state unchanged, but set the
+ * "tuple_node" in pjsip_pres_status to NULL.
+ */
+ unsigned i;
+ for (i=0; i<pres->status.info_cnt; ++i) {
+ pres->status.info[i].tuple_node = NULL;
+ }
+
+#elif 0
/* This has just been changed. Previously, we treat incoming NOTIFY
* with no message body as having the presence subscription closed.
* Now we treat it as no change in presence status (ref: EyeBeam).
*/
-#if 1
*p_st_code = 200;
return;
#else
@@ -767,10 +820,18 @@ static void pres_on_evsub_rx_notify( pjsip_evsub *sub,
* to main status, and mark the temporary status as invalid.
*/
if ((*p_st_code)/100 == 2) {
+ pj_pool_t *tmp;
+
pj_memcpy(&pres->status, &pres->tmp_status, sizeof(pjsip_pres_status));
+
+ /* Swap the pool */
+ tmp = pres->tmp_pool;
+ pres->tmp_pool = pres->status_pool;
+ pres->status_pool = tmp;
}
pres->tmp_status._is_valid = PJ_FALSE;
+ pj_pool_reset(pres->tmp_pool);
/* Done */
}
diff --git a/pjsip/src/pjsip-simple/presence_body.c b/pjsip/src/pjsip-simple/presence_body.c
index 6b215b47..30b6318f 100644
--- a/pjsip/src/pjsip-simple/presence_body.c
+++ b/pjsip/src/pjsip-simple/presence_body.c
@@ -100,6 +100,29 @@ PJ_DEF(pj_status_t) pjsip_pres_create_pidf( pj_pool_t *pool,
pidf_status = pjpidf_tuple_get_status(pidf_tuple);
pjpidf_status_set_basic_open(pidf_status,
status->info[i].basic_open);
+
+ /* Add <timestamp> if configured */
+#if defined(PJSIP_PRES_PIDF_ADD_TIMESTAMP) && PJSIP_PRES_PIDF_ADD_TIMESTAMP
+ if (PJSIP_PRES_PIDF_ADD_TIMESTAMP) {
+ char buf[50];
+ int tslen = 0;
+ pj_time_val tv;
+ pj_parsed_time pt;
+
+ pj_gettimeofday(&tv);
+ /* TODO: convert time to GMT! (unsupported by pjlib) */
+ pj_time_decode( &tv, &pt);
+
+ tslen = pj_ansi_snprintf(buf, sizeof(buf),
+ "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
+ pt.year, pt.mon, pt.day,
+ pt.hour, pt.min, pt.sec, pt.msec);
+ if (tslen > 0 && tslen < sizeof(buf)) {
+ pj_str_t time = pj_str(buf);
+ pjpidf_tuple_set_timestamp(pool, pidf_tuple, &time);
+ }
+ }
+#endif
}
/* Create <person> (RPID) */
@@ -179,9 +202,12 @@ PJ_DEF(pj_status_t) pjsip_pres_parse_pidf( pjsip_rx_data *rdata,
pres_status->info_cnt = 0;
pidf_tuple = pjpidf_pres_get_first_tuple(pidf);
- while (pidf_tuple) {
+ while (pidf_tuple && pres_status->info_cnt < PJSIP_PRES_STATUS_MAX_INFO) {
pjpidf_status *pidf_status;
+ pres_status->info[pres_status->info_cnt].tuple_node =
+ pj_xml_clone(pool, pidf_tuple);
+
pj_strdup(pool,
&pres_status->info[pres_status->info_cnt].id,
pjpidf_tuple_get_id(pidf_tuple));
@@ -231,6 +257,7 @@ PJ_DEF(pj_status_t) pjsip_pres_parse_xpidf(pjsip_rx_data *rdata,
pjxpidf_get_uri(xpidf));
pres_status->info[0].basic_open = pjxpidf_get_status(xpidf);
pres_status->info[0].id.slen = 0;
+ pres_status->info[0].tuple_node = NULL;
return PJ_SUCCESS;
}