1725a1726 > static int transmit_notify_with_mwi_ex(struct sip_pvt *p, int newmsgs, int oldmsgs, int newurgentmsgs, int oldurgentmsgs, char *vmexten); 5934,5936c5935,5948 < /* We do not support out-of-dialog NOTIFY either, < like voicemail notification, so cancel that early */ < transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); --- > /* We can support out-of-dialog NOTIFY for voicemail notifications, so do not cancel that early */ > //transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); > > //============================================================== > ast_debug(1, "***** Received a unsolicited NOTIFY request. Creating a dialog\n"); > //============================================================== > /* Ok, time to create a new SIP dialog object, a pvt */ > if ((p = sip_alloc(callid, sin, 1, intended_method))) { > /* Ok, we've created a dialog, let's go and process it */ > sip_pvt_lock(p); > } else { > /* Should the reponse be 500 Internal Server Error? */ > transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event"); > } 8983c8995 < static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) --- > static int transmit_notify_with_mwi_ex(struct sip_pvt *p, int newmsgs, int oldmsgs, int newurgentmsgs, int oldurgentmsgs, char *vmexten) 8997a9010,9017 > char urgentmsgs[50]; > urgentmsgs[0] = '\0'; > if(ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI)) { > strcpy(urgentmsgs, ""); > } else { > sprintf(urgentmsgs, " (%d/%d)",newurgentmsgs,oldurgentmsgs); > } > 8999c9019 < newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)")); --- > newmsgs, oldmsgs, urgentmsgs); 9015a9036,9046 > /*! \brief Notify user of messages waiting in voicemail > \note - Notification only works for registered peers with mailbox= definitions > in sip.conf > - We use the SIP Event package message-summary > MIME type defaults to "application/simple-message-summary"; > */ > static int transmit_notify_with_mwi(struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten) > { > return transmit_notify_with_mwi_ex(p, newmsgs, oldmsgs, 0, 0, vmexten); > } > 15812,15815c15843,16028 < /* We don't understand this event. */ < /* Here's room to implement incoming voicemail notifications :-) */ < transmit_response(p, "489 Bad event", req); < res = -1; --- > int response_code = 489; // Bad event > int messages_waiting = 0; > int new_voicemail_messages = 0; > int old_voicemail_messages = 0; > int new_urgent_voicemail_messages = 0; > int old_urgent_voicemail_messages = 0; > > // We can support "message-summary" event package > if (!strcasecmp(event, "message-summary")) { > const char *Content_Type; > Content_Type = get_header(req, "Content-Type"); > if (!strcasecmp(Content_Type, "application/simple-message-summary")) { > if (sipdebug) > ast_debug(2, "Content_Type : %s. Lines in Body=%d\n", Content_Type, req->lines); > > response_code = 400; // Bad request > int line_index = 0; > for (line_index = 0; line_index < req->lines; line_index++) { > char body_line[255]; > ast_copy_string(body_line,req->line[line_index],255); > > //Example: Messages-Waiting: yes [no] > char* msg_waiting; > if( (msg_waiting = strstr(body_line,"Messages-Waiting")) ) { > if( (msg_waiting = strstr(body_line,"yes")) ) { > messages_waiting = 1; > new_voicemail_messages = 1; > response_code = 200; > } else if( (msg_waiting = strstr(body_line,"no")) ) { > messages_waiting = 0; > response_code = 200; > } > } > if (sipdebug) > ast_debug(2, "messages_waiting=%d, new_voicemail_messages=%d, response_code=%d\n", > messages_waiting, new_voicemail_messages, response_code); > > //Example: Voice-Message: 1/3 (0/1) > const char* voice_messages; > if( (voice_messages = strstr(body_line,"Voice-Message")) ) { > char* delimiter; > if( (delimiter = strchr(voice_messages, '/')) ) { > char new_voice_messages[10]=""; > strncpy(new_voice_messages,voice_messages,(delimiter-voice_messages)-1); > new_voicemail_messages = atoi(new_voice_messages); > messages_waiting = (new_voicemail_messages) ? 1 : 0; > response_code = 200; > > char* delimiter2; > if( (delimiter2 = strchr(delimiter, '(')) ) { > char old_voice_messages[10]=""; > strncpy(old_voice_messages,delimiter,(delimiter2-delimiter)-1); > old_voicemail_messages = atoi(old_voice_messages); > > char* delimiter3; > if( (delimiter3 = strchr(delimiter2, '/')) ) { > char new_urgent_voice_messages[10]=""; > strncpy(new_urgent_voice_messages,delimiter2,(delimiter3-delimiter2)-1); > new_urgent_voicemail_messages = atoi(new_urgent_voice_messages); > > char* delimiter4; > if( (delimiter4 = strchr(delimiter3, ')')) ) { > char old_urgent_voice_messages[10]=""; > strncpy(old_urgent_voice_messages,delimiter3,(delimiter4-delimiter3)-1); > old_urgent_voicemail_messages = atoi(old_urgent_voice_messages); > } > } > } > } > } > } > } > > if (sipdebug) > ast_debug(2, "Processing : %s, Content-Type: %s, messages_waiting=%d, new_voicemail_messages=%d, old_voicemail_messages=%d\n", > event,Content_Type,messages_waiting,new_voicemail_messages,old_voicemail_messages); > > if (sipdebug) > ast_debug(2, "Processing : %s, response_code=%d\n", event,response_code); > } > > if(response_code == 200) { > struct sip_peer *peer; > struct sip_pvt *pvt; > > char* header_value; > char to[256]; > char peername[50]; > ast_copy_string(to, get_header(req, "To"), sizeof(to)); > > if(!ast_strlen_zero(to)) { > header_value = to+3; > memset(peername, 0, sizeof(peername)); > get_calleridname(to, peername, sizeof(peername)); > > if(!strlen(peername)) { > char* peer_start; > if( (peer_start = strstr(to,"sips:")) ) { > peer_start += 5; > } else if( (peer_start = strstr(to,"sip:")) ) { > peer_start += 4; > } > > if(peer_start) { > char* peer_end; > if( (peer_end = strstr(peer_start,"@")) ) { > strncpy(peername,peer_start,(peer_end-peer_start)); > } > } > } > } > > if (sipdebug) > ast_debug(2, "Finding peer for : %s\n", peername); > > peer = find_peer(peername, NULL, 1); > if (peer->mwipvt) { > // Base message on subscription > pvt = dialog_ref(peer->mwipvt); > > if (sipdebug) > ast_debug(2, "Subscription found for : %s\n", peername); > } else { > if (sipdebug) > ast_debug(2, "Subscription not found for : %s. Will send unsolicited NOTIFY\n", peername); > > res = -1; > response_code = 500; > // Build temporary dialog for this message > if ((pvt = sip_alloc(NULL, NULL, 0, SIP_NOTIFY))) { > if (!create_addr_from_peer(pvt, peer)) { > // Recalculate our side, and recalculate Call ID > ast_sip_ouraddrfor(&pvt->sa.sin_addr, &pvt->ourip); > build_via(pvt); > build_callid_pvt(pvt); > // Destroy this session after 32 secs > sip_scheddestroy(pvt, DEFAULT_TRANS_TIMEOUT); > > res = 0; > response_code = 200; > } > else { > // Maybe they're not registered, etc. > sip_destroy(pvt); > } > } > } > > if(response_code == 200) { > // Send MWI > ast_set_flag(&pvt->flags[0], SIP_OUTGOING); > transmit_notify_with_mwi_ex(pvt, new_voicemail_messages, old_voicemail_messages, new_urgent_voicemail_messages, old_urgent_voicemail_messages, peer->vmexten); > } else { > if (sipdebug) > ast_debug(2, "NOTIFY not sent, response_code=%d\n", response_code); > } > } > > char response_str[255]; > switch(response_code) { > case 400: > ast_copy_string(response_str,"400 Bad Request Asterisk",255); > break; > case 404: > ast_copy_string(response_str,"404 Not Found",255); > break; > case 500: > ast_copy_string(response_str,"500 Internal Server Error",255); > break; > case 200: > ast_copy_string(response_str,"200 OK",255); > break; > case 489: > default: > ast_copy_string(response_str,"489 Bad Event",255); > break; > } > > if (sipdebug) > ast_debug(2, "Responding to incoming NOTIFY with %d\n",response_code); > > transmit_response(p, (const char*)response_str, req); > if(res == 0) { > res = (response_code != 200) ? -1 : 0; > } > //===================================================================