Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Functions | Variables
func_frame_trace.c File Reference

Trace internal ast_frames on a channel. More...

#include "asterisk.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/framehook.h"
Include dependency graph for func_frame_trace.c:

Go to the source code of this file.

Data Structures

struct  frame_trace_data
 

Functions

 AST_MODULE_INFO_STANDARD_EXTENDED (ASTERISK_GPL_KEY, "Frame Trace for internal ast_frame debugging.")
 
static void datastore_destroy_cb (void *data)
 
static int frame_trace_helper (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 
static void hook_destroy_cb (void *framedata)
 
static struct ast_framehook_event_cb (struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
 
static int load_module (void)
 
static void print_frame (struct ast_frame *frame)
 
static int unload_module (void)
 

Variables

static const struct ast_datastore_info frame_trace_datastore
 
static struct ast_custom_function frame_trace_function
 
struct {
   const char *   str
 
   enum ast_frame_type   type
 
frametype2str []
 

Detailed Description

Trace internal ast_frames on a channel.

Author
David Vossel dvoss.nosp@m.el@d.nosp@m.igium.nosp@m..com

Definition in file func_frame_trace.c.

Function Documentation

◆ AST_MODULE_INFO_STANDARD_EXTENDED()

AST_MODULE_INFO_STANDARD_EXTENDED ( ASTERISK_GPL_KEY  ,
"Frame Trace for internal ast_frame debugging."   
)

Referenced by load_module().

◆ datastore_destroy_cb()

static void datastore_destroy_cb ( void *  data)
static

Definition at line 104 of file func_frame_trace.c.

References ast_free.

104  {
105  ast_free(data);
106 }
#define ast_free(a)
Definition: astmm.h:182

◆ frame_trace_helper()

static int frame_trace_helper ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Definition at line 149 of file func_frame_trace.c.

References ARRAY_LEN, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_framehook_attach(), ast_framehook_detach(), AST_FRAMEHOOK_INTERFACE_VERSION, ast_log, ast_datastore::data, ast_framehook_interface::data, frametype2str, hook_destroy_cb(), hook_event_cb(), id, frame_trace_data::list_type, LOG_WARNING, NULL, str, strcasestr(), frame_trace_data::values, and ast_framehook_interface::version.

150 {
151  struct frame_trace_data *framedata;
152  struct ast_datastore *datastore = NULL;
153  struct ast_framehook_interface interface = {
155  .event_cb = hook_event_cb,
156  .destroy_cb = hook_destroy_cb,
157  };
158  int i = 0;
159 
160  if (!chan) {
161  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
162  return -1;
163  }
164 
165  if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
166  return 0;
167  }
168 
169  interface.data = framedata;
170 
171  if (!strcasecmp(data, "black")) {
172  framedata->list_type = 1;
173  }
174  for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
175  if (strcasestr(value, frametype2str[i].str)) {
176  framedata->values[i] = 1;
177  }
178  }
179 
180  ast_channel_lock(chan);
181  i = ast_framehook_attach(chan, &interface);
182  if (i >= 0) {
183  int *id;
184  if ((datastore = ast_channel_datastore_find(chan, &frame_trace_datastore, NULL))) {
185  id = datastore->data;
186  ast_framehook_detach(chan, *id);
187  ast_channel_datastore_remove(chan, datastore);
188  ast_datastore_free(datastore);
189  }
190 
191  if (!(datastore = ast_datastore_alloc(&frame_trace_datastore, NULL))) {
192  ast_framehook_detach(chan, i);
193  ast_channel_unlock(chan);
194  return 0;
195  }
196 
197  if (!(id = ast_calloc(1, sizeof(int)))) {
198  ast_datastore_free(datastore);
199  ast_framehook_detach(chan, i);
200  ast_channel_unlock(chan);
201  return 0;
202  }
203 
204  *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
205  datastore->data = id;
206  ast_channel_datastore_add(chan, datastore);
207  }
208  ast_channel_unlock(chan);
209 
210  return 0;
211 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static struct ast_frame * hook_event_cb(struct ast_channel *chan, struct ast_frame *frame, enum ast_framehook_event event, void *data)
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void hook_destroy_cb(void *framedata)
#define LOG_WARNING
Definition: logger.h:274
int ast_framehook_detach(struct ast_channel *chan, int framehook_id)
Detach an framehook from a channel.
Definition: framehook.c:177
Structure for a data store object.
Definition: datastore.h:68
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.
Definition: channel.c:2404
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
static struct @209 frametype2str[]
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
int ast_framehook_attach(struct ast_channel *chan, struct ast_framehook_interface *i)
Attach an framehook onto a channel for frame interception.
Definition: framehook.c:132
#define ast_log
Definition: astobj2.c:42
int values[ARRAY_LEN(frametype2str)]
#define AST_FRAMEHOOK_INTERFACE_VERSION
Definition: framehook.h:227
char * strcasestr(const char *, const char *)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
const char * str
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
enum queue_result id
Definition: app_queue.c:1507
static const struct ast_datastore_info frame_trace_datastore
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2399

◆ hook_destroy_cb()

static void hook_destroy_cb ( void *  framedata)
static

Definition at line 113 of file func_frame_trace.c.

References ast_free.

Referenced by frame_trace_helper().

114 {
115  ast_free(framedata);
116 }
#define ast_free(a)
Definition: astmm.h:182

◆ hook_event_cb()

static struct ast_frame* hook_event_cb ( struct ast_channel chan,
struct ast_frame frame,
enum ast_framehook_event  event,
void *  data 
)
static

Definition at line 118 of file func_frame_trace.c.

References ARRAY_LEN, ast_channel_name(), AST_FRAMEHOOK_EVENT_READ, AST_FRAMEHOOK_EVENT_WRITE, ast_verbose(), ast_frame::frametype, frametype2str, frame_trace_data::list_type, print_frame(), show_frame(), and frame_trace_data::values.

Referenced by frame_trace_helper().

119 {
120  int i;
121  int show_frame = 0;
122  struct frame_trace_data *framedata = data;
123  if (!frame) {
124  return frame;
125  }
126 
128  return frame;
129  }
130 
131  for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
132  if (frame->frametype == frametype2str[i].type) {
133  if ((framedata->list_type == 0) && (framedata->values[i])) { /* white list */
134  show_frame = 1;
135  } else if ((framedata->list_type == 1) && (!framedata->values[i])){ /* black list */
136  show_frame = 1;
137  }
138  break;
139  }
140  }
141 
142  if (show_frame) {
143  ast_verbose("%s on Channel %s\n", event == AST_FRAMEHOOK_EVENT_READ ? "<--Read" : "--> Write", ast_channel_name(chan));
144  print_frame(frame);
145  }
146  return frame;
147 }
static void print_frame(struct ast_frame *frame)
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
Definition: astman.c:222
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
static struct @209 frametype2str[]
static void show_frame(struct video_desc *env, int out)
Definition: console_gui.c:98
int values[ARRAY_LEN(frametype2str)]
const char * ast_channel_name(const struct ast_channel *chan)
enum ast_frame_type frametype

◆ load_module()

static int load_module ( void  )
static

Definition at line 440 of file func_frame_trace.c.

References ast_custom_function_register, AST_MODULE_INFO_STANDARD_EXTENDED(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and ASTERISK_GPL_KEY.

441 {
444 }
static struct ast_custom_function frame_trace_function
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508

◆ print_frame()

static void print_frame ( struct ast_frame frame)
static

Definition at line 213 of file func_frame_trace.c.

References _XXX_AST_CONTROL_T38, ast_assert, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_MASQUERADE_NOTIFY, AST_CONTROL_MCID, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_RECORD_CANCEL, AST_CONTROL_RECORD_MUTE, AST_CONTROL_RECORD_STOP, AST_CONTROL_RECORD_SUSPEND, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_STREAM_FORWARD, AST_CONTROL_STREAM_RESTART, AST_CONTROL_STREAM_REVERSE, AST_CONTROL_STREAM_STOP, AST_CONTROL_STREAM_SUSPEND, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, AST_CONTROL_STREAM_TOPOLOGY_REQUEST_CHANGE, AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_format_get_name(), AST_FRAME_BRIDGE_ACTION, AST_FRAME_BRIDGE_ACTION_SYNC, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_RTCP, AST_FRAME_TEXT, AST_FRAME_TEXT_DATA, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_strlen_zero, ast_verbose(), ast_frame::datalen, ast_frame_subclass::format, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::len, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

Referenced by hook_event_cb().

214 {
215  switch (frame->frametype) {
216  case AST_FRAME_DTMF_END:
217  ast_verbose("FrameType: DTMF END\n");
218  ast_verbose("Digit: 0x%02X '%c'\n", (unsigned)frame->subclass.integer,
219  frame->subclass.integer < ' ' ? ' ' : frame->subclass.integer);
220  break;
221  case AST_FRAME_VOICE:
222  ast_verbose("FrameType: VOICE\n");
223  ast_verbose("Codec: %s\n", ast_format_get_name(frame->subclass.format));
224  ast_verbose("MS: %ld\n", frame->len);
225  ast_verbose("Samples: %d\n", frame->samples);
226  ast_verbose("Bytes: %d\n", frame->datalen);
227  break;
228  case AST_FRAME_VIDEO:
229  ast_verbose("FrameType: VIDEO\n");
230  ast_verbose("Codec: %s\n", ast_format_get_name(frame->subclass.format));
231  ast_verbose("MS: %ld\n", frame->len);
232  ast_verbose("Samples: %d\n", frame->samples);
233  ast_verbose("Bytes: %d\n", frame->datalen);
234  break;
235  case AST_FRAME_CONTROL:
236  ast_verbose("FrameType: CONTROL\n");
237  switch ((enum ast_control_frame_type) frame->subclass.integer) {
238  case AST_CONTROL_HANGUP:
239  ast_verbose("SubClass: HANGUP\n");
240  break;
241  case AST_CONTROL_RING:
242  ast_verbose("SubClass: RING\n");
243  break;
244  case AST_CONTROL_RINGING:
245  ast_verbose("SubClass: RINGING\n");
246  break;
247  case AST_CONTROL_ANSWER:
248  ast_verbose("SubClass: ANSWER\n");
249  break;
250  case AST_CONTROL_BUSY:
251  ast_verbose("SubClass: BUSY\n");
252  break;
254  ast_verbose("SubClass: TAKEOFFHOOK\n");
255  break;
256  case AST_CONTROL_OFFHOOK:
257  ast_verbose("SubClass: OFFHOOK\n");
258  break;
260  ast_verbose("SubClass: CONGESTION\n");
261  break;
262  case AST_CONTROL_FLASH:
263  ast_verbose("SubClass: FLASH\n");
264  break;
265  case AST_CONTROL_WINK:
266  ast_verbose("SubClass: WINK\n");
267  break;
268  case AST_CONTROL_OPTION:
269  ast_verbose("SubClass: OPTION\n");
270  break;
272  ast_verbose("SubClass: RADIO KEY\n");
273  break;
275  ast_verbose("SubClass: RADIO UNKEY\n");
276  break;
278  ast_verbose("SubClass: PROGRESS\n");
279  break;
281  ast_verbose("SubClass: PROCEEDING\n");
282  break;
283  case AST_CONTROL_HOLD:
284  ast_verbose("SubClass: HOLD\n");
285  break;
286  case AST_CONTROL_UNHOLD:
287  ast_verbose("SubClass: UNHOLD\n");
288  break;
290  ast_verbose("SubClass: VIDUPDATE\n");
291  break;
293  ast_verbose("SubClass: XXX T38\n");
294  break;
296  ast_verbose("SubClass: SRCUPDATE\n");
297  break;
299  ast_verbose("SubClass: TRANSFER\n");
300  break;
302  ast_verbose("SubClass: CONNECTED LINE\n");
303  break;
305  ast_verbose("SubClass: REDIRECTING\n");
306  break;
308  ast_verbose("SubClass: T38 PARAMETERS\n");
309  break;
310  case AST_CONTROL_CC:
311  ast_verbose("SubClass: CC\n");
312  break;
314  ast_verbose("SubClass: SRCCHANGE\n");
315  break;
317  ast_verbose("SubClass: READ ACTION\n");
318  break;
319  case AST_CONTROL_AOC:
320  ast_verbose("SubClass: AOC\n");
321  break;
322  case AST_CONTROL_MCID:
323  ast_verbose("SubClass: MCID\n");
324  break;
326  ast_verbose("SubClass: INCOMPLETE\n");
327  break;
329  ast_verbose("SubClass: END_OF_Q\n");
330  break;
332  ast_verbose("SubClass: UPDATE_RTP_PEER\n");
333  break;
335  ast_verbose("SubClass: PVT_CAUSE_CODE\n");
336  break;
338  /* Should never happen. */
339  ast_assert(0);
340  break;
342  ast_verbose("SubClass: STREAM_TOPOLOGY_REQUEST_CHANGE\n");
343  break;
345  ast_verbose("SubClass: STREAM_TOPOLOGY_CHANGED\n");
346  break;
348  ast_verbose("SubClass: STREAM_TOPOLOGY_SOURCE_CHANGED\n");
349  break;
351  ast_verbose("SubClass: STREAM_STOP\n");
352  break;
354  ast_verbose("SubClass: STREAM_SUSPEND\n");
355  break;
357  ast_verbose("SubClass: STREAM_RESTART\n");
358  break;
360  ast_verbose("SubClass: STREAM_REVERSE\n");
361  break;
363  ast_verbose("SubClass: STREAM_FORWARD\n");
364  break;
366  ast_verbose("SubClass: RECORD_CANCEL\n");
367  break;
369  ast_verbose("SubClass: RECORD_STOP\n");
370  break;
372  ast_verbose("SubClass: RECORD_SUSPEND\n");
373  break;
375  ast_verbose("SubClass: RECORD_MUTE\n");
376  break;
377  }
378 
379  if (frame->subclass.integer == -1) {
380  ast_verbose("SubClass: %d\n", frame->subclass.integer);
381  }
382  ast_verbose("Bytes: %d\n", frame->datalen);
383  break;
384  case AST_FRAME_RTCP:
385  ast_verbose("FrameType: RTCP\n");
386  break;
387  case AST_FRAME_NULL:
388  ast_verbose("FrameType: NULL\n");
389  break;
390  case AST_FRAME_IAX:
391  ast_verbose("FrameType: IAX\n");
392  break;
393  case AST_FRAME_TEXT:
394  ast_verbose("FrameType: TXT\n");
395  break;
396  case AST_FRAME_TEXT_DATA:
397  ast_verbose("FrameType: TXT_DATA\n");
398  break;
399  case AST_FRAME_IMAGE:
400  ast_verbose("FrameType: IMAGE\n");
401  break;
402  case AST_FRAME_HTML:
403  ast_verbose("FrameType: HTML\n");
404  break;
405  case AST_FRAME_CNG:
406  ast_verbose("FrameType: CNG\n");
407  break;
408  case AST_FRAME_MODEM:
409  ast_verbose("FrameType: MODEM\n");
410  break;
412  ast_verbose("FrameType: DTMF BEGIN\n");
413  ast_verbose("Digit: 0x%02X '%c'\n", (unsigned)frame->subclass.integer,
414  frame->subclass.integer < ' ' ? ' ' : frame->subclass.integer);
415  break;
417  ast_verbose("FrameType: Bridge\n");
418  ast_verbose("SubClass: %d\n", frame->subclass.integer);
419  break;
421  ast_verbose("Frametype: Synchronous Bridge\n");
422  ast_verbose("Subclass: %d\n", frame->subclass.integer);
423  break;
424  }
425 
426  ast_verbose("Src: %s\n", ast_strlen_zero(frame->src) ? "NOT PRESENT" : frame->src);
427  ast_verbose("\n");
428 }
ast_control_frame_type
Internal control frame subtype field values.
#define ast_assert(a)
Definition: utils.h:695
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2207
struct ast_frame_subclass subclass
#define ast_strlen_zero(foo)
Definition: strings.h:52
const char * src
enum ast_frame_type frametype
struct ast_format * format

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 435 of file func_frame_trace.c.

References ast_custom_function_unregister().

436 {
438 }
static struct ast_custom_function frame_trace_function
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.

Variable Documentation

◆ frame_trace_datastore

const struct ast_datastore_info frame_trace_datastore
static
Initial value:
= {
.type = "frametrace",
}
static void datastore_destroy_cb(void *data)

Definition at line 108 of file func_frame_trace.c.

◆ frame_trace_function

struct ast_custom_function frame_trace_function
static
Initial value:
= {
.name = "FRAME_TRACE",
}
static int frame_trace_helper(struct ast_channel *chan, const char *cmd, char *data, const char *value)

Definition at line 430 of file func_frame_trace.c.

◆ frametype2str

struct { ... } frametype2str[]

◆ str

const char* str

Definition at line 82 of file func_frame_trace.c.

Referenced by frame_trace_helper().

◆ type

enum ast_frame_type type

Definition at line 81 of file func_frame_trace.c.