Re-add LastMsgsSent value for SIP peers
authorMatthew Jordan <mjordan@digium.com>
Wed, 23 May 2012 13:46:38 +0000 (13:46 +0000)
committerMatthew Jordan <mjordan@digium.com>
Wed, 23 May 2012 13:46:38 +0000 (13:46 +0000)
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.  The value was previously removed
for Asterisk 10; however, since it was still present in Asterisk 1.8 and still
useful for reporting purposes, it was decided to re-add the value.

This patch re-adds the 'LastMsgsSent' field in the response to an AMI/CLI 'sip
show peer [peer]' command, and 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
........

Merged revisions 367362 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 367369 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@367376 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
channels/sip/include/sip.h

index 665daec..ef521c4 100644 (file)
@@ -15272,6 +15272,20 @@ static void extract_host_from_hostport(char **hostport)
        ast_sockaddr_split_hostport(*hostport, hostport, &dont_care, PARSE_PORT_IGNORE);
 }
 
        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
 /*! \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
@@ -15285,6 +15299,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);
        char tmp[256];
        char *c, *name, *unused_password, *domain;
        char *uri2 = ast_strdupa(uri);
+       int send_mwi = 0;
 
        terminate_uri(uri2);
 
 
        terminate_uri(uri2);
 
@@ -15414,12 +15429,14 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
                                                ast_string_field_set(p, fullcontact, peer->fullcontact);
                                                transmit_response_with_date(p, "200 OK", req);
                                                res = 0;
                                                ast_string_field_set(p, fullcontact, peer->fullcontact);
                                                transmit_response_with_date(p, "200 OK", req);
                                                res = 0;
+                                               send_mwi = 1;
                                                break;
                                        case PARSE_REGISTER_UPDATE:
                                                ast_string_field_set(p, fullcontact, peer->fullcontact);
                                                update_peer(peer, p->expiry);
                                                /* Say OK and ask subsystem to retransmit msg counter */
                                                transmit_response_with_date(p, "200 OK", req);
                                                break;
                                        case PARSE_REGISTER_UPDATE:
                                                ast_string_field_set(p, fullcontact, peer->fullcontact);
                                                update_peer(peer, p->expiry);
                                                /* Say OK and ask subsystem to retransmit msg counter */
                                                transmit_response_with_date(p, "200 OK", req);
+                                               send_mwi = 1;
                                                res = 0;
                                                break;
                                        }
                                                res = 0;
                                                break;
                                        }
@@ -15454,6 +15471,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
                        case PARSE_REGISTER_QUERY:
                                ast_string_field_set(p, fullcontact, peer->fullcontact);
                                transmit_response_with_date(p, "200 OK", req);
                        case PARSE_REGISTER_QUERY:
                                ast_string_field_set(p, fullcontact, peer->fullcontact);
                                transmit_response_with_date(p, "200 OK", req);
+                               send_mwi = 1;
                                res = 0;
                                break;
                        case PARSE_REGISTER_UPDATE:
                                res = 0;
                                break;
                        case PARSE_REGISTER_UPDATE:
@@ -15461,6 +15479,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));
                                /* 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));
+                               send_mwi = 1;
                                res = 0;
                                break;
                        }
                                res = 0;
                                break;
                        }
@@ -15468,9 +15487,13 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
                }
        }
        if (!res) {
                }
        }
        if (!res) {
-               ao2_unlock(p);
-               sip_send_mwi_to_peer(peer, 0);
-               ao2_lock(p);
+               if (send_mwi) {
+                       ao2_unlock(p);
+                       sip_send_mwi_to_peer(peer, 0);
+                       ao2_lock(p);
+               } else {
+                       update_peer_lastmsgssent(peer, -1, 0);
+               }
                ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
        }
        if (res < 0) {
                ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
        }
        if (res < 0) {
@@ -18250,6 +18273,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
                ast_cli(fd, "  MOH Suggest  : %s\n", peer->mohsuggest);
                ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
                ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
                ast_cli(fd, "  MOH Suggest  : %s\n", peer->mohsuggest);
                ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
                ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
+               ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
                ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
                ast_cli(fd, "  Max forwards : %d\n", peer->maxforwards);
                if (peer->busy_level)
                ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
                ast_cli(fd, "  Max forwards : %d\n", peer->maxforwards);
                if (peer->busy_level)
@@ -18365,6 +18389,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
                peer_mailboxes_to_str(&mailbox_str, peer);
                astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
                astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
                peer_mailboxes_to_str(&mailbox_str, peer);
                astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
                astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
+               astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
                astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
                astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
                astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
                astman_append(s, "Maxforwards: %d\r\n", peer->maxforwards);
                astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
                astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
@@ -26730,12 +26755,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) {
        }
 
        if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt) {
+               update_peer_lastmsgssent(peer, -1, 1);
                ao2_unlock(peer);
                return -1;
        }
 
        /* Do we have an IP address? If not, skip this peer */
        if (ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) {
                ao2_unlock(peer);
                return -1;
        }
 
        /* 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 -1;
        }
                ao2_unlock(peer);
                return -1;
        }
@@ -26751,6 +26778,11 @@ static int sip_send_mwi_to_peer(struct sip_peer *peer, int cache_only)
                        return -1;
                }
                ao2_unlock(peer);
                        return -1;
                }
                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);
        }
                ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs);
                ao2_lock(peer);
        }
@@ -26763,6 +26795,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, NULL))) {
                ao2_unlock(peer);
                /* Build temporary dialog for this message */
                if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL, NULL))) {
+                       update_peer_lastmsgssent(peer, -1, 0);
                        return -1;
                }
 
                        return -1;
                }
 
@@ -26775,7 +26808,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");
                        /* 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 -1;
                }
                /* Recalculate our side, and recalculate Call ID */
                        return -1;
                }
                /* Recalculate our side, and recalculate Call ID */
@@ -26808,6 +26841,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.");
 
        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;
 }
 
        return 0;
 }
 
index 6c9cba7..cd061b7 100644 (file)
@@ -1298,6 +1298,7 @@ struct sip_peer {
        int maxforwards;                /*!< SIP Loop prevention */
        enum transfermodes allowtransfer;   /*! SIP Refer restriction scheme */
        struct ast_codec_pref prefs;    /*!<  codec prefs */
        int maxforwards;                /*!< SIP Loop prevention */
        enum transfermodes allowtransfer;   /*! SIP Refer restriction scheme */
        struct ast_codec_pref prefs;    /*!<  codec prefs */
+       int lastmsgssent;                               /*!< The last known VM message counts (new/old) */
        unsigned int sipoptions;        /*!<  Supported SIP options */
        struct ast_flags flags[3];      /*!<  SIP_ flags */
 
        unsigned int sipoptions;        /*!<  Supported SIP options */
        struct ast_flags flags[3];      /*!<  SIP_ flags */