Merge OEJ's print groups feature (bug #3228, with changes)
[asterisk/asterisk.git] / apps / app_dumpchan.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Application to dump channel variables
5  * 
6  * Copyright (C) 2004, Anthony Minessale II.
7  *
8  * Anthony Minessale <anthmct@yahoo.com>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License (and disclaimed to Digium)
12  */
13
14 #include <asterisk/file.h>
15 #include <asterisk/logger.h>
16 #include <asterisk/channel.h>
17 #include <asterisk/pbx.h>
18 #include <asterisk/module.h>
19 #include <asterisk/options.h>
20 #include <asterisk/utils.h>
21 #include <asterisk/lock.h>
22 #include <asterisk/utils.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26
27 static char *tdesc = "Dump Info About The Calling Channel";
28 static char *app = "DumpChan";
29 static char *synopsis = "Dump Info About The Calling Channel";
30 static char *desc = 
31 "   DumpChan([<min_verbose_level>])\n"
32 "Displays information on channel and listing of all channel\n"
33 "variables. If min_verbose_level is specified, output is only\n"
34 "displayed when the verbose level is currently set to that number\n"
35 "or greater. Always returns 0.\n\n";
36
37 STANDARD_LOCAL_USER;
38
39 LOCAL_USER_DECL;
40
41 static int ast_serialize_showchan(struct ast_channel *c, char *buf, size_t size)
42 {
43         struct timeval now;
44         long elapsed_seconds=0;
45         int hour=0, min=0, sec=0;
46         char cgrp[256];
47         char pgrp[256];
48         
49         gettimeofday(&now, NULL);
50         memset(buf,0,size);
51         if (!c)
52                 return 0;
53
54         if (c->cdr) {
55                 elapsed_seconds = now.tv_sec - c->cdr->start.tv_sec;
56                 hour = elapsed_seconds / 3600;
57                 min = (elapsed_seconds % 3600) / 60;
58                 sec = elapsed_seconds % 60;
59         }
60
61         snprintf(buf,size, 
62                          "Name=               %s\n"
63                          "Type=               %s\n"
64                          "UniqueID=           %s\n"
65                          "CallerID=           %s\n"
66                          "CallerIDName=       %s\n"
67                          "DNIDDigits=         %s\n"
68                          "State=              %s (%d)\n"
69                          "Rings=              %d\n"
70                          "NativeFormat=       %d\n"
71                          "WriteFormat=        %d\n"
72                          "ReadFormat=         %d\n"
73                          "1stFileDescriptor=  %d\n"
74                          "Framesin=           %d %s\n"
75                          "Framesout=          %d %s\n"
76                          "TimetoHangup=       %ld\n"
77                          "ElapsedTime=        %dh%dm%ds\n"
78                          "Context=            %s\n"
79                          "Extension=          %s\n"
80                          "Priority=           %d\n"
81                          "CallGroup=          %s\n"
82                          "PickupGroup=        %s\n"
83                          "Application=        %s\n"
84                          "Data=               %s\n"
85                          "Blocking_in=        %s\n",
86                          c->name,
87                          c->type,
88                          c->uniqueid,
89                          (c->cid.cid_num ? c->cid.cid_num : "(N/A)"),
90                          (c->cid.cid_name ? c->cid.cid_name : "(N/A)"),
91                          (c->cid.cid_dnid ? c->cid.cid_dnid : "(N/A)" ),
92                          ast_state2str(c->_state),
93                          c->_state,
94                          c->rings,
95                          c->nativeformats,
96                          c->writeformat,
97                          c->readformat,
98                          c->fds[0], c->fin & 0x7fffffff, (c->fin & 0x80000000) ? " (DEBUGGED)" : "",
99                          c->fout & 0x7fffffff, (c->fout & 0x80000000) ? " (DEBUGGED)" : "", (long)c->whentohangup,
100                          hour,
101                          min,
102                          sec,
103                          c->context,
104                          c->exten,
105                          c->priority,
106                          ast_print_group(cgrp, sizeof(cgrp), c->callgroup),
107                          ast_print_group(pgrp, sizeof(pgrp), c->pickupgroup),
108                          ( c->appl ? c->appl : "(N/A)" ),
109                          ( c-> data ? (!ast_strlen_zero(c->data) ? c->data : "(Empty)") : "(None)"),
110                          (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));
111
112         return 0;
113 }
114
115 static int dumpchan_exec(struct ast_channel *chan, void *data)
116 {
117         int res=0;
118         struct localuser *u;
119         char vars[1024];
120         char info[1024];
121         int level = 0;
122         static char *line = "================================================================================";
123         LOCAL_USER_ADD(u);
124
125         if (data) {
126                 level = atoi(data);
127         }
128
129         pbx_builtin_serialize_variables(chan, vars, sizeof(vars));
130         ast_serialize_showchan(chan, info, sizeof(info));
131         if (option_verbose >= level)
132                 ast_verbose("\nDumping Info For Channel: %s:\n%s\nInfo:\n%s\nVariables:\n%s%s\n",chan->name, line, info, vars, line);
133
134         LOCAL_USER_REMOVE(u);
135         return res;
136 }
137
138 int unload_module(void)
139 {
140         STANDARD_HANGUP_LOCALUSERS;
141         return ast_unregister_application(app);
142 }
143
144 int load_module(void)
145 {
146         return ast_register_application(app, dumpchan_exec, synopsis, desc);
147 }
148
149 char *description(void)
150 {
151         return tdesc;
152 }
153
154 int usecount(void)
155 {
156         int res;
157         STANDARD_USECOUNT(res);
158         return res;
159 }
160
161 char *key()
162 {
163         return ASTERISK_GPL_KEY;
164 }
165