Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 172702) +++ channels/chan_sip.c (working copy) @@ -327,6 +327,22 @@ Always returns 0. + + + Send SIP Notify Event to a local Peer. + + + + template defined in sip_notify.conf. + + + local sip registered peer name + + + + Send SIP Notify Event as defined in sip_notify.conf to a single peer. + + Gets the specified SIP header. @@ -2409,6 +2425,7 @@ static char *sip_set_history(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static int sip_dtmfmode(struct ast_channel *chan, void *data); static int sip_addheader(struct ast_channel *chan, void *data); +static int sip_app_notify(struct ast_channel *chan, void *data); static int sip_do_reload(enum channelreloadreason reason); static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a); static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen); @@ -23962,6 +23979,7 @@ static char *app_dtmfmode = "SIPDtmfMode"; static char *app_sipaddheader = "SIPAddHeader"; static char *app_sipremoveheader = "SIPRemoveHeader"; +static char *app_sipnotify = "SIPNotify"; /*! \brief Set the DTMFmode for an outbound SIP call (application) */ static int sip_dtmfmode(struct ast_channel *chan, void *data) @@ -24092,6 +24110,76 @@ return 0; } +/*! \brief Dialplan application to send SIP notify to a single peer */ +static int sip_app_notify(struct ast_channel *chan, void *data) +{ + struct ast_variable *varlist; + char *parse; + struct sip_pvt *p; + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(template); + AST_APP_ARG(name); + ); + + if (ast_strlen_zero(data)) { + ast_log(LOG_ERROR, "SIPNotify requires 2 arguments (template(from sip_notify.conf), name)\n"); + return AST_FAILURE; + } + + if (!notify_types) { + ast_log(LOG_ERROR, "No %s file found, or no types listed there\n", notify_config); + return AST_FAILURE; + } + + parse = ast_strdupa(data); + AST_STANDARD_APP_ARGS(args, parse); + + varlist = ast_variable_browse(notify_types, args.template); + if (!varlist) { + ast_log(LOG_ERROR, "Unable to find notify type '%s'\n", args.template); + return AST_FAILURE; + } + + if (ast_strlen_zero(args.name)) { + ast_log(LOG_ERROR, "SIPNotify missing 2nd argument, name\n"); + return AST_FAILURE; + } + + if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { + ast_log(LOG_ERROR, "Unable to build sip pvt data for notify (memory/socket error)\n"); + return AST_FAILURE; + } + + if (create_addr(p, args.name, NULL, 0)) { + /* Maybe they're not registered, etc. */ + dialog_unlink_all(p, TRUE, TRUE); + dialog_unref(p, "unref dialog inside for loop" ); + /* sip_destroy(p); */ + ast_log(LOG_ERROR, "Could not create address for '%s'\n", args.name); + return AST_FAILURE; + } + + /* Notify is outgoing call */ + ast_set_flag(&p->flags[0], SIP_OUTGOING); + + /* Recalculate our side, and recalculate Call ID */ + + ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip); + build_via(p); + ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name"); + build_callid_pvt(p); + ao2_t_link(dialogs, p, "Linking in new name"); + ast_verb(3, "Sending NOTIFY of type '%s' to '%s'\n", args.template, args.name); + + dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement."); + + sip_scheddestroy(p, SIP_TRANS_TIMEOUT); + + transmit_notify_custom(p, varlist); + + return 0; +} + /*! \brief Transfer call before connect with a 302 redirect \note Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state @@ -24376,6 +24464,7 @@ ast_register_application_xml(app_dtmfmode, sip_dtmfmode); ast_register_application_xml(app_sipaddheader, sip_addheader); ast_register_application_xml(app_sipremoveheader, sip_removeheader); + ast_register_application_xml(app_sipnotify, sip_app_notify); /* Register dialplan functions */ ast_custom_function_register(&sip_header_function); @@ -24438,6 +24527,7 @@ ast_unregister_application(app_dtmfmode); ast_unregister_application(app_sipaddheader); ast_unregister_application(app_sipremoveheader); + ast_unregister_application(app_sipnotify); /* Unregister CLI commands */ ast_cli_unregister_multiple(cli_sip, ARRAY_LEN(cli_sip));