Added initial "norefersub" (RFC 4488) implementation in PJSUA-LIB, and also properly register all supported SIP method, accepted content type, and supported extensions to endpoint.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@688 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
3a5e1ab170
commit
c8141a834a
|
@ -40,9 +40,17 @@
|
|||
#define THIS_FILE "publishc.c"
|
||||
|
||||
|
||||
/* Let's define this enum, so that it'll trigger compilation error
|
||||
* when somebody define the same enum in sip_msg.h
|
||||
*/
|
||||
enum
|
||||
{
|
||||
PJSIP_PUBLISH_METHOD = PJSIP_OTHER_METHOD,
|
||||
};
|
||||
|
||||
const pjsip_method pjsip_publish_method =
|
||||
{
|
||||
PJSIP_OTHER_METHOD,
|
||||
PJSIP_PUBLISH_METHOD,
|
||||
{ "PUBLISH", 7 }
|
||||
};
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
|
|||
{
|
||||
pjsip_inv_callback inv_cb;
|
||||
unsigned i;
|
||||
const pj_str_t str_norefersub = { "norefersub", 10 };
|
||||
pj_status_t status;
|
||||
|
||||
/* Init calls array. */
|
||||
|
@ -116,6 +117,10 @@ pj_status_t pjsua_call_subsys_init(const pjsua_config *cfg)
|
|||
status = pjsip_inv_usage_init(pjsua_var.endpt, &inv_cb);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
|
||||
|
||||
/* Add "norefersub" in Supported header */
|
||||
pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_SUPPORTED,
|
||||
NULL, 1, &str_norefersub);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -2124,10 +2129,12 @@ static void on_call_transfered( pjsip_inv_session *inv,
|
|||
pjsua_call *existing_call;
|
||||
int new_call;
|
||||
const pj_str_t str_refer_to = { "Refer-To", 8};
|
||||
const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
|
||||
pjsip_generic_string_hdr *refer_to;
|
||||
pjsip_generic_string_hdr *refer_sub;
|
||||
pj_bool_t no_refer_sub = PJ_FALSE;
|
||||
char *uri;
|
||||
pj_str_t tmp;
|
||||
struct pjsip_evsub_user xfer_cb;
|
||||
pjsip_status_code code;
|
||||
pjsip_evsub *sub;
|
||||
|
||||
|
@ -2146,6 +2153,16 @@ static void on_call_transfered( pjsip_inv_session *inv,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Find optional Refer-Sub header */
|
||||
refer_sub = (pjsip_generic_string_hdr*)
|
||||
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_refer_sub, NULL);
|
||||
|
||||
if (refer_sub) {
|
||||
if (!pj_strnicmp2(&refer_sub->hvalue, "true", 4)==0)
|
||||
no_refer_sub = PJ_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Notify callback */
|
||||
code = PJSIP_SC_OK;
|
||||
if (pjsua_var.ua_cfg.cb.on_call_transfered)
|
||||
|
@ -2166,34 +2183,92 @@ static void on_call_transfered( pjsip_inv_session *inv,
|
|||
(int)refer_to->hvalue.slen,
|
||||
refer_to->hvalue.ptr));
|
||||
|
||||
/* Init callback */
|
||||
pj_bzero(&xfer_cb, sizeof(xfer_cb));
|
||||
xfer_cb.on_evsub_state = &xfer_on_evsub_state;
|
||||
if (no_refer_sub) {
|
||||
/*
|
||||
* Always answer with 200.
|
||||
*/
|
||||
pjsip_tx_data *tdata;
|
||||
const pj_str_t str_false = { "false", 5};
|
||||
pjsip_hdr *hdr;
|
||||
|
||||
/* Create transferee event subscription */
|
||||
status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
|
||||
pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
status = pjsip_dlg_create_response(inv->dlg, rdata, 200, NULL, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create 200 response to REFER",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Accept the REFER request, send 200 (OK). */
|
||||
pjsip_xfer_accept(sub, rdata, code, NULL);
|
||||
/* Add Refer-Sub header */
|
||||
hdr = (pjsip_hdr*)
|
||||
pjsip_generic_string_hdr_create(tdata->pool, &str_refer_sub,
|
||||
&str_false);
|
||||
pjsip_msg_add_hdr(tdata->msg, hdr);
|
||||
|
||||
/* Create initial NOTIFY request */
|
||||
status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
|
||||
100, NULL, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER", status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send initial NOTIFY request */
|
||||
status = pjsip_xfer_send_request( sub, tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
|
||||
return;
|
||||
/* Send answer */
|
||||
status = pjsip_dlg_send_response(inv->dlg, pjsip_rdata_get_tsx(rdata),
|
||||
tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create 200 response to REFER",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't have subscription */
|
||||
sub = NULL;
|
||||
|
||||
} else {
|
||||
struct pjsip_evsub_user xfer_cb;
|
||||
pjsip_hdr hdr_list;
|
||||
|
||||
/* Init callback */
|
||||
pj_bzero(&xfer_cb, sizeof(xfer_cb));
|
||||
xfer_cb.on_evsub_state = &xfer_on_evsub_state;
|
||||
|
||||
/* Init additional header list to be sent with REFER response */
|
||||
pj_list_init(&hdr_list);
|
||||
|
||||
/* Create transferee event subscription */
|
||||
status = pjsip_xfer_create_uas( inv->dlg, &xfer_cb, rdata, &sub);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create xfer uas", status);
|
||||
pjsip_dlg_respond( inv->dlg, rdata, 500, NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there's Refer-Sub header and the value is "true", send back
|
||||
* Refer-Sub in the response with value "true" too.
|
||||
*/
|
||||
if (refer_sub) {
|
||||
const pj_str_t str_true = { "true", 4 };
|
||||
pjsip_hdr *hdr;
|
||||
|
||||
hdr = (pjsip_hdr*)
|
||||
pjsip_generic_string_hdr_create(inv->dlg->pool,
|
||||
&str_refer_sub,
|
||||
&str_true);
|
||||
pj_list_push_back(&hdr_list, hdr);
|
||||
|
||||
}
|
||||
|
||||
/* Accept the REFER request, send 200 (OK). */
|
||||
pjsip_xfer_accept(sub, rdata, code, &hdr_list);
|
||||
|
||||
/* Create initial NOTIFY request */
|
||||
status = pjsip_xfer_notify( sub, PJSIP_EVSUB_STATE_ACTIVE,
|
||||
100, NULL, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send initial NOTIFY request */
|
||||
status = pjsip_xfer_send_request( sub, tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER", status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* We're cheating here.
|
||||
|
@ -2211,32 +2286,36 @@ static void on_call_transfered( pjsip_inv_session *inv,
|
|||
&new_call);
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
||||
/* Notify xferer about the error */
|
||||
status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
|
||||
500, NULL, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
status = pjsip_xfer_send_request(sub, tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER",
|
||||
status);
|
||||
return;
|
||||
/* Notify xferer about the error (if we have subscription) */
|
||||
if (sub) {
|
||||
status = pjsip_xfer_notify(sub, PJSIP_EVSUB_STATE_TERMINATED,
|
||||
500, NULL, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to create NOTIFY to REFER",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
status = pjsip_xfer_send_request(sub, tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_perror(THIS_FILE, "Unable to send NOTIFY to REFER",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Put the server subscription in inv_data.
|
||||
* Subsequent state changed in pjsua_inv_on_state_changed() will be
|
||||
* reported back to the server subscription.
|
||||
*/
|
||||
pjsua_var.calls[new_call].xfer_sub = sub;
|
||||
if (sub) {
|
||||
/* Put the server subscription in inv_data.
|
||||
* Subsequent state changed in pjsua_inv_on_state_changed() will be
|
||||
* reported back to the server subscription.
|
||||
*/
|
||||
pjsua_var.calls[new_call].xfer_sub = sub;
|
||||
|
||||
/* Put the invite_data in the subscription. */
|
||||
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id,
|
||||
&pjsua_var.calls[new_call]);
|
||||
/* Put the invite_data in the subscription. */
|
||||
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id,
|
||||
&pjsua_var.calls[new_call]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -334,12 +334,6 @@ PJ_DEF(pj_status_t) pjsua_reconfigure_logging(const pjsua_logging_config *cfg)
|
|||
}
|
||||
}
|
||||
|
||||
/* Unregister OPTIONS handler if it's previously registered */
|
||||
if (pjsua_options_handler.id >= 0) {
|
||||
pjsip_endpt_unregister_module(pjsua_var.endpt, &pjsua_options_handler);
|
||||
pjsua_options_handler.id = -1;
|
||||
}
|
||||
|
||||
/* Unregister msg logging if it's previously registered */
|
||||
if (pjsua_msg_logger.id >= 0) {
|
||||
pjsip_endpt_unregister_module(pjsua_var.endpt, &pjsua_msg_logger);
|
||||
|
@ -350,9 +344,6 @@ PJ_DEF(pj_status_t) pjsua_reconfigure_logging(const pjsua_logging_config *cfg)
|
|||
if (pjsua_var.log_cfg.msg_logging)
|
||||
pjsip_endpt_register_module(pjsua_var.endpt, &pjsua_msg_logger);
|
||||
|
||||
/* Register OPTIONS handler */
|
||||
pjsip_endpt_register_module(pjsua_var.endpt, &pjsua_options_handler);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -443,6 +434,7 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg,
|
|||
{
|
||||
pjsua_config default_cfg;
|
||||
pjsua_media_config default_media_cfg;
|
||||
const pj_str_t STR_OPTIONS = { "OPTIONS", 7 };
|
||||
pj_status_t status;
|
||||
|
||||
|
||||
|
@ -541,6 +533,13 @@ PJ_DEF(pj_status_t) pjsua_init( const pjsua_config *ua_cfg,
|
|||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
/* Register OPTIONS handler */
|
||||
pjsip_endpt_register_module(pjsua_var.endpt, &pjsua_options_handler);
|
||||
|
||||
/* Add OPTIONS in Allow header */
|
||||
pjsip_endpt_add_capability(pjsua_var.endpt, NULL, PJSIP_H_ALLOW,
|
||||
NULL, 1, &STR_OPTIONS);
|
||||
|
||||
/* Start worker thread if needed. */
|
||||
if (pjsua_var.ua_cfg.thread_cnt) {
|
||||
unsigned i;
|
||||
|
|
|
@ -567,6 +567,9 @@ PJ_DEF(pj_status_t) pjsua_im_typing( pjsua_acc_id acc_id,
|
|||
pj_status_t pjsua_im_init(void)
|
||||
{
|
||||
const pj_str_t msg_tag = { "MESSAGE", 7 };
|
||||
const pj_str_t STR_MIME_TEXT_PLAIN = { "text/plain", 10 };
|
||||
const pj_str_t STR_MIME_APP_ISCOMPOSING =
|
||||
{ "application/im-iscomposing+xml", 30 };
|
||||
pj_status_t status;
|
||||
|
||||
/* Register module */
|
||||
|
@ -578,6 +581,14 @@ pj_status_t pjsua_im_init(void)
|
|||
pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ALLOW,
|
||||
NULL, 1, &msg_tag);
|
||||
|
||||
/* Register support for "application/im-iscomposing+xml" content */
|
||||
pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT,
|
||||
NULL, 1, &STR_MIME_APP_ISCOMPOSING);
|
||||
|
||||
/* Register support for "text/plain" content */
|
||||
pjsip_endpt_add_capability( pjsua_var.endpt, &mod_pjsua_im, PJSIP_H_ACCEPT,
|
||||
NULL, 1, &STR_MIME_TEXT_PLAIN);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue