1a8ea17ecd93ae014e63f8127cd6733b456b610c
[asterisk/asterisk.git] / channels / chan_local.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \author Mark Spencer <markster@digium.com>
22  *
23  * \brief Local Proxy Channel
24  * 
25  * \ingroup channel_drivers
26  */
27
28 /*** MODULEINFO
29         <support_level>core</support_level>
30  ***/
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <fcntl.h>
37 #include <sys/signal.h>
38
39 #include "asterisk/lock.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/config.h"
42 #include "asterisk/module.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/sched.h"
45 #include "asterisk/io.h"
46 #include "asterisk/acl.h"
47 #include "asterisk/callerid.h"
48 #include "asterisk/file.h"
49 #include "asterisk/cli.h"
50 #include "asterisk/app.h"
51 #include "asterisk/musiconhold.h"
52 #include "asterisk/manager.h"
53 #include "asterisk/stringfields.h"
54 #include "asterisk/devicestate.h"
55 #include "asterisk/astobj2.h"
56
57 /*** DOCUMENTATION
58         <manager name="LocalOptimizeAway" language="en_US">
59                 <synopsis>
60                         Optimize away a local channel when possible.
61                 </synopsis>
62                 <syntax>
63                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
64                         <parameter name="Channel" required="true">
65                                 <para>The channel name to optimize away.</para>
66                         </parameter>
67                 </syntax>
68                 <description>
69                         <para>A local channel created with "/n" will not automatically optimize away.
70                         Calling this command on the local channel will clear that flag and allow
71                         it to optimize away if it's bridged or when it becomes bridged.</para>
72                 </description>
73         </manager>
74  ***/
75
76 static const char tdesc[] = "Local Proxy Channel Driver";
77
78 #define IS_OUTBOUND(a,b) (a == b->chan ? 1 : 0)
79
80 /* right now we are treating the locals astobj2 container as a
81  * list.  If there is ever a reason to make this more efficient
82  * increasing the bucket size would help. */
83 static const int BUCKET_SIZE = 1;
84
85 static struct ao2_container *locals;
86
87 static struct ast_jb_conf g_jb_conf = {
88         .flags = 0,
89         .max_size = -1,
90         .resync_threshold = -1,
91         .impl = "",
92         .target_extra = -1,
93 };
94
95 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
96 static int local_digit_begin(struct ast_channel *ast, char digit);
97 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
98 static int local_call(struct ast_channel *ast, const char *dest, int timeout);
99 static int local_hangup(struct ast_channel *ast);
100 static int local_answer(struct ast_channel *ast);
101 static struct ast_frame *local_read(struct ast_channel *ast);
102 static int local_write(struct ast_channel *ast, struct ast_frame *f);
103 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen);
104 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
105 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen);
106 static int local_sendtext(struct ast_channel *ast, const char *text);
107 static int local_devicestate(const char *data);
108 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
109 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen);
110 static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
111
112 /* PBX interface structure for channel registration */
113 static struct ast_channel_tech local_tech = {
114         .type = "Local",
115         .description = tdesc,
116         .requester = local_request,
117         .send_digit_begin = local_digit_begin,
118         .send_digit_end = local_digit_end,
119         .call = local_call,
120         .hangup = local_hangup,
121         .answer = local_answer,
122         .read = local_read,
123         .write = local_write,
124         .write_video = local_write,
125         .exception = local_read,
126         .indicate = local_indicate,
127         .fixup = local_fixup,
128         .send_html = local_sendhtml,
129         .send_text = local_sendtext,
130         .devicestate = local_devicestate,
131         .bridged_channel = local_bridgedchannel,
132         .queryoption = local_queryoption,
133         .setoption = local_setoption,
134 };
135
136 /*! \brief the local pvt structure for all channels
137
138         The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
139
140         ast_chan owner -> local_pvt -> ast_chan chan -> yet-another-pvt-depending-on-channel-type
141
142 */
143 struct local_pvt {
144         unsigned int flags;             /*!< Private flags */
145         char context[AST_MAX_CONTEXT];  /*!< Context to call */
146         char exten[AST_MAX_EXTENSION];  /*!< Extension to call */
147         struct ast_format_cap *reqcap;  /*!< Requested format capabilities */
148         struct ast_jb_conf jb_conf;     /*!< jitterbuffer configuration for this local channel */
149         struct ast_channel *owner;      /*!< Master Channel - Bridging happens here */
150         struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */
151         struct ast_module_user *u_owner;/*!< reference to keep the module loaded while in use */
152         struct ast_module_user *u_chan; /*!< reference to keep the module loaded while in use */
153 };
154
155 #define LOCAL_ALREADY_MASQED  (1 << 0) /*!< Already masqueraded */
156 #define LOCAL_LAUNCHED_PBX    (1 << 1) /*!< PBX was launched */
157 #define LOCAL_NO_OPTIMIZATION (1 << 2) /*!< Do not optimize using masquerading */
158 #define LOCAL_BRIDGE          (1 << 3) /*!< Report back the "true" channel as being bridged to */
159 #define LOCAL_MOH_PASSTHRU    (1 << 4) /*!< Pass through music on hold start/stop frames */
160
161 /* 
162  * \brief Send a pvt in with no locks held and get all locks
163  *
164  * \note NO locks should be held prior to calling this function
165  * \note The pvt must have a ref held before calling this function
166  * \note if outchan or outowner is set != NULL after calling this function
167  *       those channels are locked and reffed.
168  * \note Batman.
169  */
170 static void awesome_locking(struct local_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
171 {
172         struct ast_channel *chan = NULL;
173         struct ast_channel *owner = NULL;
174
175         for (;;) {
176                 ao2_lock(p);
177                 if (p->chan) {
178                         chan = p->chan;
179                         ast_channel_ref(chan);
180                 }
181                 if (p->owner) {
182                         owner = p->owner;
183                         ast_channel_ref(owner);
184                 }
185                 ao2_unlock(p);
186
187                 /* if we don't have both channels, then this is very easy */
188                 if (!owner || !chan) {
189                         if (owner) {
190                                 ast_channel_lock(owner);
191                         } else if(chan) {
192                                 ast_channel_lock(chan);
193                         }
194                         ao2_lock(p);
195                 } else {
196                         /* lock both channels first, then get the pvt lock */
197                         ast_channel_lock_both(chan, owner);
198                         ao2_lock(p);
199                 }
200
201                 /* Now that we have all the locks, validate that nothing changed */
202                 if (p->owner != owner || p->chan != chan) {
203                         if (owner) {
204                                 ast_channel_unlock(owner);
205                                 owner = ast_channel_unref(owner);
206                         }
207                         if (chan) {
208                                 ast_channel_unlock(chan);
209                                 chan = ast_channel_unref(chan);
210                         }
211                         ao2_unlock(p);
212                         continue;
213                 }
214
215                 break;
216         }
217         *outowner = p->owner;
218         *outchan = p->chan;
219 }
220
221 /* Called with ast locked */
222 static int local_setoption(struct ast_channel *ast, int option, void * data, int datalen)
223 {
224         int res = 0;
225         struct local_pvt *p = NULL;
226         struct ast_channel *otherchan = NULL;
227         ast_chan_write_info_t *write_info;
228
229         if (option != AST_OPTION_CHANNEL_WRITE) {
230                 return -1;
231         }
232
233         write_info = data;
234
235         if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
236                 ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
237                 return -1;
238         }
239
240         /* get the tech pvt */
241         if (!(p = ast_channel_tech_pvt(ast))) {
242                 return -1;
243         }
244         ao2_ref(p, 1);
245         ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
246
247         /* get the channel we are supposed to write to */
248         ao2_lock(p);
249         otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
250         if (!otherchan || otherchan == write_info->chan) {
251                 res = -1;
252                 otherchan = NULL;
253                 ao2_unlock(p);
254                 goto setoption_cleanup;
255         }
256         ast_channel_ref(otherchan);
257
258         /* clear the pvt lock before grabbing the channel */
259         ao2_unlock(p);
260
261         ast_channel_lock(otherchan);
262         res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
263         ast_channel_unlock(otherchan);
264
265 setoption_cleanup:
266         if (p) {
267                 ao2_ref(p, -1);
268         }
269         if (otherchan) {
270                 ast_channel_unref(otherchan);
271         }
272         ast_channel_lock(ast); /* Lock back before we leave */
273         return res;
274 }
275
276 /*! \brief Adds devicestate to local channels */
277 static int local_devicestate(const char *data)
278 {
279         char *exten = ast_strdupa(data);
280         char *context = NULL, *opts = NULL;
281         int res;
282         struct local_pvt *lp;
283         struct ao2_iterator it;
284
285         if (!(context = strchr(exten, '@'))) {
286                 ast_log(LOG_WARNING, "Someone used Local/%s somewhere without a @context. This is bad.\n", exten);
287                 return AST_DEVICE_INVALID;
288         }
289
290         *context++ = '\0';
291
292         /* Strip options if they exist */
293         if ((opts = strchr(context, '/')))
294                 *opts = '\0';
295
296         ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
297
298         res = ast_exists_extension(NULL, context, exten, 1, NULL);
299         if (!res)
300                 return AST_DEVICE_INVALID;
301
302         res = AST_DEVICE_NOT_INUSE;
303
304         it = ao2_iterator_init(locals, 0);
305         while ((lp = ao2_iterator_next(&it))) {
306                 if (!strcmp(exten, lp->exten) && !strcmp(context, lp->context) && lp->owner) {
307                         res = AST_DEVICE_INUSE;
308                         ao2_ref(lp, -1);
309                         break;
310                 }
311                 ao2_ref(lp, -1);
312         }
313         ao2_iterator_destroy(&it);
314
315         return res;
316 }
317
318 /*! \brief Return the bridged channel of a Local channel */
319 static struct ast_channel *local_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge)
320 {
321         struct local_pvt *p = ast_channel_tech_pvt(bridge);
322         struct ast_channel *bridged = bridge;
323
324         if (!p) {
325                 ast_debug(1, "Asked for bridged channel on '%s'/'%s', returning <none>\n",
326                         ast_channel_name(chan), ast_channel_name(bridge));
327                 return NULL;
328         }
329
330         ao2_lock(p);
331
332         if (ast_test_flag(p, LOCAL_BRIDGE)) {
333                 /* Find the opposite channel */
334                 bridged = (bridge == p->owner ? p->chan : p->owner);
335
336                 /* Now see if the opposite channel is bridged to anything */
337                 if (!bridged) {
338                         bridged = bridge;
339                 } else if (ast_channel_internal_bridged_channel(bridged)) {
340                         bridged = ast_channel_internal_bridged_channel(bridged);
341                 }
342         }
343
344         ao2_unlock(p);
345
346         return bridged;
347 }
348
349 /* Called with ast locked */
350 static int local_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
351 {
352         struct local_pvt *p;
353         struct ast_channel *bridged = NULL;
354         struct ast_channel *tmp = NULL;
355         int res = 0;
356
357         if (option != AST_OPTION_T38_STATE) {
358                 /* AST_OPTION_T38_STATE is the only supported option at this time */
359                 return -1;
360         }
361
362         /* for some reason the channel is not locked in channel.c when this function is called */
363         if (!(p = ast_channel_tech_pvt(ast))) {
364                 return -1;
365         }
366
367         ao2_lock(p);
368         if (!(tmp = IS_OUTBOUND(ast, p) ? p->owner : p->chan)) {
369                 ao2_unlock(p);
370                 return -1;
371         }
372         ast_channel_ref(tmp);
373         ao2_unlock(p);
374         ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
375
376         ast_channel_lock(tmp);
377         if (!(bridged = ast_bridged_channel(tmp))) {
378                 res = -1;
379                 ast_channel_unlock(tmp);
380                 goto query_cleanup;
381         }
382         ast_channel_ref(bridged);
383         ast_channel_unlock(tmp);
384
385 query_cleanup:
386         if (bridged) {
387                 res = ast_channel_queryoption(bridged, option, data, datalen, 0);
388                 bridged = ast_channel_unref(bridged);
389         }
390         if (tmp) {
391                 tmp = ast_channel_unref(tmp);
392         }
393         ast_channel_lock(ast); /* Lock back before we leave */
394
395         return res;
396 }
397
398 /*! \brief queue a frame on a to either the p->owner or p->chan
399  *
400  * \note the local_pvt MUST have it's ref count bumped before entering this function and
401  * decremented after this function is called.  This is a side effect of the deadlock
402  * avoidance that is necessary to lock 2 channels and a tech_pvt.  Without a ref counted
403  * local_pvt, it is impossible to guarantee it will not be destroyed by another thread
404  * during deadlock avoidance.
405  */
406 static int local_queue_frame(struct local_pvt *p, int isoutbound, struct ast_frame *f,
407         struct ast_channel *us, int us_locked)
408 {
409         struct ast_channel *other = NULL;
410
411         /* Recalculate outbound channel */
412         other = isoutbound ? p->owner : p->chan;
413
414         if (!other) {
415                 return 0;
416         }
417
418         /* do not queue frame if generator is on both local channels */
419         if (us && ast_channel_generator(us) && ast_channel_generator(other)) {
420                 return 0;
421         }
422
423         /* grab a ref on the channel before unlocking the pvt,
424          * other can not go away from us now regardless of locking */
425         ast_channel_ref(other);
426         if (us && us_locked) {
427                 ast_channel_unlock(us);
428         }
429         ao2_unlock(p);
430
431         if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
432                 ast_setstate(other, AST_STATE_RINGING);
433         }
434         ast_queue_frame(other, f);
435
436         other = ast_channel_unref(other);
437         if (us && us_locked) {
438                 ast_channel_lock(us);
439         }
440         ao2_lock(p);
441
442         return 0;
443 }
444
445 static int local_answer(struct ast_channel *ast)
446 {
447         struct local_pvt *p = ast_channel_tech_pvt(ast);
448         int isoutbound;
449         int res = -1;
450
451         if (!p) {
452                 return -1;
453         }
454
455         ao2_lock(p);
456         ao2_ref(p, 1);
457         isoutbound = IS_OUTBOUND(ast, p);
458         if (isoutbound) {
459                 /* Pass along answer since somebody answered us */
460                 struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
461                 res = local_queue_frame(p, isoutbound, &answer, ast, 1);
462         } else {
463                 ast_log(LOG_WARNING, "Huh?  Local is being asked to answer?\n");
464         }
465         ao2_unlock(p);
466         ao2_ref(p, -1);
467         return res;
468 }
469
470 /*!
471  * \internal
472  * \note This function assumes that we're only called from the "outbound" local channel side
473  *
474  * \note it is assummed p is locked and reffed before entering this function
475  */
476 static void check_bridge(struct local_pvt *p)
477 {
478         struct ast_channel_monitor *tmp;
479         struct ast_channel *chan = NULL;
480         struct ast_channel *bridged_chan = NULL;
481
482         /* Do a few conditional checks early on just to see if this optimization is possible */
483         if (ast_test_flag(p, LOCAL_NO_OPTIMIZATION)) {
484                 return;
485         }
486         if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || !p->chan || !p->owner) {
487                 return;
488         }
489
490         /* Safely get the channel bridged to p->chan */
491         chan = ast_channel_ref(p->chan);
492
493         ao2_unlock(p); /* don't call bridged channel with the pvt locked */
494         bridged_chan = ast_bridged_channel(chan);
495         ao2_lock(p);
496
497         chan = ast_channel_unref(chan);
498
499         /* since we had to unlock p to get the bridged chan, validate our
500          * data once again and verify the bridged channel is what we expect
501          * it to be in order to perform this optimization */
502         if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || !p->owner || !p->chan || (ast_channel_internal_bridged_channel(p->chan) != bridged_chan)) {
503                 return;
504         }
505
506         /* only do the masquerade if we are being called on the outbound channel,
507            if it has been bridged to another channel and if there are no pending
508            frames on the owner channel (because they would be transferred to the
509            outbound channel during the masquerade)
510         */
511         if (ast_channel_internal_bridged_channel(p->chan) /* Not ast_bridged_channel!  Only go one step! */ && AST_LIST_EMPTY(ast_channel_readq(p->owner))) {
512                 /* Masquerade bridged channel into owner */
513                 /* Lock everything we need, one by one, and give up if
514                    we can't get everything.  Remember, we'll get another
515                    chance in just a little bit */
516                 if (!ast_channel_trylock(ast_channel_internal_bridged_channel(p->chan))) {
517                         if (!ast_check_hangup(ast_channel_internal_bridged_channel(p->chan))) {
518                                 if (!ast_channel_trylock(p->owner)) {
519                                         if (!ast_check_hangup(p->owner)) {
520                                                 if (ast_channel_monitor(p->owner) && !ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan))) {
521                                                         /* If a local channel is being monitored, we don't want a masquerade
522                                                          * to cause the monitor to go away. Since the masquerade swaps the monitors,
523                                                          * pre-swapping the monitors before the masquerade will ensure that the monitor
524                                                          * ends up where it is expected.
525                                                          */
526                                                         tmp = ast_channel_monitor(p->owner);
527                                                         ast_channel_monitor_set(p->owner, ast_channel_monitor(ast_channel_internal_bridged_channel(p->chan)));
528                                                         ast_channel_monitor_set(ast_channel_internal_bridged_channel(p->chan), tmp);
529                                                 }
530                                                 if (ast_channel_audiohooks(p->chan)) {
531                                                         struct ast_audiohook_list *audiohooks_swapper;
532                                                         audiohooks_swapper = ast_channel_audiohooks(p->chan);
533                                                         ast_channel_audiohooks_set(p->chan, ast_channel_audiohooks(p->owner));
534                                                         ast_channel_audiohooks_set(p->owner, audiohooks_swapper);
535                                                 }
536
537                                                 /* If any Caller ID was set, preserve it after masquerade like above. We must check
538                                                  * to see if Caller ID was set because otherwise we'll mistakingly copy info not
539                                                  * set from the dialplan and will overwrite the real channel Caller ID. The reason
540                                                  * for this whole preswapping action is because the Caller ID is set on the channel
541                                                  * thread (which is the to be masqueraded away local channel) before both local
542                                                  * channels are optimized away.
543                                                  */
544                                                 if (ast_channel_caller(p->owner)->id.name.valid || ast_channel_caller(p->owner)->id.number.valid
545                                                         || ast_channel_caller(p->owner)->id.subaddress.valid || ast_channel_caller(p->owner)->ani.name.valid
546                                                         || ast_channel_caller(p->owner)->ani.number.valid || ast_channel_caller(p->owner)->ani.subaddress.valid) {
547                                                         SWAP(*ast_channel_caller(p->owner), *ast_channel_caller(ast_channel_internal_bridged_channel(p->chan)));
548                                                 }
549                                                 if (ast_channel_redirecting(p->owner)->from.name.valid || ast_channel_redirecting(p->owner)->from.number.valid
550                                                         || ast_channel_redirecting(p->owner)->from.subaddress.valid || ast_channel_redirecting(p->owner)->to.name.valid
551                                                         || ast_channel_redirecting(p->owner)->to.number.valid || ast_channel_redirecting(p->owner)->to.subaddress.valid) {
552                                                         SWAP(*ast_channel_redirecting(p->owner), *ast_channel_redirecting(ast_channel_internal_bridged_channel(p->chan)));
553                                                 }
554                                                 if (ast_channel_dialed(p->owner)->number.str || ast_channel_dialed(p->owner)->subaddress.valid) {
555                                                         SWAP(*ast_channel_dialed(p->owner), *ast_channel_dialed(ast_channel_internal_bridged_channel(p->chan)));
556                                                 }
557
558
559                                                 ast_app_group_update(p->chan, p->owner);
560                                                 ast_channel_masquerade(p->owner, ast_channel_internal_bridged_channel(p->chan));
561                                                 ast_set_flag(p, LOCAL_ALREADY_MASQED);
562                                         }
563                                         ast_channel_unlock(p->owner);
564                                 }
565                         }
566                         ast_channel_unlock(ast_channel_internal_bridged_channel(p->chan));
567                 }
568         }
569 }
570
571 static struct ast_frame  *local_read(struct ast_channel *ast)
572 {
573         return &ast_null_frame;
574 }
575
576 static int local_write(struct ast_channel *ast, struct ast_frame *f)
577 {
578         struct local_pvt *p = ast_channel_tech_pvt(ast);
579         int res = -1;
580         int isoutbound;
581
582         if (!p) {
583                 return -1;
584         }
585
586         /* Just queue for delivery to the other side */
587         ao2_ref(p, 1); /* ref for local_queue_frame */
588         ao2_lock(p);
589         isoutbound = IS_OUTBOUND(ast, p);
590
591         if (isoutbound && f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) {
592                 check_bridge(p);
593         }
594
595         if (!ast_test_flag(p, LOCAL_ALREADY_MASQED)) {
596                 res = local_queue_frame(p, isoutbound, f, ast, 1);
597         } else {
598                 ast_debug(1, "Not posting to queue since already masked on '%s'\n", ast_channel_name(ast));
599                 res = 0;
600         }
601         ao2_unlock(p);
602         ao2_ref(p, -1);
603
604         return res;
605 }
606
607 static int local_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
608 {
609         struct local_pvt *p = ast_channel_tech_pvt(newchan);
610
611         if (!p) {
612                 return -1;
613         }
614
615         ao2_lock(p);
616
617         if ((p->owner != oldchan) && (p->chan != oldchan)) {
618                 ast_log(LOG_WARNING, "Old channel wasn't %p but was %p/%p\n", oldchan, p->owner, p->chan);
619                 ao2_unlock(p);
620                 return -1;
621         }
622         if (p->owner == oldchan) {
623                 p->owner = newchan;
624         } else {
625                 p->chan = newchan;
626         }
627
628         /* Do not let a masquerade cause a Local channel to be bridged to itself! */
629         if (!ast_check_hangup(newchan) && ((p->owner && ast_channel_internal_bridged_channel(p->owner) == p->chan) || (p->chan && ast_channel_internal_bridged_channel(p->chan) == p->owner))) {
630                 ast_log(LOG_WARNING, "You can not bridge a Local channel to itself!\n");
631                 ao2_unlock(p);
632                 ast_queue_hangup(newchan);
633                 return -1;
634         }
635
636         ao2_unlock(p);
637         return 0;
638 }
639
640 static int local_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
641 {
642         struct local_pvt *p = ast_channel_tech_pvt(ast);
643         int res = 0;
644         struct ast_frame f = { AST_FRAME_CONTROL, };
645         int isoutbound;
646
647         if (!p) {
648                 return -1;
649         }
650
651         ao2_ref(p, 1); /* ref for local_queue_frame */
652
653         /* If this is an MOH hold or unhold, do it on the Local channel versus real channel */
654         if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_HOLD) {
655                 ast_moh_start(ast, data, NULL);
656         } else if (!ast_test_flag(p, LOCAL_MOH_PASSTHRU) && condition == AST_CONTROL_UNHOLD) {
657                 ast_moh_stop(ast);
658         } else if (condition == AST_CONTROL_CONNECTED_LINE || condition == AST_CONTROL_REDIRECTING) {
659                 struct ast_channel *this_channel;
660                 struct ast_channel *the_other_channel;
661                 /* A connected line update frame may only contain a partial amount of data, such
662                  * as just a source, or just a ton, and not the full amount of information. However,
663                  * the collected information is all stored in the outgoing channel's connectedline
664                  * structure, so when receiving a connected line update on an outgoing local channel,
665                  * we need to transmit the collected connected line information instead of whatever
666                  * happens to be in this control frame. The same applies for redirecting information, which
667                  * is why it is handled here as well.*/
668                 ao2_lock(p);
669                 isoutbound = IS_OUTBOUND(ast, p);
670                 if (isoutbound) {
671                         this_channel = p->chan;
672                         the_other_channel = p->owner;
673                 } else {
674                         this_channel = p->owner;
675                         the_other_channel = p->chan;
676                 }
677                 if (the_other_channel) {
678                         unsigned char frame_data[1024];
679                         if (condition == AST_CONTROL_CONNECTED_LINE) {
680                                 if (isoutbound) {
681                                         ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel), ast_channel_connected(this_channel));
682                                 }
683                                 f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data), ast_channel_connected(this_channel), NULL);
684                         } else {
685                                 f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data), ast_channel_redirecting(this_channel), NULL);
686                         }
687                         f.subclass.integer = condition;
688                         f.data.ptr = frame_data;
689                         res = local_queue_frame(p, isoutbound, &f, ast, 1);
690                 }
691                 ao2_unlock(p);
692         } else {
693                 /* Queue up a frame representing the indication as a control frame */
694                 ao2_lock(p);
695                 isoutbound = IS_OUTBOUND(ast, p);
696                 f.subclass.integer = condition;
697                 f.data.ptr = (void*)data;
698                 f.datalen = datalen;
699                 res = local_queue_frame(p, isoutbound, &f, ast, 1);
700                 ao2_unlock(p);
701         }
702
703         ao2_ref(p, -1);
704         return res;
705 }
706
707 static int local_digit_begin(struct ast_channel *ast, char digit)
708 {
709         struct local_pvt *p = ast_channel_tech_pvt(ast);
710         int res = -1;
711         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
712         int isoutbound;
713
714         if (!p) {
715                 return -1;
716         }
717
718         ao2_ref(p, 1); /* ref for local_queue_frame */
719         ao2_lock(p);
720         isoutbound = IS_OUTBOUND(ast, p);
721         f.subclass.integer = digit;
722         res = local_queue_frame(p, isoutbound, &f, ast, 0);
723         ao2_unlock(p);
724         ao2_ref(p, -1);
725
726         return res;
727 }
728
729 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
730 {
731         struct local_pvt *p = ast_channel_tech_pvt(ast);
732         int res = -1;
733         struct ast_frame f = { AST_FRAME_DTMF_END, };
734         int isoutbound;
735
736         if (!p) {
737                 return -1;
738         }
739
740         ao2_ref(p, 1); /* ref for local_queue_frame */
741         ao2_lock(p);
742         isoutbound = IS_OUTBOUND(ast, p);
743         f.subclass.integer = digit;
744         f.len = duration;
745         res = local_queue_frame(p, isoutbound, &f, ast, 0);
746         ao2_unlock(p);
747         ao2_ref(p, -1);
748
749         return res;
750 }
751
752 static int local_sendtext(struct ast_channel *ast, const char *text)
753 {
754         struct local_pvt *p = ast_channel_tech_pvt(ast);
755         int res = -1;
756         struct ast_frame f = { AST_FRAME_TEXT, };
757         int isoutbound;
758
759         if (!p) {
760                 return -1;
761         }
762
763         ao2_lock(p);
764         ao2_ref(p, 1); /* ref for local_queue_frame */
765         isoutbound = IS_OUTBOUND(ast, p);
766         f.data.ptr = (char *) text;
767         f.datalen = strlen(text) + 1;
768         res = local_queue_frame(p, isoutbound, &f, ast, 0);
769         ao2_unlock(p);
770         ao2_ref(p, -1);
771         return res;
772 }
773
774 static int local_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
775 {
776         struct local_pvt *p = ast_channel_tech_pvt(ast);
777         int res = -1;
778         struct ast_frame f = { AST_FRAME_HTML, };
779         int isoutbound;
780
781         if (!p) {
782                 return -1;
783         }
784
785         ao2_lock(p);
786         ao2_ref(p, 1); /* ref for local_queue_frame */
787         isoutbound = IS_OUTBOUND(ast, p);
788         f.subclass.integer = subclass;
789         f.data.ptr = (char *)data;
790         f.datalen = datalen;
791         res = local_queue_frame(p, isoutbound, &f, ast, 0);
792         ao2_unlock(p);
793         ao2_ref(p, -1);
794
795         return res;
796 }
797
798 /*! \brief Initiate new call, part of PBX interface
799  *         dest is the dial string */
800 static int local_call(struct ast_channel *ast, const char *dest, int timeout)
801 {
802         struct local_pvt *p = ast_channel_tech_pvt(ast);
803         int pvt_locked = 0;
804
805         struct ast_channel *owner = NULL;
806         struct ast_channel *chan = NULL;
807         int res;
808         struct ast_var_t *varptr = NULL, *new;
809         size_t len, namelen;
810         char *reduced_dest = ast_strdupa(dest);
811         char *slash;
812         const char *exten;
813         const char *context;
814
815         if (!p) {
816                 return -1;
817         }
818
819         /* since we are letting go of channel locks that were locked coming into
820          * this function, then we need to give the tech pvt a ref */
821         ao2_ref(p, 1);
822         ast_channel_unlock(ast);
823
824         awesome_locking(p, &chan, &owner);
825         pvt_locked = 1;
826
827         if (owner != ast) {
828                 res = -1;
829                 goto return_cleanup;
830         }
831
832         if (!owner || !chan) {
833                 res = -1;
834                 goto return_cleanup;
835         }
836
837         /*
838          * Note that cid_num and cid_name aren't passed in the ast_channel_alloc
839          * call, so it's done here instead.
840          *
841          * All these failure points just return -1. The individual strings will
842          * be cleared when we destroy the channel.
843          */
844         ast_party_redirecting_copy(ast_channel_redirecting(chan), ast_channel_redirecting(owner));
845
846         ast_party_dialed_copy(ast_channel_dialed(chan), ast_channel_dialed(owner));
847
848         ast_connected_line_copy_to_caller(ast_channel_caller(chan), ast_channel_connected(owner));
849         ast_connected_line_copy_from_caller(ast_channel_connected(chan), ast_channel_caller(owner));
850
851         ast_channel_language_set(chan, ast_channel_language(owner));
852         ast_channel_accountcode_set(chan, ast_channel_accountcode(owner));
853         ast_channel_musicclass_set(chan, ast_channel_musicclass(owner));
854         ast_cdr_update(chan);
855
856         ast_channel_cc_params_init(chan, ast_channel_get_cc_config_params(owner));
857
858         /* Make sure we inherit the ANSWERED_ELSEWHERE flag if it's set on the queue/dial call request in the dialplan */
859         if (ast_test_flag(ast_channel_flags(ast), AST_FLAG_ANSWERED_ELSEWHERE)) {
860                 ast_set_flag(ast_channel_flags(chan), AST_FLAG_ANSWERED_ELSEWHERE);
861         }
862
863         /* copy the channel variables from the incoming channel to the outgoing channel */
864         /* Note that due to certain assumptions, they MUST be in the same order */
865         AST_LIST_TRAVERSE(ast_channel_varshead(owner), varptr, entries) {
866                 namelen = strlen(varptr->name);
867                 len = sizeof(struct ast_var_t) + namelen + strlen(varptr->value) + 2;
868                 if ((new = ast_calloc(1, len))) {
869                         memcpy(new, varptr, len);
870                         new->value = &(new->name[0]) + namelen + 1;
871                         AST_LIST_INSERT_TAIL(ast_channel_varshead(chan), new, entries);
872                 }
873         }
874         ast_channel_datastore_inherit(owner, chan);
875         /* If the local channel has /n or /b on the end of it,
876          * we need to lop that off for our argument to setting
877          * up the CC_INTERFACES variable
878          */
879         if ((slash = strrchr(reduced_dest, '/'))) {
880                 *slash = '\0';
881         }
882         ast_set_cc_interfaces_chanvar(chan, reduced_dest);
883
884         exten = ast_strdupa(ast_channel_exten(chan));
885         context = ast_strdupa(ast_channel_context(chan));
886
887         ao2_unlock(p);
888         pvt_locked = 0;
889
890         ast_channel_unlock(chan);
891
892         if (!ast_exists_extension(chan, context, exten, 1,
893                 S_COR(ast_channel_caller(owner)->id.number.valid, ast_channel_caller(owner)->id.number.str, NULL))) {
894                 ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n", exten, context);
895                 res = -1;
896                 chan = ast_channel_unref(chan); /* we already unlocked it, so clear it hear so the cleanup label won't touch it. */
897                 goto return_cleanup;
898         }
899
900         manager_event(EVENT_FLAG_CALL, "LocalBridge",
901                       "Channel1: %s\r\n"
902                       "Channel2: %s\r\n"
903                       "Uniqueid1: %s\r\n"
904                       "Uniqueid2: %s\r\n"
905                       "Context: %s\r\n"
906                       "Exten: %s\r\n"
907                       "LocalOptimization: %s\r\n",
908                         ast_channel_name(p->owner), ast_channel_name(p->chan), ast_channel_uniqueid(p->owner), ast_channel_uniqueid(p->chan),
909                         p->context, p->exten,
910                         ast_test_flag(p, LOCAL_NO_OPTIMIZATION) ? "Yes" : "No");
911
912
913         /* Start switch on sub channel */
914         if (!(res = ast_pbx_start(chan))) {
915                 ao2_lock(p);
916                 ast_set_flag(p, LOCAL_LAUNCHED_PBX);
917                 ao2_unlock(p);
918         }
919         chan = ast_channel_unref(chan); /* chan is already unlocked, clear it here so the cleanup lable won't touch it. */
920
921 return_cleanup:
922         if (p) {
923                 if (pvt_locked) {
924                         ao2_unlock(p);
925                 }
926                 ao2_ref(p, -1);
927         }
928         if (chan) {
929                 ast_channel_unlock(chan);
930                 chan = ast_channel_unref(chan);
931         }
932
933         /* owner is supposed to be == to ast,  if it
934          * is, don't unlock it because ast must exit locked */
935         if (owner) {
936                 if (owner != ast) {
937                         ast_channel_unlock(owner);
938                         ast_channel_lock(ast);
939                 }
940                 owner = ast_channel_unref(owner);
941         } else {
942                 /* we have to exit with ast locked */
943                 ast_channel_lock(ast);
944         }
945
946         return res;
947 }
948
949 /*! \brief Hangup a call through the local proxy channel */
950 static int local_hangup(struct ast_channel *ast)
951 {
952         struct local_pvt *p = ast_channel_tech_pvt(ast);
953         int isoutbound;
954         int hangup_chan = 0;
955         int res = 0;
956         struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = ast_channel_hangupcause(ast) };
957         struct ast_channel *owner = NULL;
958         struct ast_channel *chan = NULL;
959
960         if (!p) {
961                 return -1;
962         }
963
964         /* give the pvt a ref since we are unlocking the channel. */
965         ao2_ref(p, 1);
966
967         /* the pvt isn't going anywhere, we gave it a ref */
968         ast_channel_unlock(ast);
969
970         /* lock everything */
971         awesome_locking(p, &chan, &owner);
972
973         if (ast != chan && ast != owner) {
974                 res = -1;
975                 goto local_hangup_cleanup;
976         }
977
978         isoutbound = IS_OUTBOUND(ast, p); /* just comparing pointer of ast */
979
980         if (p->chan && ast_test_flag(ast_channel_flags(ast), AST_FLAG_ANSWERED_ELSEWHERE)) {
981                 ast_set_flag(ast_channel_flags(p->chan), AST_FLAG_ANSWERED_ELSEWHERE);
982                 ast_debug(2, "This local call has the ANSWERED_ELSEWHERE flag set.\n");
983         }
984
985         if (isoutbound) {
986                 const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
987                 if ((status) && (p->owner)) {
988                         ast_channel_hangupcause_set(p->owner, ast_channel_hangupcause(p->chan));
989                         pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
990                 }
991
992                 ast_clear_flag(p, LOCAL_LAUNCHED_PBX);
993                 ast_module_user_remove(p->u_chan);
994                 p->chan = NULL;
995         } else {
996                 ast_module_user_remove(p->u_owner);
997                 if (p->chan) {
998                         ast_queue_hangup(p->chan);
999                 }
1000                 p->owner = NULL;
1001         }
1002
1003         ast_channel_tech_pvt_set(ast, NULL); /* this is one of our locked channels, doesn't matter which */
1004
1005         if (!p->owner && !p->chan) {
1006                 ao2_unlock(p);
1007                 /* Remove from list */
1008                 ao2_unlink(locals, p);
1009                 ao2_ref(p, -1);
1010                 p = NULL;
1011                 res = 0;
1012                 goto local_hangup_cleanup;
1013         }
1014         if (p->chan && !ast_test_flag(p, LOCAL_LAUNCHED_PBX)) {
1015                 /* Need to actually hangup since there is no PBX */
1016                 hangup_chan = 1;
1017         } else {
1018                 local_queue_frame(p, isoutbound, &f, NULL, 0);
1019         }
1020
1021 local_hangup_cleanup:
1022         if (p) {
1023                 ao2_unlock(p);
1024                 ao2_ref(p, -1);
1025         }
1026         if (chan) {
1027                 ast_channel_unlock(chan);
1028                 if (hangup_chan) {
1029                         ast_hangup(chan);
1030                 }
1031                 chan = ast_channel_unref(chan);
1032         }
1033         if (owner) {
1034                 ast_channel_unlock(owner);
1035                 owner = ast_channel_unref(owner);
1036         }
1037
1038         /* leave with the same stupid channel locked that came in */
1039         ast_channel_lock(ast);
1040         return res;
1041 }
1042
1043 static void local_destroy(void *obj)
1044 {
1045         struct local_pvt *pvt = obj;
1046         pvt->reqcap = ast_format_cap_destroy(pvt->reqcap);
1047 }
1048
1049 /*! \brief Create a call structure */
1050 static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
1051 {
1052         struct local_pvt *tmp = NULL;
1053         char *c = NULL, *opts = NULL;
1054
1055         if (!(tmp = ao2_alloc(sizeof(*tmp), local_destroy))) {
1056                 return NULL;
1057         }
1058         if (!(tmp->reqcap = ast_format_cap_dup(cap))) {
1059                 ao2_ref(tmp, -1);
1060                 return NULL;
1061         }
1062
1063         /* Initialize private structure information */
1064         ast_copy_string(tmp->exten, data, sizeof(tmp->exten));
1065
1066         memcpy(&tmp->jb_conf, &g_jb_conf, sizeof(tmp->jb_conf));
1067
1068         /* Look for options */
1069         if ((opts = strchr(tmp->exten, '/'))) {
1070                 *opts++ = '\0';
1071                 if (strchr(opts, 'n'))
1072                         ast_set_flag(tmp, LOCAL_NO_OPTIMIZATION);
1073                 if (strchr(opts, 'j')) {
1074                         if (ast_test_flag(tmp, LOCAL_NO_OPTIMIZATION))
1075                                 ast_set_flag(&tmp->jb_conf, AST_JB_ENABLED);
1076                         else {
1077                                 ast_log(LOG_ERROR, "You must use the 'n' option for chan_local "
1078                                         "to use the 'j' option to enable the jitterbuffer\n");
1079                         }
1080                 }
1081                 if (strchr(opts, 'b')) {
1082                         ast_set_flag(tmp, LOCAL_BRIDGE);
1083                 }
1084                 if (strchr(opts, 'm')) {
1085                         ast_set_flag(tmp, LOCAL_MOH_PASSTHRU);
1086                 }
1087         }
1088
1089         /* Look for a context */
1090         if ((c = strchr(tmp->exten, '@')))
1091                 *c++ = '\0';
1092
1093         ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
1094 #if 0
1095         /* We can't do this check here, because we don't know the CallerID yet, and
1096          * the CallerID could potentially affect what step is actually taken (or
1097          * even if that step exists). */
1098         if (!ast_exists_extension(NULL, tmp->context, tmp->exten, 1, NULL)) {
1099                 ast_log(LOG_NOTICE, "No such extension/context %s@%s creating local channel\n", tmp->exten, tmp->context);
1100                 tmp = local_pvt_destroy(tmp);
1101         } else {
1102 #endif
1103                 /* Add to list */
1104                 ao2_link(locals, tmp);
1105 #if 0
1106         }
1107 #endif
1108         return tmp; /* this is returned with a ref */
1109 }
1110
1111 /*! \brief Start new local channel */
1112 static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid)
1113 {
1114         struct ast_channel *tmp = NULL, *tmp2 = NULL;
1115         int randnum = ast_random() & 0xffff;
1116         struct ast_format fmt;
1117         const char *t;
1118         int ama;
1119
1120         /* Allocate two new Asterisk channels */
1121         /* safe accountcode */
1122         if (p->owner && ast_channel_accountcode(p->owner))
1123                 t = ast_channel_accountcode(p->owner);
1124         else
1125                 t = "";
1126
1127         if (p->owner)
1128                 ama = ast_channel_amaflags(p->owner);
1129         else
1130                 ama = 0;
1131         if (!(tmp = ast_channel_alloc(1, state, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;1", p->exten, p->context, randnum))
1132                 || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, t, p->exten, p->context, linkedid, ama, "Local/%s@%s-%04x;2", p->exten, p->context, randnum))) {
1133                 if (tmp) {
1134                         tmp = ast_channel_release(tmp);
1135                 }
1136                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
1137                 return NULL;
1138         }
1139
1140         ast_channel_tech_set(tmp, &local_tech);
1141         ast_channel_tech_set(tmp2, &local_tech);
1142
1143         ast_format_cap_copy(ast_channel_nativeformats(tmp), p->reqcap);
1144         ast_format_cap_copy(ast_channel_nativeformats(tmp2), p->reqcap);
1145
1146         /* Determine our read/write format and set it on each channel */
1147         ast_best_codec(p->reqcap, &fmt);
1148         ast_format_copy(ast_channel_writeformat(tmp), &fmt);
1149         ast_format_copy(ast_channel_writeformat(tmp2), &fmt);
1150         ast_format_copy(ast_channel_rawwriteformat(tmp), &fmt);
1151         ast_format_copy(ast_channel_rawwriteformat(tmp2), &fmt);
1152         ast_format_copy(ast_channel_readformat(tmp), &fmt);
1153         ast_format_copy(ast_channel_readformat(tmp2), &fmt);
1154         ast_format_copy(ast_channel_rawreadformat(tmp), &fmt);
1155         ast_format_copy(ast_channel_rawreadformat(tmp2), &fmt);
1156
1157         ast_channel_tech_pvt_set(tmp, p);
1158         ast_channel_tech_pvt_set(tmp2, p);
1159
1160         p->owner = tmp;
1161         p->chan = tmp2;
1162         p->u_owner = ast_module_user_add(p->owner);
1163         p->u_chan = ast_module_user_add(p->chan);
1164
1165         ast_channel_context_set(tmp, p->context);
1166         ast_channel_context_set(tmp2, p->context);
1167         ast_channel_exten_set(tmp2, p->exten);
1168         ast_channel_priority_set(tmp, 1);
1169         ast_channel_priority_set(tmp2, 1);
1170
1171         ast_jb_configure(tmp, &p->jb_conf);
1172
1173         return tmp;
1174 }
1175
1176 /*! \brief Part of PBX interface */
1177 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
1178 {
1179         struct local_pvt *p;
1180         struct ast_channel *chan;
1181
1182         /* Allocate a new private structure and then Asterisk channel */
1183         p = local_alloc(data, cap);
1184         if (!p) {
1185                 return NULL;
1186         }
1187         chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
1188         if (!chan) {
1189                 ao2_unlink(locals, p);
1190         } else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
1191                 ao2_unlink(locals, p);
1192                 p->owner = ast_channel_release(p->owner);
1193                 ast_module_user_remove(p->u_owner);
1194                 p->chan = ast_channel_release(p->chan);
1195                 ast_module_user_remove(p->u_chan);
1196                 chan = NULL;
1197         }
1198         ao2_ref(p, -1); /* kill the ref from the alloc */
1199
1200         return chan;
1201 }
1202
1203 /*! \brief CLI command "local show channels" */
1204 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
1205 {
1206         struct local_pvt *p = NULL;
1207         struct ao2_iterator it;
1208
1209         switch (cmd) {
1210         case CLI_INIT:
1211                 e->command = "local show channels";
1212                 e->usage =
1213                         "Usage: local show channels\n"
1214                         "       Provides summary information on active local proxy channels.\n";
1215                 return NULL;
1216         case CLI_GENERATE:
1217                 return NULL;
1218         }
1219
1220         if (a->argc != 3) {
1221                 return CLI_SHOWUSAGE;
1222         }
1223
1224         if (ao2_container_count(locals) == 0) {
1225                 ast_cli(a->fd, "No local channels in use\n");
1226                 return RESULT_SUCCESS;
1227         }
1228
1229         it = ao2_iterator_init(locals, 0);
1230         while ((p = ao2_iterator_next(&it))) {
1231                 ao2_lock(p);
1232                 ast_cli(a->fd, "%s -- %s@%s\n", p->owner ? ast_channel_name(p->owner) : "<unowned>", p->exten, p->context);
1233                 ao2_unlock(p);
1234                 ao2_ref(p, -1);
1235         }
1236         ao2_iterator_destroy(&it);
1237
1238         return CLI_SUCCESS;
1239 }
1240
1241 static struct ast_cli_entry cli_local[] = {
1242         AST_CLI_DEFINE(locals_show, "List status of local channels"),
1243 };
1244
1245 static int manager_optimize_away(struct mansession *s, const struct message *m)
1246 {
1247         const char *channel;
1248         struct local_pvt *p, *tmp = NULL;
1249         struct ast_channel *c;
1250         int found = 0;
1251         struct ao2_iterator it;
1252
1253         channel = astman_get_header(m, "Channel");
1254
1255         if (ast_strlen_zero(channel)) {
1256                 astman_send_error(s, m, "'Channel' not specified.");
1257                 return 0;
1258         }
1259
1260         c = ast_channel_get_by_name(channel);
1261         if (!c) {
1262                 astman_send_error(s, m, "Channel does not exist.");
1263                 return 0;
1264         }
1265
1266         p = ast_channel_tech_pvt(c);
1267         ast_channel_unref(c);
1268         c = NULL;
1269
1270         it = ao2_iterator_init(locals, 0);
1271         while ((tmp = ao2_iterator_next(&it))) {
1272                 if (tmp == p) {
1273                         ao2_lock(tmp);
1274                         found = 1;
1275                         ast_clear_flag(tmp, LOCAL_NO_OPTIMIZATION);
1276                         ao2_unlock(tmp);
1277                         ao2_ref(tmp, -1);
1278                         break;
1279                 }
1280                 ao2_ref(tmp, -1);
1281         }
1282         ao2_iterator_destroy(&it);
1283
1284         if (found) {
1285                 astman_send_ack(s, m, "Queued channel to be optimized away");
1286         } else {
1287                 astman_send_error(s, m, "Unable to find channel");
1288         }
1289
1290         return 0;
1291 }
1292
1293
1294 static int locals_cmp_cb(void *obj, void *arg, int flags)
1295 {
1296         return (obj == arg) ? CMP_MATCH : 0;
1297 }
1298
1299 /*! \brief Load module into PBX, register channel */
1300 static int load_module(void)
1301 {
1302         if (!(local_tech.capabilities = ast_format_cap_alloc())) {
1303                 return AST_MODULE_LOAD_FAILURE;
1304         }
1305         ast_format_cap_add_all(local_tech.capabilities);
1306
1307         if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
1308                 ast_format_cap_destroy(local_tech.capabilities);
1309                 return AST_MODULE_LOAD_FAILURE;
1310         }
1311
1312         /* Make sure we can register our channel type */
1313         if (ast_channel_register(&local_tech)) {
1314                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
1315                 ao2_ref(locals, -1);
1316                 ast_format_cap_destroy(local_tech.capabilities);
1317                 return AST_MODULE_LOAD_FAILURE;
1318         }
1319         ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
1320         ast_manager_register_xml("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
1321
1322         return AST_MODULE_LOAD_SUCCESS;
1323 }
1324
1325 /*! \brief Unload the local proxy channel from Asterisk */
1326 static int unload_module(void)
1327 {
1328         struct local_pvt *p = NULL;
1329         struct ao2_iterator it;
1330
1331         /* First, take us out of the channel loop */
1332         ast_cli_unregister_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
1333         ast_manager_unregister("LocalOptimizeAway");
1334         ast_channel_unregister(&local_tech);
1335
1336         it = ao2_iterator_init(locals, 0);
1337         while ((p = ao2_iterator_next(&it))) {
1338                 if (p->owner) {
1339                         ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
1340                 }
1341                 ao2_ref(p, -1);
1342         }
1343         ao2_iterator_destroy(&it);
1344         ao2_ref(locals, -1);
1345
1346         ast_format_cap_destroy(local_tech.capabilities);
1347         return 0;
1348 }
1349
1350 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Local Proxy Channel (Note: used internally by other modules)",
1351                 .load = load_module,
1352                 .unload = unload_module,
1353                 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
1354         );