From fe1bd34b905840240bbdf147005ac29157132bc5 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Fri, 20 Nov 2009 23:33:07 +0000 Subject: [PATCH] More ticket #982 (MWI): support for Asterisk unsolicited MWI requests: - undo r3019 which put unsolicited MWI support in pjsua app only - put the unsolicited MWI support in PJSUA-LIB instead - unsolicited MWI is by default enabled - on_mwi_info() callback will be called just as the solicited MWI version git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@3021 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip-apps/src/pjsua/pjsua_app.c | 103 +------------------------------ pjsip/include/pjsua-lib/pjsua.h | 20 +++++- pjsip/src/pjsua-lib/pjsua_core.c | 1 + pjsip/src/pjsua-lib/pjsua_pres.c | 87 ++++++++++++++++++++++++++ 4 files changed, 107 insertions(+), 104 deletions(-) diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index 4e73770d0..aa1563fc5 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -101,7 +101,6 @@ static struct app_config pjsua_conf_port_id rec_port; unsigned auto_answer; unsigned duration; - pj_bool_t unsolicited_mwi; #ifdef STEREO_DEMO pjmedia_snd_port *snd; @@ -145,7 +144,6 @@ static pj_status_t transport_adapter_sample(void); #endif static pj_status_t create_ipv6_media_transports(void); pj_status_t app_destroy(void); -static void enable_unsolicited_mwi(void); static void ringback_start(pjsua_call_id call_id); static void ring_start(pjsua_call_id call_id); @@ -196,7 +194,6 @@ static void usage(void) puts (" --password=string Set authentication password"); puts (" --publish Send presence PUBLISH for this account"); puts (" --mwi Subscribe to message summary/waiting indication"); - puts (" --unsolicited-mwi Handle unsolicited MWI requests"); puts (" --use-100rel Require reliable provisional response (100rel)"); puts (" --use-timer Require SIP session timers"); puts (" --timer-se=N Session timers expiration period, in secs (def:1800)"); @@ -487,7 +484,7 @@ static pj_status_t parse_args(int argc, char *argv[], OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT, OPT_BOUND_ADDR, OPT_CONTACT_PARAMS, OPT_CONTACT_URI_PARAMS, OPT_100REL, OPT_USE_IMS, OPT_REALM, OPT_USERNAME, OPT_PASSWORD, - OPT_MWI, OPT_UNSOLICITED_MWI, OPT_NAMESERVER, OPT_STUN_SRV, + OPT_MWI, OPT_NAMESERVER, OPT_STUN_SRV, OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, OPT_AUTO_ANSWER, OPT_AUTO_PLAY, OPT_AUTO_PLAY_HANGUP, OPT_AUTO_LOOP, OPT_AUTO_CONF, OPT_CLOCK_RATE, OPT_SND_CLOCK_RATE, OPT_STEREO, @@ -540,7 +537,6 @@ static pj_status_t parse_args(int argc, char *argv[], { "reg-timeout",1, 0, OPT_REG_TIMEOUT}, { "publish", 0, 0, OPT_PUBLISH}, { "mwi", 0, 0, OPT_MWI}, - { "unsolicited-mwi", 0, 0, OPT_UNSOLICITED_MWI}, { "use-100rel", 0, 0, OPT_100REL}, { "use-ims", 0, 0, OPT_USE_IMS}, { "id", 1, 0, OPT_ID}, @@ -843,10 +839,6 @@ static pj_status_t parse_args(int argc, char *argv[], cur_acc->mwi_enabled = PJ_TRUE; break; - case OPT_UNSOLICITED_MWI: - cfg->unsolicited_mwi = PJ_TRUE; - break; - case OPT_100REL: /** 100rel */ cur_acc->require_100rel = PJ_TRUE; cfg->cfg.require_100rel = PJ_TRUE; @@ -2000,10 +1992,6 @@ static int write_settings(const struct app_config *config, pj_strcat2(&cfg, "--use-compact-form\n"); } - if (config->unsolicited_mwi) { - pj_strcat2(&cfg, "--unsolicited-mwi\n"); - } - if (!config->cfg.force_lr) { pj_strcat2(&cfg, "--no-force-lr\n"); } @@ -4407,10 +4395,6 @@ pj_status_t app_init(int argc, char *argv[]) if (status != PJ_SUCCESS) return status; - /* Initialize unsolicited MWI */ - if (app_config.unsolicited_mwi) - enable_unsolicited_mwi(); - /* Initialize our module to handle otherwise unhandled request */ status = pjsip_endpt_register_module(pjsua_get_pjsip_endpt(), &mod_default_handler); @@ -5015,88 +4999,3 @@ static pj_status_t create_ipv6_media_transports(void) return pjsua_media_transports_attach(tp, i, PJ_TRUE); } -/***************************************************************************** - * Asterisk unsolicited MWI module - */ -static pj_bool_t mwi_on_rx_request(pjsip_rx_data *rdata) -{ - pjsip_msg *msg = rdata->msg_info.msg; - pj_str_t EVENT_HDR = { "Event", 5 }; - pj_str_t MWI = { "message-summary", 15 }; - pjsip_event_hdr *eh; - pj_str_t body; - - if (pjsip_method_cmp(&msg->line.req.method, &pjsip_notify_method)!=0) { - /* Only interested with NOTIFY request */ - return PJ_FALSE; - } - - eh = (pjsip_event_hdr*) pjsip_msg_find_hdr_by_name(msg, &EVENT_HDR, NULL); - if (!eh) { - /* Something wrong with the request, it has no Event hdr */ - return PJ_FALSE; - } - - if (pj_stricmp(&eh->event_type, &MWI) != 0) { - /* Not MWI event */ - return PJ_FALSE; - } - - /* Got unsolicited MWI request, respond with 200/OK first */ - pjsip_endpt_respond(pjsua_get_pjsip_endpt(), NULL, rdata, 200, NULL, - NULL, NULL, NULL); - - - PJ_LOG(3,(THIS_FILE, "Received MWI info:")); - - if (rdata->msg_info.ctype) { - const pjsip_ctype_hdr *ctype = rdata->msg_info.ctype; - - PJ_LOG(3,(THIS_FILE, " Content-Type: %.*s/%.*s", - (int)ctype->media.type.slen, - ctype->media.type.ptr, - (int)ctype->media.subtype.slen, - ctype->media.subtype.ptr)); - } - - if (!rdata->msg_info.msg->body) { - PJ_LOG(3,(THIS_FILE, " no message body")); - return PJ_TRUE; - } - - body.ptr = rdata->msg_info.msg->body->data; - body.slen = rdata->msg_info.msg->body->len; - - PJ_LOG(3,(THIS_FILE, " Body:\n%.*s", (int)body.slen, body.ptr)); - - return PJ_TRUE; -} - -/* The module instance. */ -static pjsip_module pjsua_mwi_mod = -{ - NULL, NULL, /* prev, next. */ - { "mod-unsolicited-mwi", 19 }, /* Name. */ - -1, /* Id */ - PJSIP_MOD_PRIORITY_UA_PROXY_LAYER-1,/* Priority */ - NULL, /* load() */ - NULL, /* start() */ - NULL, /* stop() */ - NULL, /* unload() */ - &mwi_on_rx_request, /* on_rx_request() */ - NULL, /* on_rx_response() */ - NULL, /* on_tx_request. */ - NULL, /* on_tx_response() */ - NULL, /* on_tsx_state() */ -}; - -static void enable_unsolicited_mwi(void) -{ - pj_status_t status; - - status = pjsip_endpt_register_module(pjsua_get_pjsip_endpt(), - &pjsua_mwi_mod); - if (status != PJ_SUCCESS) - pjsua_perror(THIS_FILE, "Error registering MWI module", status); -} - diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index a8bb2f394..44ce9f0fa 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1001,6 +1001,21 @@ typedef struct pjsua_config */ pj_bool_t require_timer; + /** + * Handle unsolicited NOTIFY requests containing message waiting + * indication (MWI) info. Unsolicited MWI is incoming NOTIFY requests + * which are not requested by client with SUBSCRIBE request. + * + * If this is enabled, the library will respond 200/OK to the NOTIFY + * request and forward the request to \a on_mwi_info() callback. + * + * See also \a mwi_enabled field #on pjsua_acc_config. + * + * Default: PJ_TRUE + * + */ + pj_bool_t enable_unsolicited_mwi; + /** * Specify Session Timer settings, see #pjsip_timer_setting. * Note that this setting can be further customized in account @@ -1882,8 +1897,9 @@ typedef struct pjsua_acc_config pj_str_t reg_uri; /** - * Enable message summary and message waiting indication subscription - * (RFC 3842) for this account. + * Subscribe to message waiting indication events (RFC 3842). + * + * See also \a enable_unsolicited_mwi field on #pjsua_config. * * Default: no */ diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 6e41cbe0b..52d436e33 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -101,6 +101,7 @@ PJ_DEF(void) pjsua_config_default(pjsua_config *cfg) cfg->nat_type_in_sdp = 1; cfg->stun_ignore_failure = PJ_TRUE; cfg->force_lr = PJ_TRUE; + cfg->enable_unsolicited_mwi = PJ_TRUE; #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) cfg->use_srtp = PJSUA_DEFAULT_USE_SRTP; cfg->srtp_secure_signaling = PJSUA_DEFAULT_SRTP_SECURE_SIGNALING; diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index fbf133526..effa40105 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -2075,6 +2075,87 @@ void pjsua_start_mwi(pjsua_acc *acc) } +/*************************************************************************** + * Unsolicited MWI + */ +static pj_bool_t unsolicited_mwi_on_rx_request(pjsip_rx_data *rdata) +{ + pjsip_msg *msg = rdata->msg_info.msg; + pj_str_t EVENT_HDR = { "Event", 5 }; + pj_str_t MWI = { "message-summary", 15 }; + pjsip_event_hdr *eh; + + if (pjsip_method_cmp(&msg->line.req.method, &pjsip_notify_method)!=0) { + /* Only interested with NOTIFY request */ + return PJ_FALSE; + } + + eh = (pjsip_event_hdr*) pjsip_msg_find_hdr_by_name(msg, &EVENT_HDR, NULL); + if (!eh) { + /* Something wrong with the request, it has no Event hdr */ + return PJ_FALSE; + } + + if (pj_stricmp(&eh->event_type, &MWI) != 0) { + /* Not MWI event */ + return PJ_FALSE; + } + + /* Got unsolicited MWI request, respond with 200/OK first */ + pjsip_endpt_respond(pjsua_get_pjsip_endpt(), NULL, rdata, 200, NULL, + NULL, NULL, NULL); + + + /* Call callback */ + if (pjsua_var.ua_cfg.cb.on_mwi_info) { + pjsua_acc_id acc_id; + pjsua_mwi_info mwi_info; + + acc_id = pjsua_acc_find_for_incoming(rdata); + + pj_bzero(&mwi_info, sizeof(mwi_info)); + mwi_info.rdata = rdata; + + (*pjsua_var.ua_cfg.cb.on_mwi_info)(acc_id, &mwi_info); + } + + + return PJ_TRUE; +} + +/* The module instance. */ +static pjsip_module pjsua_unsolicited_mwi_mod = +{ + NULL, NULL, /* prev, next. */ + { "mod-unsolicited-mwi", 19 }, /* Name. */ + -1, /* Id */ + PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */ + NULL, /* load() */ + NULL, /* start() */ + NULL, /* stop() */ + NULL, /* unload() */ + &unsolicited_mwi_on_rx_request, /* on_rx_request() */ + NULL, /* on_rx_response() */ + NULL, /* on_tx_request. */ + NULL, /* on_tx_response() */ + NULL, /* on_tsx_state() */ +}; + +static pj_status_t enable_unsolicited_mwi(void) +{ + pj_status_t status; + + status = pjsip_endpt_register_module(pjsua_get_pjsip_endpt(), + &pjsua_unsolicited_mwi_mod); + if (status != PJ_SUCCESS) + pjsua_perror(THIS_FILE, "Error registering unsolicited MWI module", + status); + + return status; +} + + + /***************************************************************************/ /* Timer callback to re-create client subscription */ @@ -2150,6 +2231,12 @@ pj_status_t pjsua_pres_start(void) pjsua_var.pres_timer.id = PJ_TRUE; } + if (pjsua_var.ua_cfg.enable_unsolicited_mwi) { + pj_status_t status = enable_unsolicited_mwi(); + if (status != PJ_SUCCESS) + return status; + } + return PJ_SUCCESS; }