diff -Naru asterisk-14.5.0_orig/channels/chan_sip.c asterisk-14.5.0/channels/chan_sip.c
--- asterisk-14.5.0_orig/channels/chan_sip.c 2017-05-31 02:50:46.000000000 +0900
+++ asterisk-14.5.0/channels/chan_sip.c 2017-06-16 17:20:51.662231445 +0900
@@ -15546,8 +15546,9 @@
{
const char *channame = astman_get_header(m, "Channel");
struct ast_variable *vars = astman_get_variables_order(m, ORDER_NATURAL);
- struct sip_pvt *p;
+ struct sip_pvt *p = NULL;
struct ast_variable *header, *var;
+ char indialog = 0;
if (ast_strlen_zero(channame)) {
astman_send_error(s, m, "SIPNotify requires a channel name");
@@ -15558,25 +15559,61 @@
channame += 4;
}
- if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
- astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
- return 0;
- }
+ // check if Call-ID variable is set
+ for (var = vars; var; var = var->next) {
+ if (!strcasecmp(var->name, "Call-ID")) {
+ struct sip_pvt tmp_dialog = {
+ .callid = var->value,
+ };
+
+ p = ao2_find(dialogs, &tmp_dialog, OBJ_POINTER);
+ if (!p) {
+ astman_send_error(s, m, "Call-ID not found");
+ return 0;
+ }
+ indialog = 1;
+ }
+ }
+
+ if (!indialog) {
+ if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, 0))) {
+ astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
+ return 0;
+ }
- if (create_addr(p, channame, NULL, 0)) {
- /* Maybe they're not registered, etc. */
- dialog_unlink_all(p);
- dialog_unref(p, "unref dialog inside for loop" );
- /* sip_destroy(p); */
- astman_send_error(s, m, "Could not create address");
- return 0;
- }
+ if (create_addr(p, channame, NULL, 0)) {
+ /* Maybe they're not registered, etc. */
+ dialog_unlink_all(p);
+ dialog_unref(p, "unref dialog inside for loop" );
+ /* sip_destroy(p); */
+ astman_send_error(s, m, "Could not create address");
+ return 0;
+ }
- /* Notify is outgoing call */
- ast_set_flag(&p->flags[0], SIP_OUTGOING);
- sip_notify_alloc(p);
+ /* Notify is outgoing call */
+ ast_set_flag(&p->flags[0], SIP_OUTGOING);
+ sip_notify_alloc(p);
+
+ p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
+ } else {
+ if (!(p->notify)) {
+ sip_notify_alloc(p);
+ } else {
+ ast_variables_destroy(p->notify->headers);
+ }
+
+ p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
+ }
- p->notify->headers = header = ast_variable_new("Subscription-State", "terminated", "");
+ /* if (pref) {
+ ast_string_field_set(p, callid, pref->callid);
+ ast_string_field_set(p, fromuser, pref->fromuser);
+ ast_string_field_set(p, fromname, pref->fromname);
+ ast_string_field_set(p, tag, pref->tag);
+ ast_string_field_set(p, theirtag, pref->theirtag);
+ p->ocseq = pref->ocseq;
+ (pref->ocseq)++;
+ } */
for (var = vars; var; var = var->next) {
if (!strcasecmp(var->name, "Content")) {
@@ -15585,21 +15622,27 @@
ast_str_append(&p->notify->content, 0, "%s", var->value);
} else if (!strcasecmp(var->name, "Content-Length")) {
ast_log(LOG_WARNING, "it is not necessary to specify Content-Length, ignoring\n");
+ } else if (!strcasecmp(var->name, "Call-ID")) {
+ // do nothing here
} else {
header->next = ast_variable_new(var->name, var->value, "");
header = header->next;
}
}
+ if (!indialog) {
/* Now that we have the peer's address, set our ip and change callid */
ast_sip_ouraddrfor(&p->sa, &p->ourip, p);
build_via(p);
- change_callid_pvt(p, NULL);
+ change_callid_pvt(p, NULL);
sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
transmit_invite(p, SIP_NOTIFY, 0, 2, NULL);
dialog_unref(p, "bump down the count of p since we're done with it.");
+ } else {
+ transmit_invite(p, SIP_NOTIFY, 0, 1, NULL);
+ }
astman_send_ack(s, m, "Notify Sent");
ast_variables_destroy(vars);