|
35 | 35 | #include "asterisk/channel.h" |
36 | 36 | #include "asterisk/pbx.h" |
37 | 37 | #include "asterisk/framehook.h" |
| 38 | +#include "asterisk/cli.h" |
38 | 39 |
|
39 | 40 | /*** DOCUMENTATION |
40 | 41 | <function name="FRAME_TRACE" language="en_US"> |
@@ -438,14 +439,64 @@ static struct ast_custom_function frame_trace_function = { |
438 | 439 | .write = frame_trace_helper, |
439 | 440 | }; |
440 | 441 |
|
| 442 | +static char *handle_dump_frames(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| 443 | +{ |
| 444 | + struct ast_channel *chan; |
| 445 | + struct ast_frame *f; |
| 446 | + int c = 1; |
| 447 | + |
| 448 | + switch (cmd) { |
| 449 | + case CLI_INIT: |
| 450 | + e->command = "channel dump frames"; |
| 451 | + e->usage = |
| 452 | + "Usage: channel dump frames <channel>\n" |
| 453 | + " List all frames queued to a channel.\n"; |
| 454 | + return NULL; |
| 455 | + case CLI_GENERATE: |
| 456 | + return ast_complete_channels(a->line, a->word, a->pos, a->n, 3); |
| 457 | + } |
| 458 | + |
| 459 | + if (a->argc != 4) { |
| 460 | + return CLI_SHOWUSAGE; |
| 461 | + } |
| 462 | + |
| 463 | + chan = ast_channel_get_by_name(a->argv[3]); |
| 464 | + if (!chan) { |
| 465 | + ast_cli(a->fd, "%s is not a known channel\n", a->argv[3]); |
| 466 | + return CLI_SUCCESS; |
| 467 | + } |
| 468 | + |
| 469 | + ast_channel_lock(chan); |
| 470 | + |
| 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"); |
| 473 | + AST_LIST_TRAVERSE(ast_channel_readq(chan), f, frame_list) { |
| 474 | + char type[64]; |
| 475 | + char subclass[64]; |
| 476 | + ast_frame_type2str(f->frametype, type, sizeof(type)); |
| 477 | + ast_frame_subclass2str(f, subclass, sizeof(subclass), NULL, 0); |
| 478 | + ast_cli(a->fd, "%5d %6d %6d %-15s (%-20s) - %s\n", c++, f->seqno, f->stream_num, type, subclass, S_OR(f->src, "")); |
| 479 | + } |
| 480 | + |
| 481 | + ast_channel_unlock(chan); |
| 482 | + ast_channel_unref(chan); |
| 483 | + return CLI_SUCCESS; |
| 484 | +} |
| 485 | + |
| 486 | +static struct ast_cli_entry cli_frames[] = { |
| 487 | + AST_CLI_DEFINE(handle_dump_frames, "Display frames queued on a specific channel") |
| 488 | +}; |
| 489 | + |
441 | 490 | static int unload_module(void) |
442 | 491 | { |
| 492 | + ast_cli_unregister_multiple(cli_frames, ARRAY_LEN(cli_frames)); |
443 | 493 | return ast_custom_function_unregister(&frame_trace_function); |
444 | 494 | } |
445 | 495 |
|
446 | 496 | static int load_module(void) |
447 | 497 | { |
448 | 498 | int res = ast_custom_function_register(&frame_trace_function); |
| 499 | + res |= ast_cli_register_multiple(cli_frames, ARRAY_LEN(cli_frames)); |
449 | 500 | return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS; |
450 | 501 | } |
451 | 502 |
|
|
0 commit comments