86 static void print_frame(
struct ast_frame *frame);
108 int values[ARRAY_LEN(frametype2str)];
111 static void datastore_destroy_cb(
void *data) {
116 .
type =
"frametrace",
117 .destroy = datastore_destroy_cb
120 static void hook_destroy_cb(
void *framedata)
138 for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
139 if (frame->
frametype == frametype2str[i].type) {
140 if ((framedata->list_type == 0) && (framedata->values[i])) {
142 }
else if ((framedata->list_type == 1) && (!framedata->values[i])){
150 ast_verbose(
"%s on Channel %s\n", event ==
AST_FRAMEHOOK_EVENT_READ ?
"<--Read" :
"--> Write", ast_channel_name(chan));
156 static int frame_trace_helper(
struct ast_channel *chan,
const char *cmd,
char *data,
const char *value)
161 .
version = AST_FRAMEHOOK_INTERFACE_VERSION,
162 .event_cb = hook_event_cb,
163 .destroy_cb = hook_destroy_cb,
168 ast_log(LOG_WARNING,
"No channel was provided to %s function.\n", cmd);
172 if (!(framedata =
ast_calloc(1,
sizeof(*framedata)))) {
176 interface.
data = framedata;
178 if (!strcasecmp(data,
"black")) {
179 framedata->list_type = 1;
181 for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
182 if (strcasestr(value, frametype2str[i].str)) {
183 framedata->values[i] = 1;
187 ast_channel_lock(chan);
192 id = datastore->
data;
198 if (!(datastore = ast_datastore_alloc(&frame_trace_datastore, NULL))) {
200 ast_channel_unlock(chan);
207 ast_channel_unlock(chan);
212 datastore->
data = id;
215 ast_channel_unlock(chan);
220 static void print_frame(
struct ast_frame *frame)
224 ast_verbose(
"FrameType: DTMF END\n");
229 ast_verbose(
"FrameType: VOICE\n");
231 ast_verbose(
"MS: %ld\n", frame->
len);
232 ast_verbose(
"Samples: %d\n", frame->
samples);
233 ast_verbose(
"Bytes: %d\n", frame->
datalen);
236 ast_verbose(
"FrameType: VIDEO\n");
238 ast_verbose(
"MS: %ld\n", frame->
len);
239 ast_verbose(
"Samples: %d\n", frame->
samples);
240 ast_verbose(
"Bytes: %d\n", frame->
datalen);
243 ast_verbose(
"FrameType: CONTROL\n");
246 ast_verbose(
"SubClass: HANGUP\n");
249 ast_verbose(
"SubClass: RING\n");
252 ast_verbose(
"SubClass: RINGING\n");
255 ast_verbose(
"SubClass: ANSWER\n");
258 ast_verbose(
"SubClass: BUSY\n");
261 ast_verbose(
"SubClass: TAKEOFFHOOK\n");
264 ast_verbose(
"SubClass: OFFHOOK\n");
267 ast_verbose(
"SubClass: CONGESTION\n");
270 ast_verbose(
"SubClass: FLASH\n");
273 ast_verbose(
"SubClass: WINK\n");
276 ast_verbose(
"SubClass: OPTION\n");
279 ast_verbose(
"SubClass: RADIO KEY\n");
282 ast_verbose(
"SubClass: RADIO UNKEY\n");
285 ast_verbose(
"SubClass: PROGRESS\n");
288 ast_verbose(
"SubClass: PROCEEDING\n");
291 ast_verbose(
"SubClass: HOLD\n");
294 ast_verbose(
"SubClass: UNHOLD\n");
297 ast_verbose(
"SubClass: VIDUPDATE\n");
300 ast_verbose(
"SubClass: XXX T38\n");
303 ast_verbose(
"SubClass: SRCUPDATE\n");
306 ast_verbose(
"SubClass: TRANSFER\n");
309 ast_verbose(
"SubClass: CONNECTED LINE\n");
312 ast_verbose(
"SubClass: REDIRECTING\n");
315 ast_verbose(
"SubClass: T38 PARAMETERS\n");
318 ast_verbose(
"SubClass: CC\n");
321 ast_verbose(
"SubClass: SRCCHANGE\n");
324 ast_verbose(
"SubClass: READ ACTION\n");
327 ast_verbose(
"SubClass: AOC\n");
330 ast_verbose(
"SubClass: MCID\n");
333 ast_verbose(
"SubClass: INCOMPLETE\n");
336 ast_verbose(
"SubClass: END_OF_Q\n");
339 ast_verbose(
"SubClass: UPDATE_RTP_PEER\n");
342 ast_verbose(
"SubClass: PVT_CAUSE_CODE\n");
345 ast_verbose(
"SubClass: MASQUERADE_NOTIFY\n");
348 ast_verbose(
"SubClass: STREAM_TOPOLOGY_REQUEST_CHANGE\n");
351 ast_verbose(
"SubClass: STREAM_TOPOLOGY_CHANGED\n");
354 ast_verbose(
"SubClass: STREAM_TOPOLOGY_SOURCE_CHANGED\n");
357 ast_verbose(
"SubClass: STREAM_STOP\n");
360 ast_verbose(
"SubClass: STREAM_SUSPEND\n");
363 ast_verbose(
"SubClass: STREAM_RESTART\n");
366 ast_verbose(
"SubClass: STREAM_REVERSE\n");
369 ast_verbose(
"SubClass: STREAM_FORWARD\n");
372 ast_verbose(
"SubClass: RECORD_CANCEL\n");
375 ast_verbose(
"SubClass: RECORD_STOP\n");
378 ast_verbose(
"SubClass: RECORD_SUSPEND\n");
381 ast_verbose(
"SubClass: RECORD_MUTE\n");
388 ast_verbose(
"Bytes: %d\n", frame->
datalen);
391 ast_verbose(
"FrameType: RTCP\n");
394 ast_verbose(
"FrameType: NULL\n");
397 ast_verbose(
"FrameType: IAX\n");
400 ast_verbose(
"FrameType: TXT\n");
401 ast_verbose(
"Text: %.*s\n", frame->
datalen, (
char*) frame->
data.ptr);
404 ast_verbose(
"FrameType: TXT_DATA\n");
407 ast_verbose(
"FrameType: IMAGE\n");
410 ast_verbose(
"FrameType: HTML\n");
413 ast_verbose(
"FrameType: CNG\n");
416 ast_verbose(
"FrameType: MODEM\n");
419 ast_verbose(
"FrameType: DTMF BEGIN\n");
424 ast_verbose(
"FrameType: Bridge\n");
428 ast_verbose(
"Frametype: Synchronous Bridge\n");
433 ast_verbose(
"Src: %s\n", ast_strlen_zero(frame->
src) ?
"NOT PRESENT" : frame->
src);
438 .
name =
"FRAME_TRACE",
439 .write = frame_trace_helper,
450 e->
command =
"channel dump frames";
452 "Usage: channel dump frames <channel>\n"
453 " List all frames queued to a channel.\n";
460 return CLI_SHOWUSAGE;
465 ast_cli(a->fd,
"%s is not a known channel\n", a->argv[3]);
469 ast_channel_lock(chan);
471 ast_cli(a->fd,
"== Frame list for %s ==\n", ast_channel_name(chan));
472 ast_cli(a->fd,
"%5s %6s %6s %-15s (%-20s) - %s\n",
"#",
"Seqno",
"Stream",
"Frame Type",
"Frame Subclass",
"Src");
478 ast_cli(a->fd,
"%5d %6d %6d %-15s (%-20s) - %s\n", c++, f->
seqno, f->
stream_num, type, subclass,
S_OR(f->
src,
""));
481 ast_channel_unlock(chan);
487 AST_CLI_DEFINE(handle_dump_frames,
"Display frames queued on a specific channel")
490 static int unload_module(
void)
496 static int load_module(
void)
503 AST_MODULE_INFO_STANDARD_EXTENDED(
ASTERISK_GPL_KEY,
"Frame Trace for internal ast_frame debugging.");
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define ast_channel_unref(c)
Decrease channel reference count.
descriptor for a cli entry.
ast_framehook_event
These are the types of events that the framehook's event callback can receive.
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Structure for a data store type.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
ast_control_frame_type
Internal control frame subtype field values.
Structure for a data store object.
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
struct ast_frame_subclass subclass
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
General Asterisk PBX channel definitions.
Data structure associated with a custom dialplan function.
char * ast_frame_subclass2str(struct ast_frame *f, char *subclass, size_t slen, char *moreinfo, size_t mlen)
Copy the discription of a frame's subclass into the provided string.
Core PBX routines and definitions.
ast_frame_type
Frame types.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
Module has failed to load, may be in an inconsistent state.
char * ast_frame_type2str(enum ast_frame_type frame_type, char *ftype, size_t len)
Copy the discription of a frame type into the provided string.
Standard Command Line Interface.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
struct ast_format * format
#define ASTERISK_GPL_KEY
The text the key() function should return.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Asterisk module definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
#define ast_custom_function_register(acf)
Register a custom function.