Thu Apr 28 2011 16:57:10

Asterisk developer's documentation


func_channel.c File Reference

Channel info dialplan functions. More...

#include "asterisk.h"
#include <regex.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/indications.h"
#include "asterisk/stringfields.h"
Include dependency graph for func_channel.c:

Go to the source code of this file.

Defines

#define locked_copy_string(chan, dest, source, len)
#define locked_string_field_set(chan, field, source)

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int func_channel_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
static int func_channel_write (struct ast_channel *chan, const char *function, char *data, const char *value)
static int func_channel_write_real (struct ast_channel *chan, const char *function, char *data, const char *value)
static int func_channels_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t maxlen)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Channel information dialplan functions" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_custom_function channel_function
static struct ast_custom_function channels_function
char * transfercapability_table [0x20]

Detailed Description

Channel info dialplan functions.

Author:
Kevin P. Fleming <kpfleming@digium.com>
Ben Winslow

Definition in file func_channel.c.


Define Documentation

#define locked_copy_string (   chan,
  dest,
  source,
  len 
)
Value:
do { \
      ast_channel_lock(chan); \
      ast_copy_string(dest, source, len); \
      ast_channel_unlock(chan); \
   } while (0)

Definition at line 212 of file func_channel.c.

Referenced by func_channel_read().

#define locked_string_field_set (   chan,
  field,
  source 
)
Value:
do { \
      ast_channel_lock(chan); \
      ast_string_field_set(chan, field, source); \
      ast_channel_unlock(chan); \
   } while (0)

Definition at line 218 of file func_channel.c.

Referenced by func_channel_write_real().


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 436 of file func_channel.c.

static void __unreg_module ( void  ) [static]

Definition at line 436 of file func_channel.c.

static int func_channel_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 231 of file func_channel.c.

References ast_channel::_state, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), ast_print_group(), ast_state2str(), ast_channel::callgroup, ast_tone_zone::country, ast_channel_tech::func_channel_read, ast_channel::language, locked_copy_string, LOG_WARNING, ast_channel::musicclass, ast_channel::nativeformats, ast_channel::parkinglot, ast_channel::readformat, ast_channel::tech, ast_channel::transfercapability, ast_channel_tech::type, ast_channel::writeformat, and ast_channel::zone.

{
   int ret = 0;

   if (!strcasecmp(data, "audionativeformat"))
      /* use the _multiple version when chan->nativeformats holds multiple formats */
      /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_AUDIO_MASK); */
      ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_AUDIO_MASK), len);
   else if (!strcasecmp(data, "videonativeformat"))
      /* use the _multiple version when chan->nativeformats holds multiple formats */
      /* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_VIDEO_MASK); */
      ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_VIDEO_MASK), len);
   else if (!strcasecmp(data, "audioreadformat"))
      ast_copy_string(buf, ast_getformatname(chan->readformat), len);
   else if (!strcasecmp(data, "audiowriteformat"))
      ast_copy_string(buf, ast_getformatname(chan->writeformat), len);
#ifdef CHANNEL_TRACE
   else if (!strcasecmp(data, "trace")) {
      ast_channel_lock(chan);
      ast_copy_string(buf, ast_channel_trace_is_enabled(chan) ? "1" : "0", len);
      ast_channel_unlock(chan);
   }
#endif
   else if (!strcasecmp(data, "tonezone") && chan->zone)
      locked_copy_string(chan, buf, chan->zone->country, len);
   else if (!strcasecmp(data, "language"))
      locked_copy_string(chan, buf, chan->language, len);
   else if (!strcasecmp(data, "musicclass"))
      locked_copy_string(chan, buf, chan->musicclass, len);
   else if (!strcasecmp(data, "parkinglot"))
      locked_copy_string(chan, buf, chan->parkinglot, len);
   else if (!strcasecmp(data, "state"))
      locked_copy_string(chan, buf, ast_state2str(chan->_state), len);
   else if (!strcasecmp(data, "channeltype"))
      locked_copy_string(chan, buf, chan->tech->type, len);
   else if (!strcasecmp(data, "transfercapability"))
      locked_copy_string(chan, buf, transfercapability_table[chan->transfercapability & 0x1f], len);
   else if (!strcasecmp(data, "callgroup")) {
      char groupbuf[256];
      locked_copy_string(chan, buf,  ast_print_group(groupbuf, sizeof(groupbuf), chan->callgroup), len);
   } else if (!chan->tech->func_channel_read
       || chan->tech->func_channel_read(chan, function, data, buf, len)) {
      ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n", data);
      ret = -1;
   }

   return ret;
}
static int func_channel_write ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
) [static]

Definition at line 347 of file func_channel.c.

References AST_CHAN_WRITE_INFO_T_VERSION, ast_channel_setoption(), AST_OPTION_CHANNEL_WRITE, chan, ast_channel::data, func_channel_write_real(), and ast_chan_write_info_t::version.

{
   int res;
   ast_chan_write_info_t write_info = {
      .version = AST_CHAN_WRITE_INFO_T_VERSION,
      .write_fn = func_channel_write_real,
      .chan = chan,
      .function = function,
      .data = data,
      .value = value,
   };

   res = func_channel_write_real(chan, function, data, value);
   ast_channel_setoption(chan, AST_OPTION_CHANNEL_WRITE, &write_info, sizeof(write_info), 0);

   return res;
}
static int func_channel_write_real ( struct ast_channel chan,
const char *  function,
char *  data,
const char *  value 
) [static]

Definition at line 281 of file func_channel.c.

References ast_channel_lock, ast_channel_setoption(), ast_channel_unlock, ast_false(), ast_get_group(), ast_get_indication_zone(), ast_log(), AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_tone_zone_ref(), ast_tone_zone_unref(), ast_true(), ast_channel::callgroup, ast_channel_tech::func_channel_write, language, locked_string_field_set, LOG_ERROR, LOG_WARNING, musicclass, parkinglot, ast_channel::tech, ast_channel::transfercapability, and ast_channel::zone.

Referenced by func_channel_write().

{
   int ret = 0;
   signed char gainset;

   if (!strcasecmp(data, "language"))
      locked_string_field_set(chan, language, value);
   else if (!strcasecmp(data, "parkinglot"))
      locked_string_field_set(chan, parkinglot, value);
   else if (!strcasecmp(data, "musicclass"))
      locked_string_field_set(chan, musicclass, value);
#ifdef CHANNEL_TRACE
   else if (!strcasecmp(data, "trace")) {
      ast_channel_lock(chan);
      if (ast_true(value)) 
         ret = ast_channel_trace_enable(chan);
      else if (ast_false(value)) 
         ret = ast_channel_trace_disable(chan);
      else {
         ret = -1;
         ast_log(LOG_WARNING, "Invalid value for CHANNEL(trace).");
      }
      ast_channel_unlock(chan);
   }
#endif
   else if (!strcasecmp(data, "tonezone")) {
      struct ast_tone_zone *new_zone;
      if (!(new_zone = ast_get_indication_zone(value))) {
         ast_log(LOG_ERROR, "Unknown country code '%s' for tonezone. Check indications.conf for available country codes.\n", value);
         ret = -1;   
      } else {
         ast_channel_lock(chan);
         if (chan->zone) {
            chan->zone = ast_tone_zone_unref(chan->zone);
         }
         chan->zone = ast_tone_zone_ref(new_zone);
         ast_channel_unlock(chan);
         new_zone = ast_tone_zone_unref(new_zone);
      }
   } else if (!strcasecmp(data, "callgroup"))
      chan->callgroup = ast_get_group(value);
   else if (!strcasecmp(data, "txgain")) {
      sscanf(value, "%4hhd", &gainset);
      ast_channel_setoption(chan, AST_OPTION_TXGAIN, &gainset, sizeof(gainset), 0);
   } else if (!strcasecmp(data, "rxgain")) {
      sscanf(value, "%4hhd", &gainset);
      ast_channel_setoption(chan, AST_OPTION_RXGAIN, &gainset, sizeof(gainset), 0);
   } else if (!strcasecmp(data, "transfercapability")) {
      unsigned short i;
      for (i = 0; i < 0x20; i++) {
         if (!strcasecmp(transfercapability_table[i], value) && strcmp(value, "UNK")) {
            chan->transfercapability = i;
            break;
         }
      }
   } else if (!chan->tech->func_channel_write
       || chan->tech->func_channel_write(chan, function, data, value)) {
      ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
            data);
      ret = -1;
   }

   return ret;
}
static int func_channels_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  maxlen 
) [static]

Definition at line 371 of file func_channel.c.

References ast_channel_unlock, ast_channel_walk_locked(), ast_log(), ast_strlen_zero(), LOG_WARNING, and ast_channel::name.

{
   struct ast_channel *c = NULL;
   regex_t re;
   int res;
   size_t buflen = 0;
   
   buf[0] = '\0';

   if (!ast_strlen_zero(data)) {
      if ((res = regcomp(&re, data, REG_EXTENDED | REG_ICASE | REG_NOSUB))) {
         regerror(res, &re, buf, maxlen);
         ast_log(LOG_WARNING, "Error compiling regular expression for %s(%s): %s\n", function, data, buf);
         return -1;
      }
   }

   for (c = ast_channel_walk_locked(NULL); c; ast_channel_unlock(c), c = ast_channel_walk_locked(c)) {
      if (ast_strlen_zero(data) || regexec(&re, c->name, 0, NULL, 0) == 0) {
         size_t namelen = strlen(c->name);
         if (buflen + namelen + (ast_strlen_zero(buf) ? 0 : 1) + 1 < maxlen) {
            if (!ast_strlen_zero(buf)) {
               strcat(buf, " ");
               buflen++;
            }
            strcat(buf, c->name);
            buflen += namelen;
         } else {
            ast_log(LOG_WARNING, "Number of channels exceeds the available buffer space.  Output will be truncated!\n");
         }
      }
   }

   if (!ast_strlen_zero(data)) {
      regfree(&re);
   }

   return 0;
}
static int load_module ( void  ) [static]

Definition at line 426 of file func_channel.c.

References ast_custom_function_register.

static int unload_module ( void  ) [static]

Definition at line 416 of file func_channel.c.

References ast_custom_function_unregister().


Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Channel information dialplan functions" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 436 of file func_channel.c.

Definition at line 436 of file func_channel.c.

Initial value:
 {
   .name = "CHANNEL",
   .read = func_channel_read,
   .write = func_channel_write,
}

Definition at line 365 of file func_channel.c.

Initial value:
 {
   .name = "CHANNELS",
   .read = func_channels_read,
}

Definition at line 411 of file func_channel.c.

Initial value:
 {
   "SPEECH", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
   "DIGITAL", "RESTRICTED_DIGITAL", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
   "3K1AUDIO", "DIGITAL_W_TONES", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK",
   "VIDEO", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", "UNK", }

Definition at line 225 of file func_channel.c.