Wed Jan 8 2020 09:50:03

Asterisk developer's documentation


chan_local.c File Reference

Local Proxy Channel. More...

#include "asterisk.h"
#include <fcntl.h>
#include <sys/signal.h>
#include "asterisk/lock.h"
#include "asterisk/causes.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/acl.h"
#include "asterisk/callerid.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/manager.h"
#include "asterisk/stringfields.h"
#include "asterisk/devicestate.h"
#include "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  local_pvt
 the local pvt structure for all channels More...
 

Macros

#define IS_OUTBOUND(a, b)   (a == b->chan ? 1 : 0)
 
#define LOCAL_ALREADY_MASQED   (1 << 0)
 
#define LOCAL_BRIDGE   (1 << 3)
 
#define LOCAL_LAUNCHED_PBX   (1 << 1)
 
#define LOCAL_MOH_PASSTHRU   (1 << 4)
 
#define LOCAL_NO_OPTIMIZATION   (1 << 2)
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void awesome_locking (struct local_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
 
static void check_bridge (struct ast_channel *ast, struct local_pvt *p)
 
static int load_module (void)
 Load module into PBX, register channel. More...
 
static struct local_pvtlocal_alloc (const char *data, format_t format)
 Create a call structure. More...
 
static int local_answer (struct ast_channel *ast)
 
static struct ast_channellocal_bridgedchannel (struct ast_channel *chan, struct ast_channel *bridge)
 Return the bridged channel of a Local channel. More...
 
static int local_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate new call, part of PBX interface dest is the dial string. More...
 
static int local_devicestate (void *data)
 Adds devicestate to local channels. More...
 
static int local_digit_begin (struct ast_channel *ast, char digit)
 
static int local_digit_end (struct ast_channel *ast, char digit, unsigned int duration)
 
static int local_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 
static int local_hangup (struct ast_channel *ast)
 Hangup a call through the local proxy channel. More...
 
static int local_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 
static struct ast_channellocal_new (struct local_pvt *p, int state, const char *linkedid)
 Start new local channel. More...
 
static void local_pvt_destructor (void *vdoomed)
 
static int local_queryoption (struct ast_channel *ast, int option, void *data, int *datalen)
 
static int local_queue_frame (struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
 queue a frame on a to either the p->owner or p->chan More...
 
static struct ast_framelocal_read (struct ast_channel *ast)
 
static struct ast_channellocal_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
 Part of PBX interface. More...
 
static int local_sendhtml (struct ast_channel *ast, int subclass, const char *data, int datalen)
 
static int local_sendtext (struct ast_channel *ast, const char *text)
 
static int local_setoption (struct ast_channel *chan, int option, void *data, int datalen)
 
static int local_write (struct ast_channel *ast, struct ast_frame *f)
 
static int locals_cmp_cb (void *obj, void *arg, int flags)
 
static char * locals_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command "local show channels". More...
 
static int manager_optimize_away (struct mansession *s, const struct message *m)
 
static int unload_module (void)
 Unload the local proxy channel from Asterisk. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Local Proxy Channel (Note: used internally by other modules)" , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static const int BUCKET_SIZE = 1
 
static struct ast_cli_entry cli_local []
 
static struct ast_jb_conf g_jb_conf
 
static struct ast_channel_tech local_tech
 
static struct ao2_containerlocals
 
static unsigned int name_sequence = 0
 
static const char tdesc [] = "Local Proxy Channel Driver"
 

Detailed Description

Local Proxy Channel.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file chan_local.c.

Macro Definition Documentation

#define IS_OUTBOUND (   a,
 
)    (a == b->chan ? 1 : 0)
#define LOCAL_ALREADY_MASQED   (1 << 0)

Already masqueraded

Definition at line 157 of file chan_local.c.

Referenced by check_bridge(), and local_write().

#define LOCAL_BRIDGE   (1 << 3)

Report back the "true" channel as being bridged to

Definition at line 160 of file chan_local.c.

Referenced by local_alloc(), and local_bridgedchannel().

#define LOCAL_LAUNCHED_PBX   (1 << 1)

PBX was launched

Definition at line 158 of file chan_local.c.

Referenced by local_call(), local_devicestate(), and local_hangup().

#define LOCAL_MOH_PASSTHRU   (1 << 4)

Pass through music on hold start/stop frames

Definition at line 161 of file chan_local.c.

Referenced by local_alloc(), and local_indicate().

#define LOCAL_NO_OPTIMIZATION   (1 << 2)

Do not optimize using masquerading

Definition at line 159 of file chan_local.c.

Referenced by check_bridge(), local_alloc(), local_indicate(), and manager_optimize_away().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 1428 of file chan_local.c.

static void __unreg_module ( void  )
static

Definition at line 1428 of file chan_local.c.

static void awesome_locking ( struct local_pvt p,
struct ast_channel **  outchan,
struct ast_channel **  outowner 
)
static

Definition at line 172 of file chan_local.c.

References ao2_lock, ao2_unlock, ast_channel_lock, ast_channel_ref, ast_channel_trylock, ast_channel_unlock, ast_channel_unref, local_pvt::chan, CHANNEL_DEADLOCK_AVOIDANCE, and local_pvt::owner.

Referenced by local_call(), and local_hangup().

173 {
174  struct ast_channel *chan = NULL;
175  struct ast_channel *owner = NULL;
176 
177  for (;;) {
178  ao2_lock(p);
179  if (p->chan) {
180  chan = p->chan;
181  ast_channel_ref(chan);
182  }
183  if (p->owner) {
184  owner = p->owner;
185  ast_channel_ref(owner);
186  }
187  ao2_unlock(p);
188 
189  /* if we don't have both channels, then this is very easy */
190  if (!owner || !chan) {
191  if (owner) {
192  ast_channel_lock(owner);
193  } else if(chan) {
194  ast_channel_lock(chan);
195  }
196  ao2_lock(p);
197  } else {
198  /* lock both channels first, then get the pvt lock */
199  ast_channel_lock(chan);
200  while (ast_channel_trylock(owner)) {
202  }
203  ao2_lock(p);
204  }
205 
206  /* Now that we have all the locks, validate that nothing changed */
207  if (p->owner != owner || p->chan != chan) {
208  if (owner) {
209  ast_channel_unlock(owner);
210  owner = ast_channel_unref(owner);
211  }
212  if (chan) {
213  ast_channel_unlock(chan);
214  chan = ast_channel_unref(chan);
215  }
216  ao2_unlock(p);
217  continue;
218  }
219 
220  break;
221  }
222  *outowner = p->owner;
223  *outchan = p->chan;
224 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ast_channel * owner
Definition: chan_local.c:153
#define ao2_lock(a)
Definition: astobj2.h:488
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define CHANNEL_DEADLOCK_AVOIDANCE(chan)
Definition: lock.h:480
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2491
struct ast_channel * chan
Definition: chan_local.c:154
#define ast_channel_trylock(chan)
Definition: channel.h:2468
static void check_bridge ( struct ast_channel ast,
struct local_pvt p 
)
static

Definition at line 490 of file chan_local.c.

References ast_channel::_bridge, ast_party_caller::ani, ao2_lock, ao2_unlock, ast_app_group_update(), ast_bridged_channel(), ast_channel_lock, ast_channel_masquerade(), ast_channel_ref, ast_channel_trylock, ast_channel_unlock, ast_channel_unref, ast_check_hangup(), ast_debug, ast_do_masquerade(), AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_REMOVE_HEAD, ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::caller, local_pvt::chan, ast_channel::dialed, f, ast_frame::frametype, ast_party_redirecting::from, ast_party_caller::id, LOCAL_ALREADY_MASQED, LOCAL_NO_OPTIMIZATION, ast_channel::monitor, ast_party_id::name, ast_channel::name, ast_party_id::number, ast_party_dialed::number, local_pvt::owner, ast_channel::readq, ast_channel::redirecting, ast_party_dialed::str, ast_party_id::subaddress, ast_party_dialed::subaddress, ast_party_redirecting::to, ast_party_name::valid, ast_party_number::valid, and ast_party_subaddress::valid.

Referenced by local_write().

491 {
492  struct ast_channel *owner;
493  struct ast_channel *chan;
494  struct ast_channel *bridged_chan;
495  struct ast_frame *f;
496 
497  /* Do a few conditional checks early on just to see if this optimization is possible */
499  || !p->chan || !p->owner) {
500  return;
501  }
502 
503  /* Safely get the channel bridged to p->chan */
504  chan = ast_channel_ref(p->chan);
505 
506  ao2_unlock(p); /* don't call bridged channel with the pvt locked */
507  bridged_chan = ast_bridged_channel(chan);
508  ao2_lock(p);
509 
510  chan = ast_channel_unref(chan);
511 
512  /* since we had to unlock p to get the bridged chan, validate our
513  * data once again and verify the bridged channel is what we expect
514  * it to be in order to perform this optimization */
516  || !p->chan || !p->owner
517  || (p->chan->_bridge != bridged_chan)) {
518  return;
519  }
520 
521  /* only do the masquerade if we are being called on the outbound channel,
522  if it has been bridged to another channel and if there are no pending
523  frames on the owner channel (because they would be transferred to the
524  outbound channel during the masquerade)
525  */
526  if (!p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */
527  || !AST_LIST_EMPTY(&p->owner->readq)
528  || ast != p->chan /* Sanity check (should always be false) */) {
529  return;
530  }
531 
532  /* Masquerade bridged channel into owner */
533  /* Lock everything we need, one by one, and give up if
534  we can't get everything. Remember, we'll get another
535  chance in just a little bit */
536  if (ast_channel_trylock(p->chan->_bridge)) {
537  return;
538  }
541  return;
542  }
543 
544  /*
545  * At this point we have 4 locks:
546  * p, p->chan (same as ast), p->chan->_bridge, p->owner
547  *
548  * Flush a voice or video frame on the outbound channel to make
549  * the queue empty faster so we can get optimized out.
550  */
551  f = AST_LIST_FIRST(&p->chan->readq);
552  if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
554  ast_frfree(f);
555  f = AST_LIST_FIRST(&p->chan->readq);
556  }
557 
558  if (f
559  || ast_check_hangup(p->owner)
563  return;
564  }
565 
566  /* Masquerade got setup. */
567  ast_debug(4, "Masquerading %s <- %s\n",
568  p->owner->name, p->chan->_bridge->name);
569  if (p->owner->monitor && !p->chan->_bridge->monitor) {
570  struct ast_channel_monitor *tmp;
571 
572  /* If a local channel is being monitored, we don't want a masquerade
573  * to cause the monitor to go away. Since the masquerade swaps the monitors,
574  * pre-swapping the monitors before the masquerade will ensure that the monitor
575  * ends up where it is expected.
576  */
577  tmp = p->owner->monitor;
578  p->owner->monitor = p->chan->_bridge->monitor;
579  p->chan->_bridge->monitor = tmp;
580  }
581  if (p->chan->audiohooks) {
582  struct ast_audiohook_list *audiohooks_swapper;
583 
584  audiohooks_swapper = p->chan->audiohooks;
585  p->chan->audiohooks = p->owner->audiohooks;
586  p->owner->audiohooks = audiohooks_swapper;
587  }
588 
589  /* If any Caller ID was set, preserve it after masquerade like above. We must check
590  * to see if Caller ID was set because otherwise we'll mistakingly copy info not
591  * set from the dialplan and will overwrite the real channel Caller ID. The reason
592  * for this whole preswapping action is because the Caller ID is set on the channel
593  * thread (which is the to be masqueraded away local channel) before both local
594  * channels are optimized away.
595  */
596  if (p->owner->caller.id.name.valid || p->owner->caller.id.number.valid
599  struct ast_party_caller tmp;
600 
601  tmp = p->owner->caller;
602  p->owner->caller = p->chan->_bridge->caller;
603  p->chan->_bridge->caller = tmp;
604  }
608  struct ast_party_redirecting tmp;
609 
610  tmp = p->owner->redirecting;
612  p->chan->_bridge->redirecting = tmp;
613  }
614  if (p->owner->dialed.number.str || p->owner->dialed.subaddress.valid) {
615  struct ast_party_dialed tmp;
616 
617  tmp = p->owner->dialed;
618  p->owner->dialed = p->chan->_bridge->dialed;
619  p->chan->_bridge->dialed = tmp;
620  }
623 
626 
627  /* Do the masquerade now. */
628  owner = ast_channel_ref(p->owner);
629  ao2_unlock(p);
630  ast_channel_unlock(ast);
631  ast_do_masquerade(owner);
632  ast_channel_unref(owner);
633  ast_channel_lock(ast);
634  ao2_lock(p);
635 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
char * str
Subscriber phone number (Malloced)
Definition: channel.h:336
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
int ast_channel_masquerade(struct ast_channel *original, struct ast_channel *clone)
Weird function made for call transfers.
Definition: channel.c:6110
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_party_name name
Subscriber name.
Definition: channel.h:290
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
Definition: channel.h:449
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
unsigned char valid
TRUE if the subaddress information is valid/present.
Definition: channel.h:278
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ast_channel * owner
Definition: chan_local.c:153
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_party_id ani
Automatic Number Identification (ANI)
Definition: channel.h:377
struct ast_party_dialed::@155 number
Dialed/Called number.
struct ast_audiohook_list * audiohooks
Definition: channel.h:764
Caller Party information.
Definition: channel.h:368
#define ao2_lock(a)
Definition: astobj2.h:488
struct ast_channel * _bridge
Definition: channel.h:748
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
#define LOCAL_ALREADY_MASQED
Definition: chan_local.c:157
struct ast_party_subaddress subaddress
Subscriber subaddress.
Definition: channel.h:294
Dialed/Called Party information.
Definition: channel.h:328
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
Definition: channel.h:447
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_format f[]
Definition: format_g726.c:181
struct ast_party_subaddress subaddress
Dialed/Called subaddress.
Definition: channel.h:341
int ast_app_group_update(struct ast_channel *oldchan, struct ast_channel *newchan)
Update all group counting for a channel to a new one.
Definition: app.c:1329
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2491
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
Definition: channel.h:452
struct ast_channel * chan
Definition: chan_local.c:154
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_channel_trylock(chan)
Definition: channel.h:2468
#define ast_frfree(fr)
Definition: frame.h:583
unsigned char valid
TRUE if the name information is valid/present.
Definition: channel.h:229
struct ast_channel_monitor * monitor
Definition: channel.h:769
#define LOCAL_NO_OPTIMIZATION
Definition: chan_local.c:159
struct ast_channel::@156 readq
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
int ast_do_masquerade(struct ast_channel *chan)
Start masquerading a channel.
Definition: channel.c:6546
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int load_module ( void  )
static

Load module into PBX, register channel.

Definition at line 1382 of file chan_local.c.

References ao2_container_alloc, ao2_ref, ast_channel_register(), ast_cli_register_multiple(), ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, locals_cmp_cb(), LOG_ERROR, and manager_optimize_away().

1383 {
1385  return AST_MODULE_LOAD_FAILURE;
1386  }
1387 
1388  /* Make sure we can register our channel type */
1390  ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
1391  ao2_ref(locals, -1);
1392  return AST_MODULE_LOAD_FAILURE;
1393  }
1394  ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
1396 
1397  return AST_MODULE_LOAD_SUCCESS;
1398 }
static const int BUCKET_SIZE
Definition: chan_local.c:84
descriptor for a cli entry.
Definition: cli.h:165
#define EVENT_FLAG_CALL
Definition: manager.h:72
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
Definition: channel.c:907
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static int locals_cmp_cb(void *obj, void *arg, int flags)
Definition: chan_local.c:1376
static struct ao2_container * locals
Definition: chan_local.c:86
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_cli_entry cli_local[]
Definition: chan_local.c:1323
#define ao2_container_alloc(arg1, arg2, arg3)
Definition: astobj2.h:734
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static int manager_optimize_away(struct mansession *s, const struct message *m)
Definition: chan_local.c:1327
static struct ast_channel_tech local_tech
Definition: chan_local.c:116
static struct local_pvt* local_alloc ( const char *  data,
format_t  format 
)
static

Create a call structure.

Definition at line 1131 of file chan_local.c.

References ao2_alloc, ao2_link, ast_copy_string(), ast_exists_extension(), AST_JB_ENABLED, ast_log(), ast_module_ref(), ast_set_flag, ast_test_flag, local_pvt::context, local_pvt::exten, format, local_pvt::jb_conf, LOCAL_BRIDGE, LOCAL_MOH_PASSTHRU, LOCAL_NO_OPTIMIZATION, local_pvt_destructor(), LOG_ERROR, LOG_NOTICE, local_pvt::reqformat, and ast_module_info::self.

Referenced by local_request().

1132 {
1133  struct local_pvt *tmp = NULL;
1134  char *c = NULL, *opts = NULL;
1135 
1136  if (!(tmp = ao2_alloc(sizeof(*tmp), local_pvt_destructor))) {
1137  return NULL;
1138  }
1139 
1141 
1142  /* Initialize private structure information */
1143  ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
1144 
1145  memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
1146 
1147  /* Look for options */
1148  if ((opts = strchr(tmp->exten, '/'))) {
1149  *opts++ = '\0';
1150  if (strchr(opts, 'n'))
1152  if (strchr(opts, 'j')) {
1155  else {
1156  ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
1157  "to use the 'j' option to enable the jitterbuffer\n");
1158  }
1159  }
1160  if (strchr(opts, 'b')) {
1161  ast_set_flag(tmp, LOCAL_BRIDGE);
1162  }
1163  if (strchr(opts, 'm')) {
1165  }
1166  }
1167 
1168  /* Look for a context */
1169  if ((c = strchr(tmp->exten, '@')))
1170  *c++ = '\0';
1171 
1172  ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
1173 
1174  tmp->reqformat = format;
1175 
1176 #if 0
1177  /* We can't do this check here, because we don't know the CallerID yet, and
1178  * the CallerID could potentially affect what step is actually taken (or
1179  * even if that step exists). */
1180  if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
1181  ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
1182  tmp = local_pvt_destroy(tmp);
1183  } else {
1184 #endif
1185  /* Add to list */
1186  ao2_link(locals, tmp);
1187 #if 0
1188  }
1189 #endif
1190  return tmp; /* this is returned with a ref */
1191 }
format_t reqformat
Definition: chan_local.c:151
#define LOCAL_MOH_PASSTHRU
Definition: chan_local.c:161
#define ao2_link(arg1, arg2)
Definition: astobj2.h:785
char context[AST_MAX_CONTEXT]
Definition: chan_local.c:149
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_set_flag(p, flag)
Definition: utils.h:70
static struct ast_jb_conf g_jb_conf
Definition: chan_local.c:90
#define LOCAL_BRIDGE
Definition: chan_local.c:160
struct ast_module * self
Definition: module.h:227
static struct ao2_container * locals
Definition: chan_local.c:86
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
#define LOG_NOTICE
Definition: logger.h:133
static void local_pvt_destructor(void *vdoomed)
Definition: chan_local.c:1125
the local pvt structure for all channels
Definition: chan_local.c:147
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char exten[AST_MAX_EXTENSION]
Definition: chan_local.c:150
#define LOCAL_NO_OPTIMIZATION
Definition: chan_local.c:159
static snd_pcm_format_t format
Definition: chan_alsa.c:93
struct ast_jb_conf jb_conf
Definition: chan_local.c:152
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
static int local_answer ( struct ast_channel ast)
static

Definition at line 460 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), IS_OUTBOUND, local_queue_frame(), LOG_WARNING, and ast_channel::tech_pvt.

461 {
462  struct local_pvt *p = ast->tech_pvt;
463  int isoutbound;
464  int res = -1;
465 
466  if (!p)
467  return -1;
468 
469  ao2_lock(p);
470  ao2_ref(p, 1);
471  isoutbound = IS_OUTBOUND(ast, p);
472  if (isoutbound) {
473  /* Pass along answer since somebody answered us */
474  struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
475  res = local_queue_frame(p, isoutbound, &answer, ast, 1);
476  } else {
477  ast_log(LOG_WARNING, "Huh? Local is being asked to answer?\n");
478  }
479  ao2_unlock(p);
480  ao2_ref(p, -1);
481  return res;
482 }
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
the local pvt structure for all channels
Definition: chan_local.c:147
Data structure associated with a single frame of data.
Definition: frame.h:142
static struct ast_channel * local_bridgedchannel ( struct ast_channel chan,
struct ast_channel bridge 
)
static

Return the bridged channel of a Local channel.

Definition at line 331 of file chan_local.c.

References ast_channel::_bridge, ao2_lock, ao2_unlock, ast_debug, ast_test_flag, ast_channel::bridge, local_pvt::chan, LOCAL_BRIDGE, ast_channel::name, local_pvt::owner, and ast_channel::tech_pvt.

332 {
333  struct local_pvt *p = bridge->tech_pvt;
334  struct ast_channel *bridged = bridge;
335 
336  if (!p) {
337  ast_debug(1, "Asked for bridged channel on '%s'/'%s', returning <none>\n",
338  chan->name, bridge->name);
339  return NULL;
340  }
341 
342  ao2_lock(p);
343 
344  if (ast_test_flag(p, LOCAL_BRIDGE)) {
345  /* Find the opposite channel */
346  bridged = (bridge == p->owner ? p->chan : p->owner);
347 
348  /* Now see if the opposite channel is bridged to anything */
349  if (!bridged) {
350  bridged = bridge;
351  } else if (bridged->_bridge) {
352  bridged = bridged->_bridge;
353  }
354  }
355 
356  ao2_unlock(p);
357 
358  return bridged;
359 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_test_flag(p, flag)
Definition: utils.h:63
void * tech_pvt
Definition: channel.h:744
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ast_channel * owner
Definition: chan_local.c:153
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define LOCAL_BRIDGE
Definition: chan_local.c:160
#define ao2_lock(a)
Definition: astobj2.h:488
struct ast_channel * _bridge
Definition: channel.h:748
const ast_string_field name
Definition: channel.h:787
struct ast_bridge * bridge
Definition: channel.h:865
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
static int local_call ( struct ast_channel ast,
char *  dest,
int  timeout 
)
static

Initiate new call, part of PBX interface dest is the dial string.

Definition at line 879 of file chan_local.c.

References accountcode, ast_channel::accountcode, ao2_lock, ao2_ref, ao2_unlock, ast_calloc, ast_cdr_update(), ast_channel_cc_params_init(), ast_channel_datastore_inherit(), ast_channel_get_cc_config_params(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_connected_line_copy_from_caller(), ast_connected_line_copy_to_caller(), ast_exists_extension(), AST_FLAG_ANSWERED_ELSEWHERE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_party_dialed_copy(), ast_party_redirecting_copy(), ast_pbx_start(), ast_set_cc_interfaces_chanvar(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_test_flag, awesome_locking(), ast_channel::caller, ast_channel::connected, context, ast_channel::context, ast_channel::dialed, ast_var_t::entries, exten, ast_channel::exten, ast_party_caller::id, language, ast_channel::language, len(), LOCAL_LAUNCHED_PBX, LOG_NOTICE, musicclass, ast_channel::musicclass, ast_var_t::name, ast_party_id::number, ast_channel::redirecting, S_COR, ast_party_number::str, ast_channel::tech_pvt, ast_party_number::valid, and ast_channel::varshead.

880 {
881  struct local_pvt *p = ast->tech_pvt;
882  int pvt_locked = 0;
883 
884  struct ast_channel *owner = NULL;
885  struct ast_channel *chan = NULL;
886  int res;
887  struct ast_var_t *varptr = NULL, *new;
888  size_t len, namelen;
889  char *reduced_dest = ast_strdupa(dest);
890  char *slash;
891  const char *exten;
892  const char *context;
893 
894  if (!p) {
895  return -1;
896  }
897 
898  /* since we are letting go of channel locks that were locked coming into
899  * this function, then we need to give the tech pvt a ref */
900  ao2_ref(p, 1);
901  ast_channel_unlock(ast);
902 
903  awesome_locking(p, &chan, &owner);
904  pvt_locked = 1;
905 
906  if (owner != ast) {
907  res = -1;
908  goto return_cleanup;
909  }
910 
911  if (!owner || !chan) {
912  res = -1;
913  goto return_cleanup;
914  }
915 
916  /*
917  * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
918  * call, so it's done here instead.
919  *
920  * All these failure points just return -1. The individual strings will
921  * be cleared when we destroy the channel.
922  */
924 
925  ast_party_dialed_copy(&chan->dialed, &owner->dialed);
926 
929 
930  ast_string_field_set(chan, language, owner->language);
933  ast_cdr_update(chan);
934 
936 
937  /* Make sure we inherit the ANSWERED_ELSEWHERE flag if it's set on the queue/dial call request in the dialplan */
940  }
941 
942  /* copy the channel variables from the incoming channel to the outgoing channel */
943  /* Note that due to certain assumptions, they MUST be in the same order */
944  AST_LIST_TRAVERSE(&owner->varshead, varptr, entries) {
945  namelen = strlen(varptr->name);
946  len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
947  if ((new = ast_calloc(1, len))) {
948  memcpy(new, varptr, len);
949  new->value = &(new->name[0]) + namelen + 1;
950  AST_LIST_INSERT_TAIL(&chan->varshead, new, entries);
951  }
952  }
953  ast_channel_datastore_inherit(owner, chan);
954  /* If the local channel has /n or /b on the end of it,
955  * we need to lop that off for our argument to setting
956  * up the CC_INTERFACES variable
957  */
958  if ((slash = strrchr(reduced_dest, '/'))) {
959  *slash = '\0';
960  }
961  ast_set_cc_interfaces_chanvar(chan, reduced_dest);
962 
963  exten = ast_strdupa(chan->exten);
964  context = ast_strdupa(chan->context);
965 
966  ao2_unlock(p);
967  pvt_locked = 0;
968 
969  ast_channel_unlock(chan);
970 
971  if (!ast_exists_extension(chan, context, exten, 1,
972  S_COR(owner->caller.id.number.valid, owner->caller.id.number.str, NULL))) {
973  ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
974  res = -1;
975  chan = ast_channel_unref(chan); /* we already unlocked it, so clear it hear so the cleanup label won't touch it. */
976  goto return_cleanup;
977  }
978 
979  /* Start switch on sub channel */
980  if (!(res = ast_pbx_start(chan))) {
981  ao2_lock(p);
983  ao2_unlock(p);
984  }
985  chan = ast_channel_unref(chan); /* chan is already unlocked, clear it here so the cleanup lable won't touch it. */
986 
987 return_cleanup:
988  if (p) {
989  if (pvt_locked) {
990  ao2_unlock(p);
991  }
992  ao2_ref(p, -1);
993  }
994  if (chan) {
995  ast_channel_unlock(chan);
996  chan = ast_channel_unref(chan);
997  }
998 
999  /* owner is supposed to be == to ast, if it
1000  * is, don't unlock it because ast must exit locked */
1001  if (owner) {
1002  if (owner != ast) {
1003  ast_channel_unlock(owner);
1004  ast_channel_lock(ast);
1005  }
1006  owner = ast_channel_unref(owner);
1007  } else {
1008  /* we have to exit with ast locked */
1009  ast_channel_lock(ast);
1010  }
1011 
1012  return res;
1013 }
static char musicclass[MAX_MUSICCLASS]
Definition: chan_mgcp.c:155
static char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: chan_iax2.c:383
#define ast_channel_lock(chan)
Definition: channel.h:2466
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
Main Channel structure associated with a channel.
Definition: channel.h:742
char * str
Subscriber phone number (Malloced)
Definition: channel.h:241
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_test_flag(p, flag)
Definition: utils.h:63
void * tech_pvt
Definition: channel.h:744
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
#define ast_set_flag(p, flag)
Definition: utils.h:70
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
Definition: pbx.c:5879
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
#define LOCAL_LAUNCHED_PBX
Definition: chan_local.c:158
#define ao2_unlock(a)
Definition: astobj2.h:497
int value
Definition: syslog.c:39
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition: channel.c:9754
struct ast_party_id id
Caller party ID.
Definition: channel.h:370
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2573
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:83
#define ao2_lock(a)
Definition: astobj2.h:488
static char language[MAX_LANGUAGE]
Definition: chan_alsa.c:108
char name[0]
Definition: chanvars.h:31
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params)
Set up datastore with CCSS parameters for a channel.
Definition: channel.c:9731
int ast_cdr_update(struct ast_channel *chan)
Update CDR on a channel.
Definition: cdr.c:1083
struct ast_party_dialed dialed
Dialed/Called information.
Definition: channel.h:797
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
Definition: chan_local.c:172
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2467
struct ast_var_t::@158 entries
the local pvt structure for all channels
Definition: chan_local.c:147
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8443
const ast_string_field musicclass
Definition: channel.h:787
const ast_string_field accountcode
Definition: channel.h:787
void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
Copy the connected line information to the caller information.
Definition: channel.c:8450
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:247
struct varshead varshead
Definition: channel.h:817
const ast_string_field language
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2367
int ast_set_cc_interfaces_chanvar(struct ast_channel *chan, const char *const extension)
Set the CC_INTERFACES channel variable for a channel using an extension as a starting point...
Definition: ccss.c:3402
void ast_party_dialed_copy(struct ast_party_dialed *dest, const struct ast_party_dialed *src)
Copy the source dialed party information to the destination dialed party.
Definition: channel.c:2227
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:344
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:292
static int local_devicestate ( void *  data)
static

Adds devicestate to local channels.

Definition at line 282 of file chan_local.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_debug, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, ast_exists_extension(), ast_log(), ast_strdupa, ast_test_flag, context, local_pvt::context, exten, local_pvt::exten, LOCAL_LAUNCHED_PBX, LOG_WARNING, and local_pvt::owner.

283 {
284  char *exten = ast_strdupa(data);
285  char *context = NULL, *opts = NULL;
286  int res;
287  struct local_pvt *lp;
288  struct ao2_iterator it;
289 
290  if (!(context = strchr(exten, '@'))) {
291  ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
292  return AST_DEVICE_INVALID;
293  }
294 
295  *context++ = '\0';
296 
297  /* Strip options if they exist */
298  if ((opts = strchr(context, '/')))
299  *opts = '\0';
300 
301  ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
302 
303  res = ast_exists_extension(NULL, context, exten, 1, NULL);
304  if (!res)
305  return AST_DEVICE_INVALID;
306 
307  res = AST_DEVICE_NOT_INUSE;
308 
309  it = ao2_iterator_init(locals, 0);
310  for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) {
311  int is_inuse;
312 
313  ao2_lock(lp);
314  is_inuse = !strcmp(exten, lp->exten)
315  && !strcmp(context, lp->context)
316  && lp->owner
318  ao2_unlock(lp);
319  if (is_inuse) {
320  res = AST_DEVICE_INUSE;
321  ao2_ref(lp, -1);
322  break;
323  }
324  }
326 
327  return res;
328 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
char context[AST_MAX_CONTEXT]
Definition: chan_local.c:149
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
#define LOG_WARNING
Definition: logger.h:144
#define LOCAL_LAUNCHED_PBX
Definition: chan_local.c:158
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
struct ast_channel * owner
Definition: chan_local.c:153
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ao2_container * locals
Definition: chan_local.c:86
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:5400
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
the local pvt structure for all channels
Definition: chan_local.c:147
char exten[AST_MAX_EXTENSION]
Definition: chan_local.c:150
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static int local_digit_begin ( struct ast_channel ast,
char  digit 
)
static

Definition at line 790 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_FRAME_DTMF_BEGIN, ast_frame_subclass::integer, IS_OUTBOUND, local_queue_frame(), ast_frame::subclass, and ast_channel::tech_pvt.

791 {
792  struct local_pvt *p = ast->tech_pvt;
793  int res = -1;
794  struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
795  int isoutbound;
796 
797  if (!p)
798  return -1;
799 
800  ao2_ref(p, 1); /* ref for local_queue_frame */
801  ao2_lock(p);
802  isoutbound = IS_OUTBOUND(ast, p);
803  f.subclass.integer = digit;
804  res = local_queue_frame(p, isoutbound, &f, ast, 0);
805  ao2_unlock(p);
806  ao2_ref(p, -1);
807 
808  return res;
809 }
union ast_frame_subclass subclass
Definition: frame.h:146
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ast_format f[]
Definition: format_g726.c:181
the local pvt structure for all channels
Definition: chan_local.c:147
Data structure associated with a single frame of data.
Definition: frame.h:142
static int local_digit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
)
static

Definition at line 811 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_FRAME_DTMF_END, ast_frame_subclass::integer, IS_OUTBOUND, ast_frame::len, local_queue_frame(), ast_frame::subclass, and ast_channel::tech_pvt.

812 {
813  struct local_pvt *p = ast->tech_pvt;
814  int res = -1;
815  struct ast_frame f = { AST_FRAME_DTMF_END, };
816  int isoutbound;
817 
818  if (!p)
819  return -1;
820 
821  ao2_ref(p, 1); /* ref for local_queue_frame */
822  ao2_lock(p);
823  isoutbound = IS_OUTBOUND(ast, p);
824  f.subclass.integer = digit;
825  f.len = duration;
826  res = local_queue_frame(p, isoutbound, &f, ast, 0);
827  ao2_unlock(p);
828  ao2_ref(p, -1);
829 
830  return res;
831 }
union ast_frame_subclass subclass
Definition: frame.h:146
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ast_format f[]
Definition: format_g726.c:181
the local pvt structure for all channels
Definition: chan_local.c:147
Data structure associated with a single frame of data.
Definition: frame.h:142
long len
Definition: frame.h:170
static int local_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
)
static

Definition at line 675 of file chan_local.c.

References ast_channel::_bridge, ao2_lock, ao2_unlock, ast_check_hangup(), ast_log(), ast_queue_hangup(), local_pvt::chan, LOG_WARNING, local_pvt::owner, and ast_channel::tech_pvt.

676 {
677  struct local_pvt *p = newchan->tech_pvt;
678 
679  if (!p)
680  return -1;
681 
682  ao2_lock(p);
683 
684  if ((p->owner != oldchan) && (p->chan != oldchan)) {
685  ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
686  ao2_unlock(p);
687  return -1;
688  }
689  if (p->owner == oldchan)
690  p->owner = newchan;
691  else
692  p->chan = newchan;
693 
694  /* Do not let a masquerade cause a Local channel to be bridged to itself! */
695  if (!ast_check_hangup(newchan) && ((p->owner && p->owner->_bridge == p->chan) || (p->chan && p->chan->_bridge == p->owner))) {
696  ast_log(LOG_WARNING, "You can not bridge a Local channel to itself!\n");
697  ao2_unlock(p);
698  ast_queue_hangup(newchan);
699  return -1;
700  }
701 
702  ao2_unlock(p);
703  return 0;
704 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1569
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ast_channel * owner
Definition: chan_local.c:153
#define ao2_lock(a)
Definition: astobj2.h:488
struct ast_channel * _bridge
Definition: channel.h:748
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
static int local_hangup ( struct ast_channel ast)
static

Hangup a call through the local proxy channel.

Definition at line 1016 of file chan_local.c.

References ao2_ref, ao2_unlink, ao2_unlock, AST_CAUSE_ANSWERED_ELSEWHERE, ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_clear_flag, AST_CONTROL_HANGUP, ast_debug, AST_FLAG_ANSWERED_ELSEWHERE, AST_FRAME_CONTROL, ast_hangup(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_set_flag, ast_test_flag, awesome_locking(), local_pvt::chan, hangup_chan(), ast_channel::hangupcause, IS_OUTBOUND, LOCAL_LAUNCHED_PBX, local_queue_frame(), local_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), status, and ast_channel::tech_pvt.

1017 {
1018  struct local_pvt *p = ast->tech_pvt;
1019  int isoutbound;
1020  int hangup_chan = 0;
1021  int res = 0;
1022  struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = ast->hangupcause };
1023  struct ast_channel *owner = NULL;
1024  struct ast_channel *chan = NULL;
1025  int answered_elsewhere = 0;
1026 
1027  if (!p) {
1028  return -1;
1029  }
1030 
1031  /* give the pvt a ref since we are unlocking the channel. */
1032  ao2_ref(p, 1);
1033 
1034  /* the pvt isn't going anywhere, we gave it a ref */
1035  ast_channel_unlock(ast);
1036 
1037  /* lock everything */
1038  awesome_locking(p, &chan, &owner);
1039 
1040  if (ast != chan && ast != owner) {
1041  res = -1;
1042  goto local_hangup_cleanup;
1043  }
1044 
1045  isoutbound = IS_OUTBOUND(ast, p); /* just comparing pointer of ast */
1046 
1048  answered_elsewhere = 1;
1050  ast_debug(2, "This local call has the ANSWERED_ELSEWHERE flag set.\n");
1051  }
1052 
1053  if (isoutbound) {
1054  const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
1055 
1056  if (status && p->owner) {
1057  p->owner->hangupcause = p->chan->hangupcause;
1058  pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
1059  }
1060 
1062  p->chan = NULL;
1063  } else {
1064  if (p->chan) {
1065  /* Use the hangupcause to propagate the fact that the
1066  * call was answered somewhere. */
1067  if (answered_elsewhere) {
1069  } else {
1070  ast_queue_hangup(p->chan);
1071  }
1072  }
1073  p->owner = NULL;
1074  }
1075 
1076  ast->tech_pvt = NULL; /* this is one of our locked channels, doesn't matter which */
1077 
1078  if (!p->owner && !p->chan) {
1079  ao2_unlock(p);
1080 
1081  /* Remove from list */
1082  ao2_unlink(locals, p);
1083  ao2_ref(p, -1);
1084  p = NULL;
1085  res = 0;
1086  goto local_hangup_cleanup;
1087  }
1088  if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX)) {
1089  /* Need to actually hangup since there is no PBX */
1090  hangup_chan = 1;
1091  } else {
1092  local_queue_frame(p, isoutbound, &f, NULL, 0);
1093  }
1094 
1095 local_hangup_cleanup:
1096  if (p) {
1097  ao2_unlock(p);
1098  ao2_ref(p, -1);
1099  }
1100  if (owner) {
1101  ast_channel_unlock(owner);
1102  owner = ast_channel_unref(owner);
1103  }
1104  if (chan) {
1105  ast_channel_unlock(chan);
1106  if (hangup_chan) {
1107  ast_hangup(chan);
1108  }
1109  chan = ast_channel_unref(chan);
1110  }
1111 
1112  /* leave with the same stupid channel locked that came in */
1113  ast_channel_lock(ast);
1114  return res;
1115 }
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1569
int ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2804
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define LOCAL_LAUNCHED_PBX
Definition: chan_local.c:158
#define ao2_unlock(a)
Definition: astobj2.h:497
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
Definition: channel.c:1581
struct ast_channel * owner
Definition: chan_local.c:153
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:113
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct ao2_container * locals
Definition: chan_local.c:86
static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
Definition: chan_local.c:172
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_format f[]
Definition: format_g726.c:181
#define ast_clear_flag(p, flag)
Definition: utils.h:77
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
Definition: chan_misdn.c:8374
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
Data structure associated with a single frame of data.
Definition: frame.h:142
int hangupcause
Definition: channel.h:849
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
jack_status_t status
Definition: app_jack.c:143
static int local_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
)
static

Definition at line 706 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_connected_line_build_data(), ast_connected_line_copy_to_caller(), AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_redirecting_build_data(), AST_T38_REQUEST_PARMS, ast_test_flag, ast_channel::caller, local_pvt::chan, ast_channel::connected, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, IS_OUTBOUND, LOCAL_MOH_PASSTHRU, LOCAL_NO_OPTIMIZATION, local_queue_frame(), local_pvt::owner, ast_frame::ptr, ast_channel::redirecting, ast_control_t38_parameters::request_response, ast_frame::subclass, and ast_channel::tech_pvt.

707 {
708  struct local_pvt *p = ast->tech_pvt;
709  int res = 0;
710  struct ast_frame f = { AST_FRAME_CONTROL, };
711  int isoutbound;
712 
713  if (!p)
714  return -1;
715 
716  ao2_ref(p, 1); /* ref for local_queue_frame */
717 
718  /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
719  if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
720  ast_moh_start(ast, data, NULL);
721  } else if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
722  ast_moh_stop(ast);
723  } else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
724  struct ast_channel *this_channel;
725  struct ast_channel *the_other_channel;
726  /* A connected line update frame may only contain a partial amount of data, such
727  * as just a source, or just a ton, and not the full amount of information. However,
728  * the collected information is all stored in the outgoing channel's connectedline
729  * structure, so when receiving a connected line update on an outgoing local channel,
730  * we need to transmit the collected connected line information instead of whatever
731  * happens to be in this control frame. The same applies for redirecting information, which
732  * is why it is handled here as well.*/
733  ao2_lock(p);
734  isoutbound = IS_OUTBOUND(ast, p);
735  if (isoutbound) {
736  this_channel = p->chan;
737  the_other_channel = p->owner;
738  } else {
739  this_channel = p->owner;
740  the_other_channel = p->chan;
741  }
742  if (the_other_channel) {
743  unsigned char frame_data[1024];
744  if (condition == AST_CONTROL_CONNECTED_LINE) {
745  if (isoutbound) {
746  ast_connected_line_copy_to_caller(&the_other_channel->caller, &this_channel->connected);
747  }
748  f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), &this_channel->connected, NULL);
749  } else {
750  f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), &this_channel->redirecting, NULL);
751  }
752  f.subclass.integer = condition;
753  f.data.ptr = frame_data;
754  res = local_queue_frame(p, isoutbound, &f, ast, 1);
755  }
756  ao2_unlock(p);
757  } else {
758  /* Queue up a frame representing the indication as a control frame */
759  ao2_lock(p);
760  /*
761  * Block -1 stop tones events if we are to be optimized out. We
762  * don't need a flurry of these events on a local channel chain
763  * when initially connected to slow the optimization process.
764  */
765  if (0 <= condition || ast_test_flag(p, LOCAL_NO_OPTIMIZATION)) {
766  isoutbound = IS_OUTBOUND(ast, p);
767  f.subclass.integer = condition;
768  f.data.ptr = (void *) data;
769  f.datalen = datalen;
770  res = local_queue_frame(p, isoutbound, &f, ast, 1);
771 
772  if (!res && (condition == AST_CONTROL_T38_PARAMETERS) &&
773  (datalen == sizeof(struct ast_control_t38_parameters))) {
774  const struct ast_control_t38_parameters *parameters = data;
775 
776  if (parameters->request_response == AST_T38_REQUEST_PARMS) {
777  res = AST_T38_REQUEST_PARMS;
778  }
779  }
780  } else {
781  ast_debug(4, "Blocked indication %d\n", condition);
782  }
783  ao2_unlock(p);
784  }
785 
786  ao2_ref(p, -1);
787  return res;
788 }
union ast_frame_subclass subclass
Definition: frame.h:146
#define LOCAL_MOH_PASSTHRU
Definition: chan_local.c:161
Main Channel structure associated with a channel.
Definition: channel.h:742
int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Build the connected line information data frame.
Definition: channel.c:8825
struct ast_party_connected_line connected
Channel Connected Line ID information.
Definition: channel.h:811
struct ast_party_caller caller
Channel Caller ID information.
Definition: channel.h:804
#define ast_test_flag(p, flag)
Definition: utils.h:63
void * ptr
Definition: frame.h:160
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
struct ast_party_redirecting redirecting
Redirecting/Diversion information.
Definition: channel.h:814
enum ast_control_t38 request_response
Definition: frame.h:412
#define ao2_unlock(a)
Definition: astobj2.h:497
const char * data
Definition: channel.h:755
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:8051
struct ast_channel * owner
Definition: chan_local.c:153
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int datalen
Definition: frame.h:148
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:8040
static struct ast_format f[]
Definition: format_g726.c:181
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
Data structure associated with a single frame of data.
Definition: frame.h:142
void ast_connected_line_copy_to_caller(struct ast_party_caller *dest, const struct ast_party_connected_line *src)
Copy the connected line information to the caller information.
Definition: channel.c:8450
#define LOCAL_NO_OPTIMIZATION
Definition: chan_local.c:159
union ast_frame::@172 data
int ast_redirecting_build_data(unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Build the redirecting id data frame.
Definition: channel.c:9161
static struct ast_channel* local_new ( struct local_pvt p,
int  state,
const char *  linkedid 
)
static

Start new local channel.

Definition at line 1194 of file chan_local.c.

References ast_channel::accountcode, ast_channel::amaflags, ast_atomic_fetchadd_int(), ast_best_codec(), ast_channel_alloc(), ast_channel_release(), ast_copy_string(), AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_jb_configure(), ast_log(), AST_STATE_RING, local_pvt::chan, local_pvt::context, ast_channel::context, local_pvt::exten, ast_channel::exten, ast_channel::flags, local_pvt::jb_conf, ast_channel::linkedid, local_tech, LOG_WARNING, ast_channel::nativeformats, local_pvt::owner, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, local_pvt::reqformat, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by local_request().

1195 {
1196  struct ast_channel *tmp = NULL, *tmp2 = NULL;
1197  int fmt = 0;
1198  int generated_seqno = ast_atomic_fetchadd_int((int *)&name_sequence, +1);
1199  const char *t;
1200  int ama;
1201 
1202  /* Allocate two new Asterisk channels */
1203  /* safe accountcode */
1204  if (p->owner && p->owner->accountcode)
1205  t = p->owner->accountcode;
1206  else
1207  t = "";
1208 
1209  if (p->owner)
1210  ama = p->owner->amaflags;
1211  else
1212  ama = 0;
1213 
1214  /* Make sure that the ;2 channel gets the same linkedid as ;1. You can't pass linkedid to both
1215  * allocations since if linkedid isn't set, then each channel will generate its own linkedid. */
1216  if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%08x;1", p->exten, p->context, (unsigned)generated_seqno))
1217  || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, tmp->linkedid, ama, "Local/%s@%s-%08x;2", p->exten, p->context, (unsigned)generated_seqno))) {
1218  if (tmp) {
1219  tmp = ast_channel_release(tmp);
1220  }
1221  ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
1222  return NULL;
1223  }
1224 
1225  tmp2->tech = tmp->tech = &local_tech;
1226 
1227  tmp->nativeformats = p->reqformat;
1228  tmp2->nativeformats = p->reqformat;
1229 
1230  /* Determine our read/write format and set it on each channel */
1231  fmt = ast_best_codec(p->reqformat);
1232  tmp->writeformat = fmt;
1233  tmp2->writeformat = fmt;
1234  tmp->rawwriteformat = fmt;
1235  tmp2->rawwriteformat = fmt;
1236  tmp->readformat = fmt;
1237  tmp2->readformat = fmt;
1238  tmp->rawreadformat = fmt;
1239  tmp2->rawreadformat = fmt;
1240 
1241  tmp->tech_pvt = p;
1242  tmp2->tech_pvt = p;
1243 
1245  tmp2->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
1246 
1247  p->owner = tmp;
1248  p->chan = tmp2;
1249 
1250  ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
1251  ast_copy_string(tmp2->context, p->context, sizeof(tmp2->context));
1252  ast_copy_string(tmp2->exten, p->exten, sizeof(tmp->exten));
1253  tmp->priority = 1;
1254  tmp2->priority = 1;
1255 
1256  ast_jb_configure(tmp, &p->jb_conf);
1257 
1258  return tmp;
1259 }
format_t reqformat
Definition: chan_local.c:151
Main Channel structure associated with a channel.
Definition: channel.h:742
int priority
Definition: channel.h:841
format_t writeformat
Definition: channel.h:854
char context[AST_MAX_CONTEXT]
Definition: chan_local.c:149
void * tech_pvt
Definition: channel.h:744
char context[AST_MAX_CONTEXT]
Definition: channel.h:868
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1921
#define LOG_WARNING
Definition: logger.h:144
format_t rawwriteformat
Definition: channel.h:856
format_t ast_best_codec(format_t fmts)
Pick the best audio codec.
Definition: channel.c:1062
format_t nativeformats
Definition: channel.h:852
const ast_string_field linkedid
Definition: channel.h:787
format_t rawreadformat
Definition: channel.h:855
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return * the previous value of *p. This can be used to handle reference co...
Definition: lock.h:603
struct ast_channel * ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt,...)
Definition: channel.c:9825
struct ast_channel * owner
Definition: chan_local.c:153
unsigned int flags
Definition: channel.h:850
static unsigned int name_sequence
Definition: chan_local.c:88
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
Definition: abstract_jb.c:616
format_t readformat
Definition: channel.h:853
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_channel * chan
Definition: chan_local.c:154
const ast_string_field accountcode
Definition: channel.h:787
char exten[AST_MAX_EXTENSION]
Definition: chan_local.c:150
int amaflags
Definition: channel.h:843
struct ast_channel_tech * tech
Definition: channel.h:743
struct ast_jb_conf jb_conf
Definition: chan_local.c:152
char exten[AST_MAX_EXTENSION]
Definition: channel.h:869
static struct ast_channel_tech local_tech
Definition: chan_local.c:116
static void local_pvt_destructor ( void *  vdoomed)
static

Definition at line 1125 of file chan_local.c.

References ast_module_unref(), and ast_module_info::self.

Referenced by local_alloc().

1126 {
1128 }
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
struct ast_module * self
Definition: module.h:227
static int local_queryoption ( struct ast_channel ast,
int  option,
void *  data,
int *  datalen 
)
static

Definition at line 362 of file chan_local.c.

References ao2_lock, ao2_unlock, ast_bridged_channel(), ast_channel_lock, ast_channel_queryoption(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, AST_OPTION_T38_STATE, local_pvt::chan, IS_OUTBOUND, local_pvt::owner, and ast_channel::tech_pvt.

363 {
364  struct local_pvt *p;
365  struct ast_channel *bridged = NULL;
366  struct ast_channel *tmp = NULL;
367  int res = 0;
368 
369  if (option != AST_OPTION_T38_STATE) {
370  /* AST_OPTION_T38_STATE is the only supported option at this time */
371  return -1;
372  }
373 
374  /* for some reason the channel is not locked in channel.c when this function is called */
375  if (!(p = ast->tech_pvt)) {
376  return -1;
377  }
378 
379  ao2_lock(p);
380  if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) {
381  ao2_unlock(p);
382  return -1;
383  }
384  ast_channel_ref(tmp);
385  ao2_unlock(p);
386  ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
387 
388  ast_channel_lock(tmp);
389  if (!(bridged = ast_bridged_channel(tmp))) {
390  res = -1;
391  ast_channel_unlock(tmp);
392  goto query_cleanup;
393  }
394  ast_channel_ref(bridged);
395  ast_channel_unlock(tmp);
396 
397 query_cleanup:
398  if (bridged) {
399  res = ast_channel_queryoption(bridged, option, data, datalen, 0);
400  bridged = ast_channel_unref(bridged);
401  }
402  if (tmp) {
403  tmp = ast_channel_unref(tmp);
404  }
405  ast_channel_lock(ast); /* Lock back before we leave */
406 
407  return res;
408 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void * tech_pvt
Definition: channel.h:744
int ast_channel_queryoption(struct ast_channel *channel, int option, void *data, int *datalen, int block)
Checks the value of an option.
Definition: channel.c:7815
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
const char * data
Definition: channel.h:755
struct ast_channel * owner
Definition: chan_local.c:153
#define ao2_lock(a)
Definition: astobj2.h:488
#define AST_OPTION_T38_STATE
Definition: frame.h:490
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2491
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
static int local_queue_frame ( struct local_pvt p,
int  isoutbound,
struct ast_frame f,
struct ast_channel us,
int  us_locked 
)
static

queue a frame on a to either the p->owner or p->chan

Note
the local_pvt MUST have it's ref count bumped before entering this function and decremented after this function is called. This is a side effect of the deadlock avoidance that is necessary to lock 2 channels and a tech_pvt. Without a ref counted local_pvt, it is impossible to guarantee it will not be destroyed by another thread during deadlock avoidance.

Definition at line 418 of file chan_local.c.

References ao2_lock, ao2_unlock, ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_queue_frame(), ast_setstate(), AST_STATE_RINGING, local_pvt::chan, ast_frame::frametype, ast_channel::generator, ast_frame_subclass::integer, local_pvt::owner, and ast_frame::subclass.

Referenced by local_answer(), local_digit_begin(), local_digit_end(), local_hangup(), local_indicate(), local_sendhtml(), local_sendtext(), and local_write().

420 {
421  struct ast_channel *other = NULL;
422 
423  /* Recalculate outbound channel */
424  other = isoutbound ? p->owner : p->chan;
425 
426  if (!other) {
427  return 0;
428  }
429 
430  /* do not queue media frames if a generator is on both local channels */
431  if (us
433  && us->generator
434  && other->generator) {
435  return 0;
436  }
437 
438  /* grab a ref on the channel before unlocking the pvt,
439  * other can not go away from us now regardless of locking */
440  ast_channel_ref(other);
441  if (us && us_locked) {
442  ast_channel_unlock(us);
443  }
444  ao2_unlock(p);
445 
448  }
449  ast_queue_frame(other, f);
450 
451  other = ast_channel_unref(other);
452  if (us && us_locked) {
453  ast_channel_lock(us);
454  }
455  ao2_lock(p);
456 
457  return 0;
458 }
union ast_frame_subclass subclass
Definition: frame.h:146
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
struct ast_generator * generator
Definition: channel.h:747
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ast_channel * owner
Definition: chan_local.c:153
#define ao2_lock(a)
Definition: astobj2.h:488
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2491
struct ast_channel * chan
Definition: chan_local.c:154
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
Definition: channel.c:7119
enum ast_frame_type frametype
Definition: frame.h:144
static struct ast_frame * local_read ( struct ast_channel ast)
static

Definition at line 637 of file chan_local.c.

References ast_null_frame.

638 {
639  return &ast_null_frame;
640 }
struct ast_frame ast_null_frame
Definition: frame.c:131
static struct ast_channel * local_request ( const char *  type,
format_t  format,
const struct ast_channel requestor,
void *  data,
int *  cause 
)
static

Part of PBX interface.

Definition at line 1262 of file chan_local.c.

References ao2_ref, ao2_unlink, ast_channel_cc_params_init(), ast_channel_get_cc_config_params(), ast_channel_release(), AST_STATE_DOWN, local_pvt::chan, ast_channel::linkedid, local_alloc(), local_new(), and local_pvt::owner.

1263 {
1264  struct local_pvt *p;
1265  struct ast_channel *chan;
1266 
1267  /* Allocate a new private structure and then Asterisk channels */
1268  p = local_alloc(data, format);
1269  if (!p) {
1270  return NULL;
1271  }
1272  chan = local_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
1273  if (!chan) {
1274  ao2_unlink(locals, p);
1275  } else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
1276  ao2_unlink(locals, p);
1277  p->owner = ast_channel_release(p->owner);
1278  p->chan = ast_channel_release(p->chan);
1279  chan = NULL;
1280  }
1281  ao2_ref(p, -1); /* kill the ref from the alloc */
1282 
1283  return chan;
1284 }
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
Definition: channel.c:1921
static struct ast_channel * local_new(struct local_pvt *p, int state, const char *linkedid)
Start new local channel.
Definition: chan_local.c:1194
const char * data
Definition: channel.h:755
const ast_string_field linkedid
Definition: channel.h:787
struct ast_cc_config_params * ast_channel_get_cc_config_params(struct ast_channel *chan)
Get the CCSS parameters from a channel.
Definition: channel.c:9754
struct ast_channel * owner
Definition: chan_local.c:153
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static struct ao2_container * locals
Definition: chan_local.c:86
int ast_channel_cc_params_init(struct ast_channel *chan, const struct ast_cc_config_params *base_params)
Set up datastore with CCSS parameters for a channel.
Definition: channel.c:9731
static struct local_pvt * local_alloc(const char *data, format_t format)
Create a call structure.
Definition: chan_local.c:1131
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define ao2_unlink(arg1, arg2)
Definition: astobj2.h:817
static int local_sendhtml ( struct ast_channel ast,
int  subclass,
const char *  data,
int  datalen 
)
static

Definition at line 854 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_FRAME_HTML, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, IS_OUTBOUND, local_queue_frame(), ast_frame::ptr, ast_frame::subclass, and ast_channel::tech_pvt.

855 {
856  struct local_pvt *p = ast->tech_pvt;
857  int res = -1;
858  struct ast_frame f = { AST_FRAME_HTML, };
859  int isoutbound;
860 
861  if (!p)
862  return -1;
863 
864  ao2_lock(p);
865  ao2_ref(p, 1); /* ref for local_queue_frame */
866  isoutbound = IS_OUTBOUND(ast, p);
868  f.data.ptr = (char *)data;
869  f.datalen = datalen;
870  res = local_queue_frame(p, isoutbound, &f, ast, 0);
871  ao2_unlock(p);
872  ao2_ref(p, -1);
873 
874  return res;
875 }
union ast_frame_subclass subclass
Definition: frame.h:146
void * ptr
Definition: frame.h:160
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
int datalen
Definition: frame.h:148
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ast_format f[]
Definition: format_g726.c:181
the local pvt structure for all channels
Definition: chan_local.c:147
Data structure associated with a single frame of data.
Definition: frame.h:142
union ast_frame::@172 data
static int local_sendtext ( struct ast_channel ast,
const char *  text 
)
static

Definition at line 833 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_FRAME_TEXT, ast_frame::data, ast_frame::datalen, IS_OUTBOUND, local_queue_frame(), ast_frame::ptr, and ast_channel::tech_pvt.

834 {
835  struct local_pvt *p = ast->tech_pvt;
836  int res = -1;
837  struct ast_frame f = { AST_FRAME_TEXT, };
838  int isoutbound;
839 
840  if (!p)
841  return -1;
842 
843  ao2_lock(p);
844  ao2_ref(p, 1); /* ref for local_queue_frame */
845  isoutbound = IS_OUTBOUND(ast, p);
846  f.data.ptr = (char *) text;
847  f.datalen = strlen(text) + 1;
848  res = local_queue_frame(p, isoutbound, &f, ast, 0);
849  ao2_unlock(p);
850  ao2_ref(p, -1);
851  return res;
852 }
void * ptr
Definition: frame.h:160
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
char * text
Definition: app_queue.c:1091
int datalen
Definition: frame.h:148
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ast_format f[]
Definition: format_g726.c:181
the local pvt structure for all channels
Definition: chan_local.c:147
Data structure associated with a single frame of data.
Definition: frame.h:142
union ast_frame::@172 data
static int local_setoption ( struct ast_channel chan,
int  option,
void *  data,
int  datalen 
)
static

Definition at line 227 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, AST_CHAN_WRITE_INFO_T_VERSION, ast_channel_lock, ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_log(), AST_OPTION_CHANNEL_WRITE, local_pvt::chan, ast_chan_write_info_t::chan, ast_chan_write_info_t::data, ast_channel::data, ast_chan_write_info_t::function, if(), LOG_ERROR, local_pvt::owner, ast_channel::tech_pvt, ast_chan_write_info_t::value, ast_chan_write_info_t::version, and ast_chan_write_info_t::write_fn.

228 {
229  int res = 0;
230  struct local_pvt *p = NULL;
231  struct ast_channel *otherchan = NULL;
232  ast_chan_write_info_t *write_info;
233 
234  if (option != AST_OPTION_CHANNEL_WRITE) {
235  return -1;
236  }
237 
238  write_info = data;
239 
240  if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
241  ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
242  return -1;
243  }
244 
245  /* get the tech pvt */
246  if (!(p = ast->tech_pvt)) {
247  return -1;
248  }
249  ao2_ref(p, 1);
250  ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
251 
252  /* get the channel we are supposed to write to */
253  ao2_lock(p);
254  otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
255  if (!otherchan || otherchan == write_info->chan) {
256  res = -1;
257  otherchan = NULL;
258  ao2_unlock(p);
259  goto setoption_cleanup;
260  }
261  ast_channel_ref(otherchan);
262 
263  /* clear the pvt lock before grabbing the channel */
264  ao2_unlock(p);
265 
266  ast_channel_lock(otherchan);
267  res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
268  ast_channel_unlock(otherchan);
269 
270 setoption_cleanup:
271  if (p) {
272  ao2_ref(p, -1);
273  }
274  if (otherchan) {
275  ast_channel_unref(otherchan);
276  }
277  ast_channel_lock(ast); /* Lock back before we leave */
278  return res;
279 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
const char * function
Definition: channel.h:488
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
#define ao2_unlock(a)
Definition: astobj2.h:497
const char * data
Definition: channel.h:755
const char * value
Definition: channel.h:490
struct ast_channel * owner
Definition: chan_local.c:153
struct ast_channel * chan
Definition: channel.h:487
#define AST_OPTION_CHANNEL_WRITE
Handle channel write data If a channel needs to process the data from a func_channel write operation ...
Definition: frame.h:484
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
ast_acf_write_fn_t write_fn
Definition: channel.h:486
#define LOG_ERROR
Definition: logger.h:155
#define AST_CHAN_WRITE_INFO_T_VERSION
ast_chan_write_info_t version. Must be incremented if structure is changed
Definition: channel.h:484
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
Structure to handle passing func_channel_write info to channels via setoption.
Definition: channel.h:482
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2491
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * chan
Definition: chan_local.c:154
static int local_write ( struct ast_channel ast,
struct ast_frame f 
)
static

Definition at line 642 of file chan_local.c.

References ao2_lock, ao2_ref, ao2_unlock, ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_test_flag, check_bridge(), ast_frame::frametype, IS_OUTBOUND, LOCAL_ALREADY_MASQED, local_queue_frame(), ast_channel::name, and ast_channel::tech_pvt.

643 {
644  struct local_pvt *p = ast->tech_pvt;
645  int res = -1;
646  int isoutbound;
647 
648  if (!p) {
649  return -1;
650  }
651 
652  /* Just queue for delivery to the other side */
653  ao2_ref(p, 1); /* ref for local_queue_frame */
654  ao2_lock(p);
655  isoutbound = IS_OUTBOUND(ast, p);
656 
657  if (isoutbound
658  && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
659  check_bridge(ast, p);
660  }
661 
663  res = local_queue_frame(p, isoutbound, f, ast, 1);
664  } else {
665  ast_debug(1, "Not posting to '%s' queue since already masqueraded out\n",
666  ast->name);
667  res = 0;
668  }
669  ao2_unlock(p);
670  ao2_ref(p, -1);
671 
672  return res;
673 }
static void check_bridge(struct ast_channel *ast, struct local_pvt *p)
Definition: chan_local.c:490
#define ast_test_flag(p, flag)
Definition: utils.h:63
static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f, struct ast_channel *us, int us_locked)
queue a frame on a to either the p-&gt;owner or p-&gt;chan
Definition: chan_local.c:418
void * tech_pvt
Definition: channel.h:744
#define IS_OUTBOUND(a, b)
Definition: chan_local.c:79
#define ao2_unlock(a)
Definition: astobj2.h:497
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
#define LOCAL_ALREADY_MASQED
Definition: chan_local.c:157
const ast_string_field name
Definition: channel.h:787
the local pvt structure for all channels
Definition: chan_local.c:147
enum ast_frame_type frametype
Definition: frame.h:144
static int locals_cmp_cb ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 1376 of file chan_local.c.

References CMP_MATCH.

Referenced by load_module().

1377 {
1378  return (obj == arg) ? CMP_MATCH : 0;
1379 }
static char* locals_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

CLI command "local show channels".

Definition at line 1287 of file chan_local.c.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, local_pvt::context, local_pvt::exten, ast_cli_args::fd, ast_channel::name, local_pvt::owner, RESULT_SUCCESS, and ast_cli_entry::usage.

1288 {
1289  struct local_pvt *p = NULL;
1290  struct ao2_iterator it;
1291 
1292  switch (cmd) {
1293  case CLI_INIT:
1294  e->command = "local show channels";
1295  e->usage =
1296  "Usage: local show channels\n"
1297  " Provides summary information on active local proxy channels.\n";
1298  return NULL;
1299  case CLI_GENERATE:
1300  return NULL;
1301  }
1302 
1303  if (a->argc != 3)
1304  return CLI_SHOWUSAGE;
1305 
1306  if (ao2_container_count(locals) == 0) {
1307  ast_cli(a->fd, "No local channels in use\n");
1308  return RESULT_SUCCESS;
1309  }
1310 
1311  it = ao2_iterator_init(locals, 0);
1312  while ((p = ao2_iterator_next(&it))) {
1313  ao2_lock(p);
1314  ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? p->owner->name : "<unowned>", p->exten, p->context);
1315  ao2_unlock(p);
1316  ao2_ref(p, -1);
1317  }
1318  ao2_iterator_destroy(&it);
1319 
1320  return CLI_SUCCESS;
1321 }
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Definition: astobj2.c:470
char context[AST_MAX_CONTEXT]
Definition: chan_local.c:149
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
const int argc
Definition: cli.h:154
Definition: cli.h:146
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
struct ast_channel * owner
Definition: chan_local.c:153
const int fd
Definition: cli.h:153
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ao2_container * locals
Definition: chan_local.c:86
#define CLI_SHOWUSAGE
Definition: cli.h:44
const ast_string_field name
Definition: channel.h:787
char * command
Definition: cli.h:180
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
the local pvt structure for all channels
Definition: chan_local.c:147
char exten[AST_MAX_EXTENSION]
Definition: chan_local.c:150
#define RESULT_SUCCESS
Definition: cli.h:39
static int manager_optimize_away ( struct mansession s,
const struct message m 
)
static

Definition at line 1327 of file chan_local.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock, ao2_ref, ao2_unlock, ast_channel_get_by_name(), ast_channel_unref, ast_clear_flag, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), LOCAL_NO_OPTIMIZATION, and ast_channel::tech_pvt.

Referenced by load_module().

1328 {
1329  const char *channel;
1330  struct local_pvt *p, *tmp = NULL;
1331  struct ast_channel *c;
1332  int found = 0;
1333  struct ao2_iterator it;
1334 
1335  channel = astman_get_header(m, "Channel");
1336 
1337  if (ast_strlen_zero(channel)) {
1338  astman_send_error(s, m, "'Channel' not specified.");
1339  return 0;
1340  }
1341 
1342  c = ast_channel_get_by_name(channel);
1343  if (!c) {
1344  astman_send_error(s, m, "Channel does not exist.");
1345  return 0;
1346  }
1347 
1348  p = c->tech_pvt;
1349  ast_channel_unref(c);
1350  c = NULL;
1351 
1352  it = ao2_iterator_init(locals, 0);
1353  while ((tmp = ao2_iterator_next(&it))) {
1354  if (tmp == p) {
1355  ao2_lock(tmp);
1356  found = 1;
1358  ao2_unlock(tmp);
1359  ao2_ref(tmp, -1);
1360  break;
1361  }
1362  ao2_ref(tmp, -1);
1363  }
1364  ao2_iterator_destroy(&it);
1365 
1366  if (found) {
1367  astman_send_ack(s, m, "Queued channel to be optimized away");
1368  } else {
1369  astman_send_error(s, m, "Unable to find channel");
1370  }
1371 
1372  return 0;
1373 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void * tech_pvt
Definition: channel.h:744
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
#define ao2_unlock(a)
Definition: astobj2.h:497
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define ao2_lock(a)
Definition: astobj2.h:488
static struct ao2_container * locals
Definition: chan_local.c:86
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
#define ast_clear_flag(p, flag)
Definition: utils.h:77
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
the local pvt structure for all channels
Definition: chan_local.c:147
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
#define LOCAL_NO_OPTIMIZATION
Definition: chan_local.c:159
static int unload_module ( void  )
static

Unload the local proxy channel from Asterisk.

Definition at line 1401 of file chan_local.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, and local_pvt::owner.

1402 {
1403  struct local_pvt *p = NULL;
1404  struct ao2_iterator it;
1405 
1406  /* First, take us out of the channel loop */
1407  ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
1408  ast_manager_unregister("LocalOptimizeAway");
1410 
1411  it = ao2_iterator_init(locals, 0);
1412  while ((p = ao2_iterator_next(&it))) {
1413  if (p->owner) {
1415  }
1416  ao2_ref(p, -1);
1417  }
1418  ao2_iterator_destroy(&it);
1419  ao2_ref(locals, -1);
1420 
1421  return 0;
1422 }
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
Definition: channel.c:938
#define ao2_iterator_next(arg1)
Definition: astobj2.h:1126
descriptor for a cli entry.
Definition: cli.h:165
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
Definition: astobj2.c:818
struct ast_channel * owner
Definition: chan_local.c:153
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
static struct ao2_container * locals
Definition: chan_local.c:86
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
Definition: astobj2.c:833
static struct ast_cli_entry cli_local[]
Definition: chan_local.c:1323
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1053
the local pvt structure for all channels
Definition: chan_local.c:147
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
static struct ast_channel_tech local_tech
Definition: chan_local.c:116

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Local Proxy Channel (Note: used internally by other modules)" , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DRIVER, }
static

Definition at line 1428 of file chan_local.c.

Definition at line 1428 of file chan_local.c.

const int BUCKET_SIZE = 1
static

Definition at line 84 of file chan_local.c.

struct ast_cli_entry cli_local[]
static
Initial value:
= {
AST_CLI_DEFINE(locals_show, "List status of local channels"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command &quot;local show channels&quot;.
Definition: chan_local.c:1287

Definition at line 1323 of file chan_local.c.

struct ast_jb_conf g_jb_conf
static

Definition at line 90 of file chan_local.c.

struct ast_channel_tech local_tech
static

Definition at line 116 of file chan_local.c.

Referenced by local_new().

struct ao2_container* locals
static

Definition at line 86 of file chan_local.c.

unsigned int name_sequence = 0
static

Definition at line 88 of file chan_local.c.

const char tdesc[] = "Local Proxy Channel Driver"
static

Definition at line 77 of file chan_local.c.