Merge "AST-2018-005: Fix tdata leaks when calling pjsip_endpt_send_response(2)"
[asterisk/asterisk.git] / apps / app_dumpchan.c
index d3bf17f..bec7788 100644 (file)
  * \ingroup applications
  */
 
-#include "asterisk.h"
+/*** MODULEINFO
+       <support_level>core</support_level>
+ ***/
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#include "asterisk.h"
 
 #include "asterisk/pbx.h"
 #include "asterisk/module.h"
 #include "asterisk/channel.h"
+#include "asterisk/app.h"
+#include "asterisk/translate.h"
+#include "asterisk/bridge.h"
 
 /*** DOCUMENTATION
        <application name="DumpChan" language="en_US">
@@ -43,7 +48,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                </synopsis>
                <syntax>
                        <parameter name="level">
-                               <para>Minimun verbose level</para>
+                               <para>Minimum verbose level</para>
                        </parameter>
                </syntax>
                <description>
@@ -59,107 +64,132 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
        </application>
  ***/
 
-static char *app = "DumpChan";
+static const char app[] = "DumpChan";
 
 static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
 {
-       struct timeval now;
        long elapsed_seconds = 0;
        int hour = 0, min = 0, sec = 0;
-       char cgrp[BUFSIZ/2];
-       char pgrp[BUFSIZ/2];
-       char formatbuf[BUFSIZ/2];
+       struct ast_str *format_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
+       char cgrp[256];
+       char pgrp[256];
+       struct ast_str *write_transpath = ast_str_alloca(256);
+       struct ast_str *read_transpath = ast_str_alloca(256);
+       struct ast_bridge *bridge;
 
-       now = ast_tvnow();
        memset(buf, 0, size);
        if (!c)
                return 0;
 
-       if (c->cdr) {
-               elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
-               hour = elapsed_seconds / 3600;
-               min = (elapsed_seconds % 3600) / 60;
-               sec = elapsed_seconds % 60;
-       }
+       elapsed_seconds = ast_channel_get_duration(c);
+       hour = elapsed_seconds / 3600;
+       min = (elapsed_seconds % 3600) / 60;
+       sec = elapsed_seconds % 60;
 
+       ast_channel_lock(c);
+       bridge = ast_channel_get_bridge(c);
        snprintf(buf,size,
-                       "Name=               %s\n"
-                       "Type=               %s\n"
-                       "UniqueID=           %s\n"
-                       "CallerIDNum=        %s\n"
-                       "CallerIDName=       %s\n"
-                       "DNIDDigits=         %s\n"
-                       "RDNIS=              %s\n"
-                       "Parkinglot=         %s\n"
-                       "Language=           %s\n"
-                       "State=              %s (%d)\n"
-                       "Rings=              %d\n"
-                       "NativeFormat=       %s\n"
-                       "WriteFormat=        %s\n"
-                       "ReadFormat=         %s\n"
-                       "RawWriteFormat=     %s\n"
-                       "RawReadFormat=      %s\n"
-                       "1stFileDescriptor=  %d\n"
-                       "Framesin=           %d %s\n"
-                       "Framesout=          %d %s\n"
-                       "TimetoHangup=       %ld\n"
-                       "ElapsedTime=        %dh%dm%ds\n"
-                       "Context=            %s\n"
-                       "Extension=          %s\n"
-                       "Priority=           %d\n"
-                       "CallGroup=          %s\n"
-                       "PickupGroup=        %s\n"
-                       "Application=        %s\n"
-                       "Data=               %s\n"
-                       "Blocking_in=        %s\n",
-                       c->name,
-                       c->tech->type,
-                       c->uniqueid,
-                       S_OR(c->cid.cid_num, "(N/A)"),
-                       S_OR(c->cid.cid_name, "(N/A)"),
-                       S_OR(c->cid.cid_dnid, "(N/A)"),
-                       S_OR(c->cid.cid_rdnis, "(N/A)"),
-                       c->parkinglot,
-                       c->language,
-                       ast_state2str(c->_state),
-                       c->_state,
-                       c->rings,
-                       ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->nativeformats),
-                       ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->writeformat),
-                       ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->readformat),
-                       ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawwriteformat),
-                       ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawreadformat),
-                       c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
-                       c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup.tv_sec,
-                       hour,
-                       min,
-                       sec,
-                       c->context,
-                       c->exten,
-                       c->priority,
-                       ast_print_group(cgrp, sizeof(cgrp), c->callgroup),
-                       ast_print_group(pgrp, sizeof(pgrp), c->pickupgroup),
-                       ( c->appl ? c->appl : "(N/A)" ),
-                       ( c-> data ? S_OR(c->data, "(Empty)") : "(None)"),
-                       (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
-
+               "Name=               %s\n"
+               "Type=               %s\n"
+               "UniqueID=           %s\n"
+               "LinkedID=           %s\n"
+               "CallerIDNum=        %s\n"
+               "CallerIDName=       %s\n"
+               "ConnectedLineIDNum= %s\n"
+               "ConnectedLineIDName=%s\n"
+               "DNIDDigits=         %s\n"
+               "RDNIS=              %s\n"
+               "Parkinglot=         %s\n"
+               "Language=           %s\n"
+               "State=              %s (%u)\n"
+               "Rings=              %d\n"
+               "NativeFormat=       %s\n"
+               "WriteFormat=        %s\n"
+               "ReadFormat=         %s\n"
+               "RawWriteFormat=     %s\n"
+               "RawReadFormat=      %s\n"
+               "WriteTranscode=     %s %s\n"
+               "ReadTranscode=      %s %s\n"
+               "1stFileDescriptor=  %d\n"
+               "Framesin=           %u %s\n"
+               "Framesout=          %u %s\n"
+               "TimetoHangup=       %ld\n"
+               "ElapsedTime=        %dh%dm%ds\n"
+               "BridgeID=           %s\n"
+               "Context=            %s\n"
+               "Extension=          %s\n"
+               "Priority=           %d\n"
+               "CallGroup=          %s\n"
+               "PickupGroup=        %s\n"
+               "Application=        %s\n"
+               "Data=               %s\n"
+               "Blocking_in=        %s\n",
+               ast_channel_name(c),
+               ast_channel_tech(c)->type,
+               ast_channel_uniqueid(c),
+               ast_channel_linkedid(c),
+               S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, "(N/A)"),
+               S_COR(ast_channel_caller(c)->id.name.valid, ast_channel_caller(c)->id.name.str, "(N/A)"),
+               S_COR(ast_channel_connected(c)->id.number.valid, ast_channel_connected(c)->id.number.str, "(N/A)"),
+               S_COR(ast_channel_connected(c)->id.name.valid, ast_channel_connected(c)->id.name.str, "(N/A)"),
+               S_OR(ast_channel_dialed(c)->number.str, "(N/A)"),
+               S_COR(ast_channel_redirecting(c)->from.number.valid, ast_channel_redirecting(c)->from.number.str, "(N/A)"),
+               ast_channel_parkinglot(c),
+               ast_channel_language(c),
+               ast_state2str(ast_channel_state(c)),
+               ast_channel_state(c),
+               ast_channel_rings(c),
+               ast_format_cap_get_names(ast_channel_nativeformats(c), &format_buf),
+               ast_format_get_name(ast_channel_writeformat(c)),
+               ast_format_get_name(ast_channel_readformat(c)),
+               ast_format_get_name(ast_channel_rawwriteformat(c)),
+               ast_format_get_name(ast_channel_rawreadformat(c)),
+               ast_channel_writetrans(c) ? "Yes" : "No",
+               ast_translate_path_to_str(ast_channel_writetrans(c), &write_transpath),
+               ast_channel_readtrans(c) ? "Yes" : "No",
+               ast_translate_path_to_str(ast_channel_readtrans(c), &read_transpath),
+               ast_channel_fd(c, 0),
+               ast_channel_fin(c) & ~DEBUGCHAN_FLAG, (ast_channel_fin(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+               ast_channel_fout(c) & ~DEBUGCHAN_FLAG, (ast_channel_fout(c) & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
+               (long)ast_channel_whentohangup(c)->tv_sec,
+               hour,
+               min,
+               sec,
+               bridge ? bridge->uniqueid : "(Not bridged)",
+               ast_channel_context(c),
+               ast_channel_exten(c),
+               ast_channel_priority(c),
+               ast_print_group(cgrp, sizeof(cgrp), ast_channel_callgroup(c)),
+               ast_print_group(pgrp, sizeof(pgrp), ast_channel_pickupgroup(c)),
+               ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)",
+               ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)",
+               (ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)"));
+       ast_channel_unlock(c);
+       ao2_cleanup(bridge);
        return 0;
 }
 
-static int dumpchan_exec(struct ast_channel *chan, void *data)
+static int dumpchan_exec(struct ast_channel *chan, const char *data)
 {
-       struct ast_str *vars = ast_str_alloca(BUFSIZ * 4); /* XXX very large! */
-       char info[1024];
+       struct ast_str *vars = ast_str_thread_get(&ast_str_thread_global_buf, 16);
+       char info[2048];
        int level = 0;
        static char *line = "================================================================================";
 
        if (!ast_strlen_zero(data))
                level = atoi(data);
 
-       pbx_builtin_serialize_variables(chan, &vars);
-       serialize_showchan(chan, info, sizeof(info));
-       if (option_verbose >= level)
-               ast_verbose("\nDumping Info For Channel: %s:\n%s\nInfo:\n%s\nVariables:\n%s%s\n", chan->name, line, info, vars->str, line);
+       if (VERBOSITY_ATLEAST(level)) {
+               serialize_showchan(chan, info, sizeof(info));
+               pbx_builtin_serialize_variables(chan, &vars);
+               ast_verb(level, "\n"
+                       "Dumping Info For Channel: %s:\n"
+                       "%s\n"
+                       "Info:\n"
+                       "%s\n"
+                       "Variables:\n"
+                       "%s%s\n", ast_channel_name(chan), line, info, ast_str_buffer(vars), line);
+       }
 
        return 0;
 }