Mon Mar 12 2012 21:39:55

Asterisk developer's documentation


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

static void __reg_module (void)
static void __unreg_module (void)
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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Frame Trace for internal ast_frame debugging." , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static struct ast_module_infoast_module_info = &__mod_info
static 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 <dvossel@digium.com>

Definition in file func_frame_trace.c.


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 378 of file func_frame_trace.c.

static void __unreg_module ( void  ) [static]

Definition at line 378 of file func_frame_trace.c.

static void datastore_destroy_cb ( void *  data) [static]

Definition at line 104 of file func_frame_trace.c.

References ast_free.

                                             {
   ast_free(data);
}
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_datastore::data, ast_framehook_interface::data, frametype2str, hook_destroy_cb(), hook_event_cb(), id, frame_trace_data::list_type, str, strcasestr(), frame_trace_data::values, and ast_framehook_interface::version.

{
   struct frame_trace_data *framedata;
   struct ast_datastore *datastore = NULL;
   struct ast_framehook_interface interface = {
      .version = AST_FRAMEHOOK_INTERFACE_VERSION,
      .event_cb = hook_event_cb,
      .destroy_cb = hook_destroy_cb,
   };
   int i = 0;

   if (!(framedata = ast_calloc(1, sizeof(*framedata)))) {
      return 0;
   }

   interface.data = framedata;

   if (!strcasecmp(data, "black")) {
      framedata->list_type = 1;
   }
   for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
      if (strcasestr(value, frametype2str[i].str)) {
         framedata->values[i] = 1;
      }
   }

   ast_channel_lock(chan);
   i = ast_framehook_attach(chan, &interface);
   if (i >= 0) {
      int *id;
      if ((datastore = ast_channel_datastore_find(chan, &frame_trace_datastore, NULL))) {
         id = datastore->data;
         ast_framehook_detach(chan, *id);
         ast_channel_datastore_remove(chan, datastore);
      }

      if (!(datastore = ast_datastore_alloc(&frame_trace_datastore, NULL))) {
         ast_framehook_detach(chan, i);
         ast_channel_unlock(chan);
         return 0;
      }

      if (!(id = ast_calloc(1, sizeof(int)))) {
         ast_datastore_free(datastore);
         ast_framehook_detach(chan, i);
         ast_channel_unlock(chan);
         return 0;
      }

      *id = i; /* Store off the id. The channel is still locked so it is safe to access this ptr. */
      datastore->data = id;
      ast_channel_datastore_add(chan, datastore);
   }
   ast_channel_unlock(chan);

   return 0;
}
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().

{
   ast_free(framedata);
}
static struct ast_frame* hook_event_cb ( struct ast_channel chan,
struct ast_frame frame,
enum ast_framehook_event  event,
void *  data 
) [static, read]

Definition at line 118 of file func_frame_trace.c.

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

Referenced by frame_trace_helper().

{
   int i;
   int show_frame = 0;
   struct frame_trace_data *framedata = data;
   if (!frame) {
      return frame;
   }

   if ((event != AST_FRAMEHOOK_EVENT_WRITE) && (event != AST_FRAMEHOOK_EVENT_READ)) {
      return frame;
   }

   for (i = 0; i < ARRAY_LEN(frametype2str); i++) {
      if (frame->frametype == frametype2str[i].type) {
         if ((framedata->list_type == 0) && (framedata->values[i])) { /* white list */
            show_frame = 1;
         } else if ((framedata->list_type == 1) && (!framedata->values[i])){ /* black list */
            show_frame = 1;
         }
         break;
      }
   }

   if (show_frame) {
      ast_verbose("%s on Channel %s\n", event == AST_FRAMEHOOK_EVENT_READ ? "<--Read" : "--> Write", chan->name);
      print_frame(frame);
   }
   return frame;
}
static int load_module ( void  ) [static]
static void print_frame ( struct ast_frame frame) [static]

Definition at line 207 of file func_frame_trace.c.

References _XXX_AST_CONTROL_T38, 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_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, 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_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_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_strlen_zero(), ast_verbose(), ast_frame_subclass::codec, ast_frame::datalen, 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().

{
   switch (frame->frametype) {
   case AST_FRAME_DTMF_END:
      ast_verbose("FrameType: DTMF END\n");
      ast_verbose("Digit: %d\n", frame->subclass.integer);
      break;
   case AST_FRAME_VOICE:
      ast_verbose("FrameType: VOICE\n");
      ast_verbose("Codec: %s\n", ast_getformatname(frame->subclass.codec));
      ast_verbose("MS: %ld\n", frame->len);
      ast_verbose("Samples: %d\n", frame->samples);
      ast_verbose("Bytes: %d\n", frame->datalen);
      break;
   case AST_FRAME_VIDEO:
      ast_verbose("FrameType: VIDEO\n");
      ast_verbose("Codec: %s\n", ast_getformatname(frame->subclass.codec));
      ast_verbose("MS: %ld\n", frame->len);
      ast_verbose("Samples: %d\n", frame->samples);
      ast_verbose("Bytes: %d\n", frame->datalen);
      break;
   case AST_FRAME_CONTROL:
      ast_verbose("FrameType: CONTROL\n");
      switch ((enum ast_control_frame_type) frame->subclass.integer) {
      case AST_CONTROL_HANGUP:
         ast_verbose("SubClass: HANGUP\n");
         break;
      case AST_CONTROL_RING:
         ast_verbose("SubClass: RING\n");
         break;
      case AST_CONTROL_RINGING:
         ast_verbose("SubClass: RINGING\n");
         break;
      case AST_CONTROL_ANSWER:
         ast_verbose("SubClass: ANSWER\n");
         break;
      case AST_CONTROL_BUSY:
         ast_verbose("SubClass: BUSY\n");
         break;
      case AST_CONTROL_TAKEOFFHOOK:
         ast_verbose("SubClass: TAKEOFFHOOK\n");
         break;
      case AST_CONTROL_OFFHOOK:
         ast_verbose("SubClass: OFFHOOK\n");
         break;
      case AST_CONTROL_CONGESTION:
         ast_verbose("SubClass: CONGESTION\n");
         break;
      case AST_CONTROL_FLASH:
         ast_verbose("SubClass: FLASH\n");
         break;
      case AST_CONTROL_WINK:
         ast_verbose("SubClass: WINK\n");
         break;
      case AST_CONTROL_OPTION:
         ast_verbose("SubClass: OPTION\n");
         break;
      case AST_CONTROL_RADIO_KEY:
         ast_verbose("SubClass: RADIO KEY\n");
         break;
      case AST_CONTROL_RADIO_UNKEY:
         ast_verbose("SubClass: RADIO UNKEY\n");
         break;
      case AST_CONTROL_PROGRESS:
         ast_verbose("SubClass: PROGRESS\n");
         break;
      case AST_CONTROL_PROCEEDING:
         ast_verbose("SubClass: PROCEEDING\n");
         break;
      case AST_CONTROL_HOLD:
         ast_verbose("SubClass: HOLD\n");
         break;
      case AST_CONTROL_UNHOLD:
         ast_verbose("SubClass: UNHOLD\n");
         break;
      case AST_CONTROL_VIDUPDATE:
         ast_verbose("SubClass: VIDUPDATE\n");
         break;
      case _XXX_AST_CONTROL_T38:
         ast_verbose("SubClass: XXX T38\n");
         break;
      case AST_CONTROL_SRCUPDATE:
         ast_verbose("SubClass: SRCUPDATE\n");
         break;
      case AST_CONTROL_TRANSFER:
         ast_verbose("SubClass: TRANSFER\n");
         break;
      case AST_CONTROL_CONNECTED_LINE:
         ast_verbose("SubClass: CONNECTED LINE\n");
         break;
      case AST_CONTROL_REDIRECTING:
         ast_verbose("SubClass: REDIRECTING\n");
         break;
      case AST_CONTROL_T38_PARAMETERS:
         ast_verbose("SubClass: T38 PARAMETERS\n");
         break;
      case AST_CONTROL_CC:
         ast_verbose("SubClass: CC\n");
         break;
      case AST_CONTROL_SRCCHANGE:
         ast_verbose("SubClass: SRCCHANGE\n");
         break;
      case AST_CONTROL_READ_ACTION:
         ast_verbose("SubClass: READ ACTION\n");
         break;
      case AST_CONTROL_AOC:
         ast_verbose("SubClass: AOC\n");
         break;
      case AST_CONTROL_INCOMPLETE:
         ast_verbose("SubClass: INCOMPLETE\n");
         break;
      case AST_CONTROL_END_OF_Q:
         ast_verbose("SubClass: END_OF_Q\n");
         break;
      case AST_CONTROL_UPDATE_RTP_PEER:
         ast_verbose("SubClass: UPDATE_RTP_PEER\n");
         break;
      }
      
      if (frame->subclass.integer == -1) {
         ast_verbose("SubClass: %d\n", frame->subclass.integer);
      }
      ast_verbose("Bytes: %d\n", frame->datalen);
      break;
   case AST_FRAME_NULL:
      ast_verbose("FrameType: NULL\n");
      break;
   case AST_FRAME_IAX:
      ast_verbose("FrameType: IAX\n");
      break;
   case AST_FRAME_TEXT:
      ast_verbose("FrameType: TXT\n");
      break;
   case AST_FRAME_IMAGE:
      ast_verbose("FrameType: IMAGE\n");
      break;
   case AST_FRAME_HTML:
      ast_verbose("FrameType: HTML\n");
      break;
   case AST_FRAME_CNG:
      ast_verbose("FrameType: CNG\n");
      break;
   case AST_FRAME_MODEM:
      ast_verbose("FrameType: MODEM\n");
      break;
   case AST_FRAME_DTMF_BEGIN:
      ast_verbose("FrameType: DTMF BEGIN\n");
      ast_verbose("Digit: %d\n", frame->subclass.integer);
      break;
   }

   ast_verbose("Src: %s\n", ast_strlen_zero(frame->src) ? "NOT PRESENT" : frame->src);
   ast_verbose("\n");
}
static int unload_module ( void  ) [static]

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Frame Trace for internal ast_frame debugging." , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 378 of file func_frame_trace.c.

Definition at line 378 of file func_frame_trace.c.

Initial value:
 {
   .type = "frametrace",
   .destroy = datastore_destroy_cb
}

Definition at line 108 of file func_frame_trace.c.

Initial value:
 {
   .name = "FRAME_TRACE",
   .write = frame_trace_helper,
}

Definition at line 362 of file func_frame_trace.c.

struct { ... } frametype2str[] [static]
const char* str

Definition at line 83 of file func_frame_trace.c.

Definition at line 82 of file func_frame_trace.c.