]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 194833 via svnmerge from
authorDavid Vossel <dvossel@digium.com>
Fri, 15 May 2009 21:13:39 +0000 (21:13 +0000)
committerDavid Vossel <dvossel@digium.com>
Fri, 15 May 2009 21:13:39 +0000 (21:13 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

................
  r194833 | dvossel | 2009-05-15 15:52:12 -0500 (Fri, 15 May 2009) | 24 lines

  Merged revisions 194557,194685 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.4

  ........
    r194557 | dvossel | 2009-05-14 17:59:43 -0500 (Thu, 14 May 2009) | 10 lines

    IAX2 "Ghost" Channels

    There is a bug tracker issue where people are reporting "Ghost" channels in their 'iax2 show channels' output.  The confusion is caused by channels being listed as "(NONE)" with format "unknown".  These are not channels of coarse.  They are usually just pending registration or poke requests, but it is confusing output.  To help make sense of this I have added two columns to 'iax2 show channels'.  One shows the first message which started the transaction, and the second shows the last message sent by either side of the call.  This helps diagnose why the entry exists and why it may not go away.

    (closes issue #14207)
    Reported by: clive18

    Review: https://reviewboard.asterisk.org/r/246/
  ........
    r194685 | dvossel | 2009-05-15 10:40:37 -0500 (Fri, 15 May 2009) | 6 lines

    Update to previous IAX2 "Ghost" Channels patch.

    Fixed some comments made on reviewboard for the previous patch.

    (issue #14207)
  ........
................

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

channels/chan_iax2.c
channels/iax2-parser.c
channels/iax2-parser.h
channels/iax2.h

index 38510edaeee4d15a66681b56585fc9cd66dbbb76..f645f817c694454f37b3b57e6eb3dffc04b41bfe 100644 (file)
@@ -473,6 +473,9 @@ static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
 #define TS_GAP_FOR_JB_RESYNC   5000
 
+/* used for first_iax_message and last_iax_message.  If this bit is set it was TX, else RX */
+#define MARK_IAX_SUBCLASS_TX   0x8000
+
 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
 static int iaxdynamicthreadcount = 0;
@@ -512,6 +515,10 @@ struct chan_iax2_pvt {
        unsigned int lastvsent;
        /*! Next outgoing timestamp if everything is good */
        unsigned int nextpred;
+       /*! iax frame subclass that began iax2_pvt entry. 0x8000 bit is set on TX */
+       int first_iax_message;
+       /*! Last iax frame subclass sent or received for a iax2_pvt. 0x8000 bit is set on TX */
+       int last_iax_message;
        /*! True if the last voice we transmitted was not silence/CNG */
        unsigned int notsilenttx:1;
        /*! Ping time */
@@ -5022,6 +5029,13 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
                }
                pvt->lastvsent = fts;
        }
+       if (f->frametype == AST_FRAME_IAX) {
+               /* 0x8000 marks this message as TX:, this bit will be stripped later */
+               pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
+               if (!pvt->first_iax_message) {
+                       pvt->first_iax_message = pvt->last_iax_message;
+               }
+       }
        /* Allocate an iax_frame */
        if (now) {
                fr = &frb.fr2;
@@ -5097,7 +5111,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
                        } else
                                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
                }
-       
+
                if (now) {
                        res = send_packet(fr);
                } else
@@ -5663,11 +5677,13 @@ static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, str
 
 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-#define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
-#define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s\n"
+#define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
+#define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s  %s%s  %3s%s\n"
 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
        int x;
        int numchans = 0;
+       char first_message[10] = { 0, };
+       char last_message[10] = { 0, };
 
        switch (cmd) {
        case CLI_INIT:
@@ -5682,13 +5698,12 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
 
        if (a->argc != 3)
                return CLI_SHOWUSAGE;
-       ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
+       ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
        for (x = 0; x < ARRAY_LEN(iaxs); x++) {
                ast_mutex_lock(&iaxsl[x]);
                if (iaxs[x]) {
                        int lag, jitter, localdelay;
                        jb_info jbinfo;
-                       
                        if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
                                jb_getinfo(iaxs[x]->jb, &jbinfo);
                                jitter = jbinfo.jitter;
@@ -5697,17 +5712,24 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
                                jitter = -1;
                                localdelay = 0;
                        }
+
+                       iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
+                       iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
                        lag = iaxs[x]->remote_rr.delay;
                        ast_cli(a->fd, FORMAT,
                                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
-                               ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
+                               ast_inet_ntoa(iaxs[x]->addr.sin_addr),
                                S_OR(iaxs[x]->username, "(None)"),
                                iaxs[x]->callno, iaxs[x]->peercallno,
                                iaxs[x]->oseqno, iaxs[x]->iseqno,
                                lag,
                                jitter,
                                localdelay,
-                               ast_getformatname(iaxs[x]->voiceformat) );
+                               ast_getformatname(iaxs[x]->voiceformat),
+                               (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
+                               first_message,
+                               (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
+                               last_message);
                        numchans++;
                }
                ast_mutex_unlock(&iaxsl[x]);
@@ -5723,14 +5745,18 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
 {
        int x;
        int numchans = 0;
-#define ACN_FORMAT1 "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"
-#define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"
+       char first_message[10] = { 0, };
+       char last_message[10] = { 0, };
+#define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
+#define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
        for (x = 0; x < ARRAY_LEN(iaxs); x++) {
                ast_mutex_lock(&iaxsl[x]);
                if (iaxs[x]) {
                        int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
                        jb_info jbinfo;
-                       
+                       iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
+                       iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
+
                        if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
                                jb_getinfo(iaxs[x]->jb, &jbinfo);
                                localjitter = jbinfo.jitter;
@@ -5748,29 +5774,32 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
                                localooo = -1;
                        }
                        if (s)
-                               
                                astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
-                                             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
-                                             iaxs[x]->pingtime,
-                                             localjitter, 
-                                             localdelay,
-                                             locallost,
-                                             locallosspct,
-                                             localdropped,
-                                             localooo,
-                                             iaxs[x]->frames_received/1000,
-                                             iaxs[x]->remote_rr.jitter,
-                                             iaxs[x]->remote_rr.delay,
-                                             iaxs[x]->remote_rr.losscnt,
-                                             iaxs[x]->remote_rr.losspct,
-                                             iaxs[x]->remote_rr.dropped,
-                                             iaxs[x]->remote_rr.ooo,
-                                             iaxs[x]->remote_rr.packets/1000);
+                                       iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
+                                       iaxs[x]->pingtime,
+                                       localjitter,
+                                       localdelay,
+                                       locallost,
+                                       locallosspct,
+                                       localdropped,
+                                       localooo,
+                                       iaxs[x]->frames_received/1000,
+                                       iaxs[x]->remote_rr.jitter,
+                                       iaxs[x]->remote_rr.delay,
+                                       iaxs[x]->remote_rr.losscnt,
+                                       iaxs[x]->remote_rr.losspct,
+                                       iaxs[x]->remote_rr.dropped,
+                                       iaxs[x]->remote_rr.ooo,
+                                       iaxs[x]->remote_rr.packets/1000,
+                                       (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
+                                       first_message,
+                                       (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
+                                       last_message);
                        else
                                ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
                                        iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
                                        iaxs[x]->pingtime,
-                                       localjitter, 
+                                       localjitter,
                                        localdelay,
                                        locallost,
                                        locallosspct,
@@ -5783,8 +5812,11 @@ static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
                                        iaxs[x]->remote_rr.losspct,
                                        iaxs[x]->remote_rr.dropped,
                                        iaxs[x]->remote_rr.ooo,
-                                       iaxs[x]->remote_rr.packets/1000
-                                       );
+                                       iaxs[x]->remote_rr.packets/1000,
+                                       (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
+                                       first_message,
+                                       (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
+                                       last_message);
                        numchans++;
                }
                ast_mutex_unlock(&iaxsl[x]);
@@ -5809,15 +5841,13 @@ static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, str
        }
        if (a->argc != 3)
                return CLI_SHOWUSAGE;
-       ast_cli(a->fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
-       ast_cli(a->fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
+       ast_cli(a->fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
+       ast_cli(a->fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
        numchans = ast_cli_netstats(NULL, a->fd, 1);
        ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
        return CLI_SUCCESS;
 }
 
-
-
 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
        switch (cmd) {
@@ -8683,7 +8713,10 @@ retryowner:
                                if (iaxdebug)
                                        ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
                        }
-
+                       iaxs[fr->callno]->last_iax_message = f.subclass;
+                       if (!iaxs[fr->callno]->first_iax_message) {
+                               iaxs[fr->callno]->first_iax_message = f.subclass;
+                       }
                        switch(f.subclass) {
                        case IAX_COMMAND_ACK:
                                /* Do nothing */
index b9af6fd6e546576f960a80434ba964cf2bdc598c..fb30773414ad8020c925a68f419d8ff3c1779684 100644 (file)
@@ -408,6 +408,135 @@ static void dump_ies(unsigned char *iedata, int len)
        outputf("\n");
 }
 
+void iax_frame_subclass2str(enum iax_frame_subclass subclass, char *str, size_t len)
+{
+       const char *cmd = "Unknown";
+
+       /* if an error occurs here during compile, that means a new iax frame subclass
+        * has been added to the iax_frame_subclass enum.  Add the new subclass to the
+        * switch case and make sure to update it with a new string representation. */
+       switch (subclass) {
+       case IAX_COMMAND_NEW:
+               cmd = "NEW    ";
+               break;
+       case IAX_COMMAND_PING:
+               cmd = "PING   ";
+               break;
+       case IAX_COMMAND_PONG:
+               cmd = "PONG   ";
+               break;
+       case IAX_COMMAND_ACK:
+               cmd = "ACK    ";
+               break;
+       case IAX_COMMAND_HANGUP:
+               cmd = "HANGUP ";
+               break;
+       case IAX_COMMAND_REJECT:
+               cmd = "REJECT ";
+               break;
+       case IAX_COMMAND_ACCEPT:
+               cmd = "ACCEPT ";
+               break;
+       case IAX_COMMAND_AUTHREQ:
+               cmd = "AUTHREQ";
+               break;
+       case IAX_COMMAND_AUTHREP:
+               cmd = "AUTHREP";
+               break;
+       case IAX_COMMAND_INVAL:
+               cmd = "INVAL  ";
+               break;
+       case IAX_COMMAND_LAGRQ:
+               cmd = "LAGRQ  ";
+               break;
+       case IAX_COMMAND_LAGRP:
+               cmd = "LAGRP  ";
+               break;
+       case IAX_COMMAND_REGREQ:
+               cmd = "REGREQ ";
+               break;
+       case IAX_COMMAND_REGAUTH:
+               cmd = "REGAUTH";
+               break;
+       case IAX_COMMAND_REGACK:
+               cmd = "REGACK ";
+               break;
+       case IAX_COMMAND_REGREJ:
+               cmd = "REGREJ ";
+               break;
+       case IAX_COMMAND_REGREL:
+               cmd = "REGREL ";
+               break;
+       case IAX_COMMAND_VNAK:
+               cmd = "VNAK   ";
+               break;
+       case IAX_COMMAND_DPREQ:
+               cmd = "DPREQ  ";
+               break;
+       case IAX_COMMAND_DPREP:
+               cmd = "DPREP  ";
+               break;
+       case IAX_COMMAND_DIAL:
+               cmd = "DIAL   ";
+               break;
+       case IAX_COMMAND_TXREQ:
+               cmd = "TXREQ  ";
+               break;
+       case IAX_COMMAND_TXCNT:
+               cmd = "TXCNT  ";
+               break;
+       case IAX_COMMAND_TXACC:
+               cmd = "TXACC  ";
+               break;
+       case IAX_COMMAND_TXREADY:
+               cmd = "TXREADY";
+               break;
+       case IAX_COMMAND_TXREL:
+               cmd = "TXREL  ";
+               break;
+       case IAX_COMMAND_TXREJ:
+               cmd = "TXREJ  ";
+               break;
+       case IAX_COMMAND_QUELCH:
+               cmd = "QUELCH ";
+               break;
+       case IAX_COMMAND_UNQUELCH:
+               cmd = "UNQULCH";
+               break;
+       case IAX_COMMAND_POKE:
+               cmd = "POKE   ";
+               break;
+       case IAX_COMMAND_PAGE:
+               cmd = "PAGE   ";
+               break;
+       case IAX_COMMAND_MWI:
+               cmd = "MWI    ";
+               break;
+       case IAX_COMMAND_UNSUPPORT:
+               cmd = "UNSPRTD";
+               break;
+       case IAX_COMMAND_TRANSFER:
+               cmd = "TRANSFR";
+               break;
+       case IAX_COMMAND_PROVISION:
+               cmd = "PROVISN";
+               break;
+       case IAX_COMMAND_FWDOWNL:
+               cmd = "FWDWNLD";
+               break;
+       case IAX_COMMAND_FWDATA:
+               cmd = "FWDATA ";
+               break;
+       case IAX_COMMAND_TXMEDIA:
+               cmd = "TXMEDIA";
+               break;
+       case IAX_COMMAND_RTKEY:
+               cmd = "RTKEY  ";
+               break;
+       }
+       ast_copy_string(str, cmd, len);
+}
+
 void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
 {
        const char *framelist[] = {
@@ -425,47 +554,6 @@ void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, s
                "MODEM  ",
                "DTMF_B ",
        };
-       const char *iaxs[] = {
-               "(0?)",
-               "NEW    ",
-               "PING   ",
-               "PONG   ",
-               "ACK    ",
-               "HANGUP ",
-               "REJECT ",
-               "ACCEPT ",
-               "AUTHREQ",
-               "AUTHREP",
-               "INVAL  ",
-               "LAGRQ  ",
-               "LAGRP  ",
-               "REGREQ ",
-               "REGAUTH",
-               "REGACK ",
-               "REGREJ ",
-               "REGREL ",
-               "VNAK   ",
-               "DPREQ  ",
-               "DPREP  ",
-               "DIAL   ",
-               "TXREQ  ",
-               "TXCNT  ",
-               "TXACC  ",
-               "TXREADY",
-               "TXREL  ",
-               "TXREJ  ",
-               "QUELCH ",
-               "UNQULCH",
-               "POKE   ",
-               "PAGE   ",
-               "MWI    ",
-               "UNSPRTD",
-               "TRANSFR",
-               "PROVISN",
-               "FWDWNLD",
-               "FWDATA ",
-               "TXMEDIA"
-       };
        const char *cmds[] = {
                "(0?)",
                "HANGUP ",
@@ -533,12 +621,8 @@ void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, s
                sprintf(subclass2, "%c", fh->csub);
                subclass = subclass2;
        } else if (fh->type == AST_FRAME_IAX) {
-               if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
-                       snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
-                       subclass = subclass2;
-               } else {
-                       subclass = iaxs[(int)fh->csub];
-               }
+               iax_frame_subclass2str((int)fh->csub, subclass2, sizeof(subclass2));
+               subclass = subclass2;
        } else if (fh->type == AST_FRAME_CONTROL) {
                if (fh->csub >= (int)sizeof(cmds)/(int)sizeof(cmds[0])) {
                        snprintf(subclass2, sizeof(subclass2), "(%d?)", fh->csub);
index e75cd4209d4355005e2f3286c0c8e3903458fa25..9de873b35c5dd2b7a324312a3cc2ece462e1018a 100644 (file)
@@ -150,6 +150,7 @@ void iax_set_output(void (*output)(const char *data));
 /* Choose a different function for errors */
 void iax_set_error(void (*output)(const char *data));
 void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
+void iax_frame_subclass2str(enum iax_frame_subclass subclass, char *str, size_t len);
 
 const char *iax_ie2str(int ie);
 
index 2b79e91d0de7a0f28daecd5df89d5b07448456a4..394eef2e4595c2e2f82cb97a763abc2e12fcc592 100644 (file)
@@ -44,7 +44,7 @@
 #define IAX_WINDOW                     64
 
 /*! Subclass for AST_FRAME_IAX */
-enum {
+enum iax_frame_subclass {
        IAX_COMMAND_NEW =       1,
        IAX_COMMAND_PING =      2,
        IAX_COMMAND_PONG =      3,
@@ -104,20 +104,20 @@ enum {
        /*! Provision device */
        IAX_COMMAND_PROVISION = 35,
        /*! Download firmware */
-       IAX_COMMAND_FWDOWNL =   36,     
+       IAX_COMMAND_FWDOWNL =   36,
        /*! Firmware Data */
        IAX_COMMAND_FWDATA =    37,
        /*! Transfer media only */
        IAX_COMMAND_TXMEDIA =   38,
        /*! Command to rotate key */
-       IAX_COMMAND_RTKEY =     39,
+       IAX_COMMAND_RTKEY =     39,
 };
 
 /*! By default require re-registration once per minute */
-#define IAX_DEFAULT_REG_EXPIRE  60     
+#define IAX_DEFAULT_REG_EXPIRE  60
 
 /*! How long to wait before closing bridged call */
-#define IAX_LINGER_TIMEOUT             10 
+#define IAX_LINGER_TIMEOUT             10
 
 #define IAX_DEFAULT_PORTNO             4569