From d438d7b74f18152912fb41713e3f1479e77ee443 Mon Sep 17 00:00:00 2001 From: tilghman Date: Fri, 6 Jun 2008 20:24:11 +0000 Subject: [PATCH] Added a facility for sending arbitrary SIP notify commands from AMI. (closes issue #12562) Reported by: michael-fig Patches: 20080515__bug12562.diff.txt uploaded by Corydon76 (license 14) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@121042 614ede4d-c843-0410-af14-a771ab80d22e --- CHANGES | 1 + channels/chan_sip.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/CHANGES b/CHANGES index 22d020bd4..5570ba938 100644 --- a/CHANGES +++ b/CHANGES @@ -100,6 +100,7 @@ SIP Changes * Added support for T140 RED - redundancy in T.140 to prevent text loss due to lost packets. * Added t38pt_usertpsource option. See sip.conf.sample for details. + * Added SIPnotify AMI command, for sending arbitrary SIP notify commands. IAX Changes ----------- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 6cf4a18f4..15c2ddbf1 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -9509,6 +9509,65 @@ static int transmit_notify_custom(struct sip_pvt *p, struct ast_variable *vars) return send_request(p, &req, XMIT_UNRELIABLE, p->ocseq); } +static int manager_sipnotify(struct mansession *s, const struct message *m) +{ + const char *channame = astman_get_header(m, "Channel"); + struct ast_variable *vars = astman_get_variables(m); + struct sip_pvt *p; + + if (!channame) { + astman_send_error(s, m, "SIPNotify requires a channel name"); + return -1; + } + + if (strncasecmp(channame, "sip/", 4) == 0) { + channame += 4; + } + + if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { + astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)"); + return -1; + } + + if (create_addr(p, channame, NULL)) { + /* Maybe they're not registered, etc. */ + dialog_unlink_all(p, TRUE, TRUE); + dialog_unref(p, "unref dialog inside for loop" ); + /* sip_destroy(p); */ + astman_send_error(s, m, "Could not create address"); + return -1; + } + + /* 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"); + dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement."); + sip_scheddestroy(p, SIP_TRANS_TIMEOUT); + + if (!transmit_notify_custom(p, vars)) { + astman_send_ack(s, m, "Notify Sent"); + } else { + astman_send_error(s, m, "Unable to send notify"); + } + ast_variables_destroy(vars); + return 0; +} + +static char mandescr_sipnotify[] = +"Description: Sends a SIP Notify event\n" +"All parameters for this event must be specified in the body of this request\n" +"via multiple Variable: name=value sequences.\n" +"Variables: \n" +" *Channel: Peer to receive the notify. Required.\n" +" *Variable: = At least one variable pair must be specified.\n" +" ActionID: Action ID for this transaction. Will be returned.\n"; + static const struct _map_x_s regstatestrings[] = { { REG_STATE_FAILED, "Failed" }, { REG_STATE_UNREGISTERED, "Unregistered"}, @@ -22788,6 +22847,8 @@ static int load_module(void) "Show SIP peer (text format)", mandescr_show_peer); ast_manager_register2("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry, "Show SIP registrations (text format)", mandescr_show_registry); + ast_manager_register2("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify, + "Send a SIP notify", mandescr_sipnotify); sip_poke_all_peers(); sip_send_all_registers(); @@ -22844,6 +22905,7 @@ static int unload_module(void) ast_manager_unregister("SIPshowpeer"); ast_manager_unregister("SIPqualifypeer"); ast_manager_unregister("SIPshowregistry"); + ast_manager_unregister("SIPnotify"); /* Kill TCP/TLS server threads */ if (sip_tcp_desc.master) -- 2.11.4.GIT