Fri Jul 15 2011 11:58:56

Asterisk developer's documentation


app_directed_pickup.c File Reference

Directed Call Pickup Support. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/features.h"
Include dependency graph for app_directed_pickup.c:

Go to the source code of this file.

Data Structures

struct  pickup_criteria

Defines

#define PICKUPMARK   "PICKUPMARK"

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int can_pickup (struct ast_channel *chan)
static int find_by_exten (struct ast_channel *c, void *data)
static int find_by_group (struct ast_channel *c, void *data)
static int find_by_mark (struct ast_channel *c, void *data)
static int load_module (void)
static struct ast_channelmy_ast_get_channel_by_name_locked (const char *channame)
 Helper Function to walk through ALL channels checking NAME and STATE.
static int pickup_by_channel (struct ast_channel *chan, char *pickup)
 Attempt to pick up specified channel named , does not use context.
static int pickup_by_exten (struct ast_channel *chan, const char *exten, const char *context)
static int pickup_by_group (struct ast_channel *chan)
static int pickup_by_mark (struct ast_channel *chan, const char *mark)
static int pickup_exec (struct ast_channel *chan, void *data)
static int pickupchan_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Directed Call Pickup Application" , .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, }
static const char * app = "Pickup"
static const char * app2 = "PickupChan"
static struct ast_module_infoast_module_info = &__mod_info

Detailed Description

Directed Call Pickup Support.

Author:
Joshua Colp <jcolp@digium.com>
Gary Cook

Definition in file app_directed_pickup.c.


Define Documentation

#define PICKUPMARK   "PICKUPMARK"

Definition at line 44 of file app_directed_pickup.c.

Referenced by find_by_mark(), and pickup_exec().


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 318 of file app_directed_pickup.c.

static void __unreg_module ( void  ) [static]

Definition at line 318 of file app_directed_pickup.c.

static int can_pickup ( struct ast_channel chan) [static]
Todo:
This application should return a result code, like PICKUPRESULT

Definition at line 91 of file app_directed_pickup.c.

References ast_channel::_state, AST_FLAG_ZOMBIE, AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, ast_test_flag, ast_channel::masq, and ast_channel::pbx.

Referenced by find_by_exten(), find_by_group(), find_by_mark(), and my_ast_get_channel_by_name_locked().

{
   if (!chan->pbx && !chan->masq &&
      !ast_test_flag(chan, AST_FLAG_ZOMBIE) &&
      (chan->_state == AST_STATE_RINGING ||
       chan->_state == AST_STATE_RING ||
       chan->_state == AST_STATE_DOWN)) {
      return 1;
   }
   return 0;
}
static int find_by_exten ( struct ast_channel c,
void *  data 
) [static]

Definition at line 165 of file app_directed_pickup.c.

References can_pickup(), pickup_criteria::chan, pickup_criteria::context, ast_channel::dialcontext, ast_channel::exten, pickup_criteria::exten, and ast_channel::macroexten.

Referenced by pickup_by_exten().

{
   struct pickup_criteria *info = data;

   return (!strcasecmp(c->macroexten, info->exten) || !strcasecmp(c->exten, info->exten)) &&
      !strcasecmp(c->dialcontext, info->context) &&
      (info->chan != c) && can_pickup(c);
}
static int find_by_group ( struct ast_channel c,
void *  data 
) [static]

Definition at line 219 of file app_directed_pickup.c.

References ast_channel::callgroup, can_pickup(), chan, ast_channel::data, and ast_channel::pickupgroup.

Referenced by pickup_by_group().

{
   struct ast_channel *chan = data;

   return (c != chan) && (chan->pickupgroup & c->callgroup) && can_pickup(c);
}
static int find_by_mark ( struct ast_channel c,
void *  data 
) [static]

Definition at line 195 of file app_directed_pickup.c.

References can_pickup(), pbx_builtin_getvar_helper(), and PICKUPMARK.

Referenced by pickup_by_mark().

{
   const char *mark = data;
   const char *tmp;

   return (tmp = pbx_builtin_getvar_helper(c, PICKUPMARK)) &&
      !strcasecmp(tmp, mark) &&
      can_pickup(c);
}
static int load_module ( void  ) [static]
static struct ast_channel* my_ast_get_channel_by_name_locked ( const char *  channame) [static, read]

Helper Function to walk through ALL channels checking NAME and STATE.

Definition at line 104 of file app_directed_pickup.c.

References ast_channel_unlock, ast_walk_channel_by_name_prefix_locked(), can_pickup(), chan, and ast_channel::name.

Referenced by pickup_by_channel().

{
   struct ast_channel *chan;
   char *chkchan;
   size_t channame_len, chkchan_len;

   channame_len = strlen(channame);

   /* Check if channel name contains a '-'.
    * In this case the channel name will be interpreted as full channel name.
    */
   if (strchr(channame, '-')) {
      /* check full channel name */
      chkchan_len = channame_len;
      chkchan = (char *)channame;
   } else {
      /* need to append a '-' for the comparison so we check full channel name,
       * i.e SIP/hgc- , use a temporary variable so original stays the same for
       * debugging.
       */
      chkchan_len = channame_len + 1;
      chkchan = alloca(chkchan_len + 1);
      strcpy(chkchan, channame);
      strcat(chkchan, "-");
   }

   for (chan = ast_walk_channel_by_name_prefix_locked(NULL, channame, channame_len);
       chan;
       chan = ast_walk_channel_by_name_prefix_locked(chan, channame, channame_len)) {
      if (!strncasecmp(chan->name, chkchan, chkchan_len) && can_pickup(chan)) {
         return chan;
      }
      ast_channel_unlock(chan);
   }
   return NULL;
}
static int pickup_by_channel ( struct ast_channel chan,
char *  pickup 
) [static]

Attempt to pick up specified channel named , does not use context.

Definition at line 142 of file app_directed_pickup.c.

References ast_channel_unlock, ast_do_pickup(), and my_ast_get_channel_by_name_locked().

Referenced by pickupchan_exec().

{
   int res = 0;
   struct ast_channel *target;

   if (!(target = my_ast_get_channel_by_name_locked(pickup)))
      return -1;

   /* Just check that we are not picking up the SAME as target */
   if (chan != target) {
      res = ast_do_pickup(chan, target);
   }
   ast_channel_unlock(target);

   return res;
}
static int pickup_by_exten ( struct ast_channel chan,
const char *  exten,
const char *  context 
) [static]

Definition at line 175 of file app_directed_pickup.c.

References ast_channel_search_locked(), ast_channel_unlock, ast_do_pickup(), chan, context, exten, pickup_criteria::exten, and find_by_exten().

Referenced by pickup_exec().

{
   struct ast_channel *target = NULL;
   struct pickup_criteria search = {
      .exten = exten,
      .context = context,
      .chan = chan,
   };

   target = ast_channel_search_locked(find_by_exten, &search);

   if (target) {
      int res = ast_do_pickup(chan, target);
      ast_channel_unlock(target);
      return res;
   }

   return -1;
}
static int pickup_by_group ( struct ast_channel chan) [static]

Definition at line 226 of file app_directed_pickup.c.

References ast_channel_search_locked(), ast_channel_unlock, ast_do_pickup(), ast_log(), find_by_group(), LOG_NOTICE, and ast_channel::name.

Referenced by pickup_exec().

{
   struct ast_channel *target = ast_channel_search_locked(find_by_group, chan);

   if (target) {
      int res;

      ast_log(LOG_NOTICE, "%s, pickup attempt by %s\n", target->name, chan->name);
      res = ast_do_pickup(chan, target);
      ast_channel_unlock(target);
      return res;
   }

   return -1;
}
static int pickup_by_mark ( struct ast_channel chan,
const char *  mark 
) [static]

Definition at line 206 of file app_directed_pickup.c.

References ast_channel_search_locked(), ast_channel_unlock, ast_do_pickup(), and find_by_mark().

Referenced by pickup_exec().

{
   struct ast_channel *target = ast_channel_search_locked(find_by_mark, (char *) mark);

   if (target) {
      int res = ast_do_pickup(chan, target);
      ast_channel_unlock(target);
      return res;
   }

   return -1;
}
static int pickup_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 243 of file app_directed_pickup.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), ast_channel::context, context, exten, LOG_NOTICE, pickup_by_exten(), pickup_by_group(), pickup_by_mark(), PICKUPMARK, and strsep().

Referenced by load_module().

{
   int res = 0;
   char *tmp = ast_strdupa(data);
   char *exten = NULL, *context = NULL;

   if (ast_strlen_zero(data)) {
      res = pickup_by_group(chan);
      return res;
   }

   /* Parse extension (and context if there) */
   while (!ast_strlen_zero(tmp) && (exten = strsep(&tmp, "&"))) {
      if ((context = strchr(exten, '@')))
         *context++ = '\0';
      if (!ast_strlen_zero(context) && !strcasecmp(context, PICKUPMARK)) {
         if (!pickup_by_mark(chan, exten))
            break;
      } else {
         if (!pickup_by_exten(chan, exten, !ast_strlen_zero(context) ? context : chan->context))
            break;
      }
      ast_log(LOG_NOTICE, "No target channel found for %s.\n", exten);
   }

   return res;
}
static int pickupchan_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 272 of file app_directed_pickup.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), LOG_NOTICE, LOG_WARNING, ast_channel::name, pickup_by_channel(), and strsep().

Referenced by load_module().

{
   int res = 0;
   char *tmp = ast_strdupa(data);
   char *pickup = NULL;

   if (ast_strlen_zero(data)) {
      ast_log(LOG_WARNING, "PickupChan requires an argument (channel)!\n");
      return -1;  
   }

   /* Parse channel */
   while (!ast_strlen_zero(tmp) && (pickup = strsep(&tmp, "&"))) {
      if (!strncasecmp(chan->name, pickup, strlen(pickup))) {
         ast_log(LOG_NOTICE, "Cannot pickup your own channel %s.\n", pickup);
      } else {
         if (!pickup_by_channel(chan, pickup)) {
            break;
         }
         ast_log(LOG_NOTICE, "No target channel found for %s.\n", pickup);
      }
   }

   return res;
}
static int unload_module ( void  ) [static]

Definition at line 298 of file app_directed_pickup.c.

References ast_unregister_application().

{
   int res;

   res = ast_unregister_application(app);
   res |= ast_unregister_application(app2);

   return res;
}

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Directed Call Pickup Application" , .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, } [static]

Definition at line 318 of file app_directed_pickup.c.

const char* app = "Pickup" [static]

Definition at line 86 of file app_directed_pickup.c.

const char* app2 = "PickupChan" [static]

Definition at line 87 of file app_directed_pickup.c.

Referenced by _macro_exec().

Definition at line 318 of file app_directed_pickup.c.