Skip to content

Commit 7b055fd

Browse files
committed
Support basic Busy Lamp Field (BLF) function as server (#4474)
Tested with Yealink phones (models T77U, T34W, T31P, T30P)
1 parent c1eb792 commit 7b055fd

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

pjsip/include/pjsip-simple/presence.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,25 @@ PJ_DECL(pj_status_t) pjsip_pres_parse_xpidf2(char *body, unsigned body_len,
403403
pjsip_pres_status *status);
404404

405405

406+
/**
407+
* This is a utility function to create DIALOG-INFO message body from PJSIP
408+
* presence status.
409+
*
410+
* @param pool The pool to allocate memory for the message body.
411+
* @param status Presence status to be converted into DIALOG-INFO
412+
* message body.
413+
* @param entity The entity ID, which normally is equal to the
414+
* presentity ID publishing this presence info.
415+
* @param p_body Pointer to receive the SIP message body.
416+
*
417+
* @return PJ_SUCCESS on success.
418+
*/
419+
PJ_DECL(pj_status_t) pjsip_pres_create_dialog_info(pj_pool_t* pool,
420+
const pjsip_pres_status* status,
421+
const pj_str_t* entity,
422+
pjsip_msg_body** p_body);
423+
424+
406425

407426
/**
408427
* @}

pjsip/src/pjsip-simple/presence.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ typedef enum content_type_e
6969
CONTENT_TYPE_NONE,
7070
CONTENT_TYPE_PIDF,
7171
CONTENT_TYPE_XPIDF,
72+
CONTENT_TYPE_DIALOG_INFO,
7273
} content_type_e;
7374

7475
/*
@@ -133,11 +134,13 @@ static pjsip_evsub_user pres_user =
133134
*/
134135
static const pj_str_t STR_EVENT = { "Event", 5 };
135136
static const pj_str_t STR_PRESENCE = { "presence", 8 };
137+
static const pj_str_t STR_DIALOG = { "dialog", 6 };
136138
static const pj_str_t STR_APPLICATION = { "application", 11 };
137139
static const pj_str_t STR_PIDF_XML = { "pidf+xml", 8};
138140
static const pj_str_t STR_XPIDF_XML = { "xpidf+xml", 9};
139141
static const pj_str_t STR_APP_PIDF_XML = { "application/pidf+xml", 20 };
140142
static const pj_str_t STR_APP_XPIDF_XML = { "application/xpidf+xml", 21 };
143+
static const pj_str_t STR_APP_DIALOG_INFO_XML = { "application/dialog-info+xml", 27 };
141144

142145

143146
/*
@@ -273,6 +276,10 @@ PJ_DEF(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,
273276
return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_REQUEST);
274277
}
275278
if (pj_stricmp(&event->event_type, &STR_PRESENCE) != 0) {
279+
}
280+
else if (pj_stricmp(&event->event_type, &STR_DIALOG) != 0) {
281+
}
282+
else {
276283
return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_BAD_EVENT);
277284
}
278285

@@ -289,6 +296,10 @@ PJ_DEF(pj_status_t) pjsip_pres_create_uas( pjsip_dialog *dlg,
289296
if (pj_stricmp(&accept->values[i], &STR_APP_XPIDF_XML)==0) {
290297
content_type = CONTENT_TYPE_XPIDF;
291298
break;
299+
} else
300+
if (pj_stricmp(&accept->values[i], &STR_APP_DIALOG_INFO_XML) == 0) {
301+
content_type = CONTENT_TYPE_DIALOG_INFO;
302+
break;
292303
}
293304
}
294305

@@ -499,6 +510,11 @@ static pj_status_t pres_create_msg_body( pjsip_pres *pres,
499510
return pjsip_pres_create_xpidf(tdata->pool, &pres->status,
500511
&entity, &tdata->msg->body);
501512

513+
} else if (pres->content_type == CONTENT_TYPE_DIALOG_INFO) {
514+
515+
return pjsip_pres_create_dialog_info(tdata->pool, &pres->status,
516+
&entity, &tdata->msg->body);
517+
502518
} else {
503519
return PJSIP_SIMPLE_EBADCONTENT;
504520
}

pjsip/src/pjsip-simple/presence_body.c

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <pj/os.h>
2626
#include <pj/pool.h>
2727
#include <pj/string.h>
28+
#include <pjsip-simple/dialog_info.h>
2829

2930

3031
#define THIS_FILE "presence_body.c"
@@ -33,7 +34,14 @@
3334
static const pj_str_t STR_APPLICATION = { "application", 11 };
3435
static const pj_str_t STR_PIDF_XML = { "pidf+xml", 8 };
3536
static const pj_str_t STR_XPIDF_XML = { "xpidf+xml", 9 };
36-
37+
static const pj_str_t STR_DIALOG_INFO_XML = { "dialog-info+xml", 15 };
38+
//static pj_str_t STR_TRYING = { "trying", 6 };
39+
//static pj_str_t STR_PROCEEDING = { "proceeding", 10 };
40+
//static pj_str_t STR_EARLY = { "early", 5 };
41+
static pj_str_t STR_CONFIRMED = { "confirmed", 9 };
42+
static pj_str_t STR_TERMINATED = { "terminated", 10 };
43+
static pj_str_t STR_VERSION = { "1.0", 3 };
44+
static pj_str_t STR_EMPTY_STRING = { NULL, 0 };
3745

3846

3947

@@ -294,3 +302,48 @@ PJ_DEF(pj_status_t) pjsip_pres_parse_xpidf2(char *body, unsigned body_len,
294302
}
295303

296304

305+
/*
306+
* This is a utility function to create DIALOG-INFO message body from PJSIP
307+
* presence status (pjsip_pres_status).
308+
*/
309+
PJ_DEF(pj_status_t) pjsip_pres_create_dialog_info(pj_pool_t* pool,
310+
const pjsip_pres_status* status,
311+
const pj_str_t* entity,
312+
pjsip_msg_body** p_body)
313+
{
314+
pjsip_dlg_info_dialog* dlginfo;
315+
pjsip_msg_body* body;
316+
317+
pjrpid_element rpid = status->info[0].rpid;
318+
pj_bool_t basic_open = status->info[0].basic_open;
319+
320+
const pj_str_t* state;
321+
322+
if (basic_open) {
323+
if (rpid.activity == PJRPID_ACTIVITY_BUSY) {
324+
state = &STR_CONFIRMED;
325+
}
326+
else {
327+
state = &STR_TERMINATED;
328+
}
329+
}
330+
else {
331+
//pjsip_dlg_info_dialog_set_state(pool, dlginfo, &STR_TERMINATED);
332+
state = &STR_TERMINATED;
333+
}
334+
335+
/* Create DIALOG-INFO document. */
336+
dlginfo = pjsip_dlg_info_create(pool, &STR_VERSION, state, entity);
337+
338+
body = PJ_POOL_ZALLOC_T(pool, pjsip_msg_body);
339+
body->data = dlginfo;
340+
body->content_type.type = STR_APPLICATION;
341+
body->content_type.subtype = STR_DIALOG_INFO_XML;
342+
body->print_body = &pres_print_body;
343+
body->clone_data = &xml_clone_data;
344+
345+
*p_body = body;
346+
347+
return PJ_SUCCESS;
348+
}
349+

0 commit comments

Comments
 (0)