From f26d22b563996c6c110b49004a7c7842a99d1f3e Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Wed, 23 May 2012 13:06:08 +0000 Subject: [PATCH] Update a peer's LastMsgsSent when the peer is notified of waiting messages Previously, MWI logic utilized a counter called 'lastmsgssent' to know whether or not MWI NOTIFY requests had been sent to a specific peer. When MWI notifications were changed to use the internal event framework, this value was no longer needed for its original purpose. Hence, it was no longer updated with the new/old message counts for a peer. However, the value was still presented when, either by AMI or CLI, a 'sip show peer [peer]' command was executed. The output of the command would always display the erroneous value of 32767/65535 for 'LastMsgsSent'. This patch makes it so that the value of lastmsgssent is updated appropriately. The value should now display the new/old message counts for a particular peer. (closes issue ASTERISK-17866) Reported by: Steve Davies patches by: ast-17866-rb1272.patch (License #5041 by irroot) Modified slightly for this commit Review: https://reviewboard.asterisk.org/r/1939 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@367362 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 707f7b5fbb..4fd83fef5d 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -14736,6 +14736,20 @@ static void extract_host_from_hostport(char **hostport) ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE); } +/*! \internal \brief Helper function to update a peer's lastmsgssent value + */ +static void update_peer_lastmsgssent(struct sip_peer *peer, int value, int locked) +{ + if (!locked) { + ao2_lock(peer); + } + peer->lastmsgssent = value; + if (!locked) { + ao2_unlock(peer); + } +} + + /*! \brief Verify registration of user - Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth @@ -14749,6 +14763,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock char tmp[256]; char *c, *name, *unused_password, *domain; char *uri2 = ast_strdupa(uri); + int send_mwi = 0; terminate_uri(uri2); @@ -14852,19 +14867,16 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock case PARSE_REGISTER_DENIED: ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); transmit_response_with_date(p, "603 Denied", req); - peer->lastmsgssent = -1; res = 0; break; case PARSE_REGISTER_FAILED: ast_log(LOG_WARNING, "Failed to parse contact info\n"); transmit_response_with_date(p, "400 Bad Request", req); - peer->lastmsgssent = -1; res = 0; break; case PARSE_REGISTER_QUERY: ast_string_field_set(p, fullcontact, peer->fullcontact); transmit_response_with_date(p, "200 OK", req); - peer->lastmsgssent = -1; res = 0; break; case PARSE_REGISTER_UPDATE: @@ -14872,8 +14884,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock update_peer(peer, p->expiry); /* Say OK and ask subsystem to retransmit msg counter */ transmit_response_with_date(p, "200 OK", req); - if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY)) - peer->lastmsgssent = -1; + send_mwi = 1; res = 0; break; } @@ -14898,19 +14909,17 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock case PARSE_REGISTER_DENIED: ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); transmit_response_with_date(p, "403 Forbidden (ACL)", req); - peer->lastmsgssent = -1; res = 0; break; case PARSE_REGISTER_FAILED: ast_log(LOG_WARNING, "Failed to parse contact info\n"); transmit_response_with_date(p, "400 Bad Request", req); - peer->lastmsgssent = -1; res = 0; break; case PARSE_REGISTER_QUERY: ast_string_field_set(p, fullcontact, peer->fullcontact); transmit_response_with_date(p, "200 OK", req); - peer->lastmsgssent = -1; + send_mwi = 1; res = 0; break; case PARSE_REGISTER_UPDATE: @@ -14918,7 +14927,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock /* Say OK and ask subsystem to retransmit msg counter */ transmit_response_with_date(p, "200 OK", req); manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\n", peer->name, ast_sockaddr_stringify(addr)); - peer->lastmsgssent = -1; + send_mwi = 1; res = 0; break; } @@ -14926,6 +14935,11 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock } } if (!res) { + if (send_mwi) { + sip_send_mwi_to_peer(peer, 0); + } else { + update_peer_lastmsgssent(peer, -1, 0); + } ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name); } if (res < 0) { @@ -25649,12 +25663,14 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only) } if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) { + update_peer_lastmsgssent(peer, -1, 1); ao2_unlock(peer); return 0; } /* Do we have an IP address? If not, skip this peer */ if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) { + update_peer_lastmsgssent(peer, -1, 1); ao2_unlock(peer); return 0; } @@ -25665,6 +25681,11 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only) struct ast_str *mailbox_str = ast_str_alloca(512); peer_mailboxes_to_str(&mailbox_str, peer); ao2_unlock(peer); + /* If there is no mailbox do nothing */ + if (ast_strlen_zero(mailbox_str->str)) { + update_peer_lastmsgssent(peer, -1, 0); + return 0; + } ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs); ao2_lock(peer); } @@ -25677,6 +25698,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only) ao2_unlock(peer); /* Build temporary dialog for this message */ if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) { + update_peer_lastmsgssent(peer, -1, 0); return -1; } @@ -25689,7 +25711,7 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only) /* Maybe they're not registered, etc. */ dialog_unlink_all(p); dialog_unref(p, "unref dialog p just created via sip_alloc"); - /* sip_destroy(p); */ + update_peer_lastmsgssent(peer, -1, 0); return 0; } /* Recalculate our side, and recalculate Call ID */ @@ -25722,6 +25744,8 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only) sip_pvt_unlock(p); dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer."); + update_peer_lastmsgssent(peer, ((newmsgs > 0x7fff ? 0x7fff0000 : (newmsgs << 16)) | (oldmsgs > 0xffff ? 0xffff : oldmsgs)), 0); + return 0; } -- 2.47.2