Asterisk - The Open Source Telephony Project GIT-master-7921072
cli_commands.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2016, Fairview 5 Engineering, LLC
5 *
6 * See http://www.asterisk.org for more information about
7 * the Asterisk project. Please do not directly contact
8 * any of the maintainers of this project for assistance;
9 * the project provides a web site, mailing lists and IRC
10 * channels for your use.
11 *
12 * This program is free software, distributed under the terms of
13 * the GNU General Public License Version 2. See the LICENSE file
14 * at the top of the source tree.
15 */
16
17/*!
18 * \file
19 *
20 * \author \verbatim George Joseph <george.joseph@fairview5.com> \endverbatim
21 *
22 * \ingroup functions
23 *
24 * \brief PJSIP channel CLI functions
25 */
26
27#include "asterisk.h"
28
29#include <pjsip.h>
30#include <pjlib.h>
31#include <pjsip_ua.h>
32
33#include "asterisk/astobj2.h"
34#include "asterisk/channel.h"
35#include "asterisk/format.h"
36#include "asterisk/res_pjsip.h"
39#include "asterisk/stasis.h"
40#include "asterisk/time.h"
41#include "include/chan_pjsip.h"
43
44
45static int cli_channel_iterate(void *endpoint, ao2_callback_fn callback, void *arg)
46{
47 return ast_sip_for_each_channel(endpoint, callback, arg);
48}
49
50static int cli_channelstats_iterate(void *endpoint, ao2_callback_fn callback, void *arg)
51{
52 return ast_sip_for_each_channel(endpoint, callback, arg);
53}
54
55static int cli_channel_sort(const void *obj, const void *arg, int flags)
56{
57 const struct ast_channel_snapshot *left_obj = obj;
58 const struct ast_channel_snapshot *right_obj = arg;
59 const char *right_key = arg;
60 int cmp;
61
62 switch (flags & OBJ_SEARCH_MASK) {
64 right_key = right_obj->base->name;
65 /* Fall through */
66 case OBJ_SEARCH_KEY:
67 cmp = strcmp(left_obj->base->name, right_key);
68 break;
70 cmp = strncmp(left_obj->base->name, right_key, strlen(right_key));
71 break;
72 default:
73 cmp = 0;
74 break;
75 }
76
77 return cmp;
78}
79
80static int cli_channelstats_sort(const void *obj, const void *arg, int flags)
81{
82 const struct ast_channel_snapshot *left_obj = obj;
83 const struct ast_channel_snapshot *right_obj = arg;
84 const char *right_key = arg;
85 int cmp;
86
87 switch (flags & OBJ_SEARCH_MASK) {
89 cmp = strcmp(left_obj->bridge->id, right_obj->bridge->id);
90 if (cmp) {
91 return cmp;
92 }
93 right_key = right_obj->base->name;
94 /* Fall through */
95 case OBJ_SEARCH_KEY:
96 cmp = strcmp(left_obj->base->name, right_key);
97 break;
99 cmp = strncmp(left_obj->base->name, right_key, strlen(right_key));
100 break;
101 default:
102 cmp = 0;
103 break;
104 }
105
106 return cmp;
107}
108
109static int cli_channel_compare(void *obj, void *arg, int flags)
110{
111 const struct ast_channel_snapshot *left_obj = obj;
112 const struct ast_channel_snapshot *right_obj = arg;
113 const char *right_key = arg;
114 int cmp = 0;
115
116 switch (flags & OBJ_SEARCH_MASK) {
118 right_key = right_obj->base->name;
119 /* Fall through */
120 case OBJ_SEARCH_KEY:
121 if (strcmp(left_obj->base->name, right_key) == 0) {
122 cmp = CMP_MATCH | CMP_STOP;
123 }
124 break;
126 if (strncmp(left_obj->base->name, right_key, strlen(right_key)) == 0) {
127 cmp = CMP_MATCH;
128 }
129 break;
130 default:
131 cmp = 0;
132 break;
133 }
134
135 return cmp;
136}
137
138static int cli_channelstats_compare(void *obj, void *arg, int flags)
139{
140 const struct ast_channel_snapshot *left_obj = obj;
141 const struct ast_channel_snapshot *right_obj = arg;
142 const char *right_key = arg;
143 int cmp = 0;
144
145 switch (flags & OBJ_SEARCH_MASK) {
147 if (strcmp(left_obj->bridge->id, right_obj->bridge->id) == 0
148 && strcmp(left_obj->base->name, right_obj->base->name) == 0) {
149 return CMP_MATCH | CMP_STOP;
150 }
151 break;
152 case OBJ_SEARCH_KEY:
153 if (strcmp(left_obj->base->name, right_key) == 0) {
154 cmp = CMP_MATCH | CMP_STOP;
155 }
156 break;
158 if (strncmp(left_obj->base->name, right_key, strlen(right_key)) == 0) {
159 cmp = CMP_MATCH;
160 }
161 break;
162 default:
163 cmp = 0;
164 break;
165 }
166
167 return cmp;
168}
169
170static int cli_message_to_snapshot(void *obj, void *arg, int flags)
171{
172 struct ast_channel_snapshot *snapshot = obj;
173 struct ao2_container *snapshots = arg;
174
175 if (!strcmp(snapshot->base->type, "PJSIP")) {
176 ao2_link(snapshots, snapshot);
177 return CMP_MATCH;
178 }
179
180 return 0;
181}
182
183static int cli_filter_channels(void *obj, void *arg, int flags)
184{
185 struct ast_channel_snapshot *channel = obj;
186 regex_t *regexbuf = arg;
187
188 if (!regexec(regexbuf, channel->base->name, 0, NULL, 0)
189 || !regexec(regexbuf, channel->dialplan->appl, 0, NULL, 0)) {
190 return 0;
191 }
192
193 return CMP_MATCH;
194}
195
196static struct ao2_container *get_container(const char *regex, ao2_sort_fn sort_fn, ao2_callback_fn compare_fn)
197{
198 struct ao2_container *child_container;
199 regex_t regexbuf;
200 RAII_VAR(struct ao2_container *, parent_container, ast_channel_cache_by_name(), ao2_cleanup);
201
202 if (!parent_container) {
203 return NULL;
204 }
205
206 child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, sort_fn, compare_fn);
207 if (!child_container) {
208 return NULL;
209 }
210
211 ao2_callback(parent_container, OBJ_MULTIPLE | OBJ_NODATA, cli_message_to_snapshot, child_container);
212
213 if (!ast_strlen_zero(regex)) {
214 if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
215 ao2_ref(child_container, -1);
216 return NULL;
217 }
218 ao2_callback(child_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_channels, &regexbuf);
219 regfree(&regexbuf);
220 }
221
222 return child_container;
223}
224
226{
228}
229
231{
233}
234
235static const char *cli_channel_get_id(const void *obj)
236{
237 const struct ast_channel_snapshot *snapshot = obj;
238
239 return snapshot->base->name;
240}
241
242static void *cli_channel_retrieve_by_id(const char *id)
243{
245}
246
247static int cli_channel_print_header(void *obj, void *arg, int flags)
248{
249 struct ast_sip_cli_context *context = arg;
250 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
251 int filler = CLI_LAST_TABSTOP - indent - 13;
252
253 ast_assert(context->output_buffer != NULL);
254
255 ast_str_append(&context->output_buffer, 0,
256 "%*s: <ChannelId%*.*s> <State.....> <Time.....>\n",
257 indent, "Channel", filler, filler, CLI_HEADER_FILLER);
258 if (context->recurse) {
259 context->indent_level++;
260 indent = CLI_INDENT_TO_SPACES(context->indent_level);
261 filler = CLI_LAST_TABSTOP - indent - 38;
262 ast_str_append(&context->output_buffer, 0,
263 "%*s: <DialedExten%*.*s> CLCID: <ConnectedLineCID.......>\n",
264 indent, "Exten", filler, filler, CLI_HEADER_FILLER);
265 context->indent_level--;
266 }
267
268 return 0;
269}
270
271static int cli_channel_print_body(void *obj, void *arg, int flags)
272{
273 const struct ast_channel_snapshot *snapshot = obj;
274 struct ast_sip_cli_context *context = arg;
275 char *print_name = NULL;
276 int print_name_len;
277 int indent;
278 int flexwidth;
279 char *print_time = alloca(32);
280
281 ast_assert(context->output_buffer != NULL);
282
283 print_name_len = strlen(snapshot->base->name) + strlen(snapshot->dialplan->appl) + 2;
284 print_name = alloca(print_name_len);
285
286 /* Append the application */
287 snprintf(print_name, print_name_len, "%s/%s", snapshot->base->name, snapshot->dialplan->appl);
288
289 indent = CLI_INDENT_TO_SPACES(context->indent_level);
290 flexwidth = CLI_LAST_TABSTOP - indent;
291
292 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->base->creationtime.tv_sec, print_time, 32);
293
294 ast_str_append(&context->output_buffer, 0, "%*s: %-*.*s %-12.12s %-11.11s\n",
295 CLI_INDENT_TO_SPACES(context->indent_level), "Channel",
296 flexwidth, flexwidth,
297 print_name,
298 ast_state2str(snapshot->state),
299 print_time);
300
301 if (context->recurse) {
302 context->indent_level++;
303 indent = CLI_INDENT_TO_SPACES(context->indent_level);
304 flexwidth = CLI_LAST_TABSTOP - indent - 25;
305
306 ast_str_append(&context->output_buffer, 0,
307 "%*s: %-*.*s CLCID: \"%s\" <%s>\n",
308 indent, "Exten",
309 flexwidth, flexwidth,
310 snapshot->dialplan->exten,
311 snapshot->connected->name,
312 snapshot->connected->number
313 );
314 context->indent_level--;
315 if (context->indent_level == 0) {
316 ast_str_append(&context->output_buffer, 0, "\n");
317 }
318 }
319
320 return 0;
321}
322
323static int cli_channelstats_print_header(void *obj, void *arg, int flags)
324{
325 struct ast_sip_cli_context *context = arg;
326
327 ast_assert(context->output_buffer != NULL);
328
329 ast_str_append(&context->output_buffer, 0,
330 " ...........Receive......... .........Transmit..........\n"
331 " BridgeId ChannelId ........ UpTime.. Codec. Count Lost Pct Jitter Count Lost Pct Jitter RTT....\n"
332 " =================");
333
334 return 0;
335}
336
337static int cli_channelstats_print_body(void *obj, void *arg, int flags)
338{
339 struct ast_sip_cli_context *context = arg;
340 const struct ast_channel_snapshot *snapshot = obj;
342 struct ast_sip_channel_pvt *cpvt = NULL;
343 struct ast_sip_session *session;
344 struct ast_sip_session_media *media;
345 struct ast_rtp_instance_stats stats;
346 struct ast_stream *stream;
347 char *print_name = NULL;
348 char *print_time = alloca(32);
349 char codec_in_use[7];
350 int stats_res = -1;
351
352 ast_assert(context->output_buffer != NULL);
353
354 if (!channel) {
355 ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
356 return 0;
357 }
358
359 ast_channel_lock(channel);
360
361 cpvt = ast_channel_tech_pvt(channel);
362 session = cpvt ? cpvt->session : NULL;
363
364 if (!session
365 || !session->active_media_state
366 || !session->active_media_state->topology) {
367 ast_str_append(&context->output_buffer, 0, " %s not valid\n", snapshot->base->name);
368 ast_channel_unlock(channel);
369 ao2_cleanup(channel);
370 return 0;
371 }
372
374 session->active_media_state->topology, AST_MEDIA_TYPE_AUDIO);
375
376 if (!stream) {
377 ast_str_append(&context->output_buffer, 0, " %s no audio streams\n", snapshot->base->name);
378 ast_channel_unlock(channel);
379 ao2_cleanup(channel);
380 return 0;
381 }
382
383 media = session->active_media_state->default_session[AST_MEDIA_TYPE_AUDIO];
384 if (!media || media->type != AST_MEDIA_TYPE_AUDIO || !media->rtp) {
385 ast_str_append(&context->output_buffer, 0, " %s corrupted default audio session\n", snapshot->base->name);
386 ast_channel_unlock(channel);
387 ao2_cleanup(channel);
388 return 0;
389 }
390
391 codec_in_use[0] = '\0';
392
393 if (ast_channel_rawreadformat(channel)) {
394 ast_copy_string(codec_in_use, ast_format_get_name(ast_channel_rawreadformat(channel)), sizeof(codec_in_use));
395 }
396
397 stats_res = ast_rtp_instance_get_stats(media->rtp, &stats, AST_RTP_INSTANCE_STAT_ALL);
398 ast_channel_unlock(channel);
399
400 print_name = ast_strdupa(snapshot->base->name);
401 /* Skip the PJSIP/. We know what channel type it is and we need the space. */
402 print_name += 6;
403
404 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->base->creationtime.tv_sec, print_time, 32);
405
406 if (stats_res == -1) {
407 ast_str_append(&context->output_buffer, 0, "%s direct media\n", snapshot->base->name);
408 } else {
409 ast_str_append(&context->output_buffer, 0,
410 " %8.8s %-18.18s %-8.8s %-6.6s %6u%s %6u%s %3u %7.3f %6u%s %6u%s %3u %7.3f %7.3f\n",
411 snapshot->bridge->id,
412 print_name,
413 print_time,
414 codec_in_use,
415 stats.rxcount > 100000 ? stats.rxcount / 1000 : stats.rxcount,
416 stats.rxcount > 100000 ? "K": " ",
417 stats.rxploss > 100000 ? stats.rxploss / 1000 : stats.rxploss,
418 stats.rxploss > 100000 ? "K": " ",
419 stats.rxcount ? (stats.rxploss * 100) / stats.rxcount : 0,
420 MIN(stats.rxjitter, 999.999),
421 stats.txcount > 100000 ? stats.txcount / 1000 : stats.txcount,
422 stats.txcount > 100000 ? "K": " ",
423 stats.txploss > 100000 ? stats.txploss / 1000 : stats.txploss,
424 stats.txploss > 100000 ? "K": " ",
425 stats.txcount ? (stats.txploss * 100) / stats.txcount : 0,
426 MIN(stats.txjitter, 999.999),
427 MIN(stats.normdevrtt, 999.999)
428 );
429 }
430
431 ao2_cleanup(channel);
432
433 return 0;
434}
435
436static struct ast_cli_entry cli_commands[] = {
437 AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "List PJSIP Channels",
438 .command = "pjsip list channels",
439 .usage = "Usage: pjsip list channels [ like <pattern> ]\n"
440 " List the active PJSIP channels\n"
441 " Optional regular expression pattern is used to filter the list.\n"),
442 AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Channels",
443 .command = "pjsip show channels",
444 .usage = "Usage: pjsip show channels [ like <pattern> ]\n"
445 " List(detailed) the active PJSIP channels\n"
446 " Optional regular expression pattern is used to filter the list.\n"),
447 AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Channel",
448 .command = "pjsip show channel",
449 .usage = "Usage: pjsip show channel\n"
450 " List(detailed) the active PJSIP channel\n"),
451
452 AST_CLI_DEFINE(ast_sip_cli_traverse_objects, "Show PJSIP Channel Stats",
453 .command = "pjsip show channelstats",
454 .usage = "Usage: pjsip show channelstats [ like <pattern> ]\n"
455 " List(detailed) the active PJSIP channel stats\n"
456 " Optional regular expression pattern is used to filter the list.\n"),
457};
458
461
463{
465 if (!channel_formatter) {
466 ast_log(LOG_ERROR, "Unable to allocate memory for channel_formatter\n");
467 return -1;
468 }
469 channel_formatter->name = "channel";
476
480 ast_log(LOG_ERROR, "Unable to allocate memory for channelstats_formatter\n");
481 return -1;
482 }
483 channelstats_formatter->name = "channelstat";
490
494
495 return 0;
496}
497
499{
503}
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_log
Definition: astobj2.c:42
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
Definition: astobj2.h:1226
int() ao2_sort_fn(const void *obj_left, const void *obj_right, int flags)
Type of generic container sort function.
Definition: astobj2.h:1276
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition: astobj2.h:1116
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition: astobj2.h:1087
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_SEARCH_MASK
Search option field mask.
Definition: astobj2.h:1072
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
PJSIP Channel Driver shared data structures.
General Asterisk PBX channel definitions.
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
const char * ast_state2str(enum ast_channel_state state)
Gives the string form of a given channel state.
Definition: channel.c:636
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define ast_channel_unlock(chan)
Definition: channel.h:2923
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static int cli_message_to_snapshot(void *obj, void *arg, int flags)
Definition: cli_commands.c:170
static int cli_channelstats_print_header(void *obj, void *arg, int flags)
Definition: cli_commands.c:323
static struct ast_cli_entry cli_commands[]
Definition: cli_commands.c:436
static int cli_channelstats_print_body(void *obj, void *arg, int flags)
Definition: cli_commands.c:337
static const char * cli_channel_get_id(const void *obj)
Definition: cli_commands.c:235
static int cli_channel_print_header(void *obj, void *arg, int flags)
Definition: cli_commands.c:247
static int cli_channelstats_iterate(void *endpoint, ao2_callback_fn callback, void *arg)
Definition: cli_commands.c:50
static struct ao2_container * cli_channelstats_get_container(const char *regex)
Definition: cli_commands.c:230
static int cli_channelstats_compare(void *obj, void *arg, int flags)
Definition: cli_commands.c:138
struct ast_sip_cli_formatter_entry * channelstats_formatter
Definition: cli_commands.c:459
int pjsip_channel_cli_register(void)
Registers the channel cli commands.
Definition: cli_commands.c:462
static struct ao2_container * get_container(const char *regex, ao2_sort_fn sort_fn, ao2_callback_fn compare_fn)
Definition: cli_commands.c:196
static int cli_channel_compare(void *obj, void *arg, int flags)
Definition: cli_commands.c:109
struct ast_sip_cli_formatter_entry * channel_formatter
Definition: cli_commands.c:460
static int cli_channel_sort(const void *obj, const void *arg, int flags)
Definition: cli_commands.c:55
static int cli_channelstats_sort(const void *obj, const void *arg, int flags)
Definition: cli_commands.c:80
static int cli_channel_iterate(void *endpoint, ao2_callback_fn callback, void *arg)
Definition: cli_commands.c:45
void pjsip_channel_cli_unregister(void)
Unregisters the channel cli commands.
Definition: cli_commands.c:498
static int cli_filter_channels(void *obj, void *arg, int flags)
Definition: cli_commands.c:183
static struct ao2_container * cli_channel_get_container(const char *regex)
Definition: cli_commands.c:225
static void * cli_channel_retrieve_by_id(const char *id)
Definition: cli_commands.c:242
static int cli_channel_print_body(void *obj, void *arg, int flags)
Definition: cli_commands.c:271
PJSIP CLI functions header file.
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
Media Format API.
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
struct ast_channel_snapshot * ast_channel_snapshot_get_latest_by_name(const char *name)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
struct ao2_container * ast_channel_cache_by_name(void)
Secondary channel cache, indexed by name.
#define LOG_ERROR
int ast_sip_for_each_channel(const struct ast_sip_endpoint *endpoint, ao2_callback_fn on_channel_snapshot, void *arg)
For every channel snapshot on an endpoint all the given 'on_channel_snapshot' handler.
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
Definition: pjsip_cli.c:326
#define CLI_HEADER_FILLER
Definition: res_pjsip_cli.h:24
#define CLI_LAST_TABSTOP
Definition: res_pjsip_cli.h:27
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: pjsip_cli.c:109
#define CLI_INDENT_TO_SPACES(x)
Definition: res_pjsip_cli.h:29
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
Definition: pjsip_cli.c:310
#define NULL
Definition: resample.c:96
@ AST_RTP_INSTANCE_STAT_ALL
Definition: rtp_engine.h:184
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2459
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
struct ast_stream * ast_stream_topology_get_first_stream_by_type(const struct ast_stream_topology *topology, enum ast_media_type type)
Gets the first active stream of a specific type from the topology.
Definition: stream.c:964
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Generic container type.
const ast_string_field type
const ast_string_field name
const ast_string_field exten
const ast_string_field appl
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_connected * connected
struct ast_channel_snapshot_dialplan * dialplan
struct ast_channel_snapshot_bridge * bridge
struct ast_channel_snapshot_base * base
enum ast_channel_state state
struct ast_flags flags
Main Channel structure associated with a channel.
struct ast_channel_snapshot * snapshot
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
unsigned int rxcount
Definition: rtp_engine.h:395
unsigned int rxploss
Definition: rtp_engine.h:419
unsigned int txcount
Definition: rtp_engine.h:393
unsigned int txploss
Definition: rtp_engine.h:417
A structure which contains a channel implementation and session.
struct ast_sip_session * session
Pointer to session.
CLI Formatter Context passed to all formatters.
Definition: res_pjsip_cli.h:34
CLI Formatter Registry Entry.
Definition: res_pjsip_cli.h:52
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Definition: res_pjsip_cli.h:66
ao2_callback_fn * print_header
Definition: res_pjsip_cli.h:60
void *(* retrieve_by_id)(const char *id)
Definition: res_pjsip_cli.h:68
const char *(* get_id)(const void *obj)
Definition: res_pjsip_cli.h:70
const char * name
Definition: res_pjsip_cli.h:58
ao2_callback_fn * print_body
Definition: res_pjsip_cli.h:62
struct ao2_container *(* get_container)(const char *regex)
Definition: res_pjsip_cli.h:64
A structure containing SIP session media information.
enum ast_media_type type
Media type of this session media.
struct ast_rtp_instance * rtp
RTP instance itself.
A structure describing a SIP session.
Time-related functions and macros.
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: utils.c:2297
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
char * usage
Definition: utils/frame.c:37
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739
#define MIN(a, b)
Definition: utils.h:231
#define ARRAY_LEN(a)
Definition: utils.h:666