From dc216fbe98f8335de253cf671528b6e0dc2cb509 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 20 Aug 2006 09:12:19 +0000 Subject: 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: http://svn.pjsip.org/repos/pjproject/trunk@688 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/src/pjsip-simple/publishc.c | 10 ++- pjsip/src/pjsua-lib/pjsua_call.c | 171 ++++++++++++++++++++++++++++---------- pjsip/src/pjsua-lib/pjsua_core.c | 17 ++-- pjsip/src/pjsua-lib/pjsua_im.c | 11 +++ 4 files changed, 153 insertions(+), 56 deletions(-) (limited to 'pjsip/src') diff --git a/pjsip/src/pjsip-simple/publishc.c b/pjsip/src/pjsip-simple/publishc.c index 5a0df963..749959bb 100644 --- a/pjsip/src/pjsip-simple/publishc.c +++ b/pjsip/src/pjsip-simple/publishc.c @@ -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 } }; diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c index f2517536..f9989ee8 100644 --- a/pjsip/src/pjsua-lib/pjsua_call.c +++ b/pjsip/src/pjsua-lib/pjsua_call.c @@ -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]); + } } diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index c9bd2482..a0a87fbe 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -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; diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c index 434ec10e..462796a0 100644 --- a/pjsip/src/pjsua-lib/pjsua_im.c +++ b/pjsip/src/pjsua-lib/pjsua_im.c @@ -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; } -- cgit v1.2.3