Make local channels use ast_channel_move() instead of the inlined version.
[asterisk/asterisk.git] / main / core_local.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013 Digium, Inc.
5  *
6  * Richard Mudgett <rmudgett@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 /*!
20  * \file
21  * \brief Local proxy channel driver.
22  *
23  * \author Richard Mudgett <rmudgett@digium.com>
24  *
25  * See Also:
26  * \arg \ref AstCREDITS
27  */
28
29 /*** MODULEINFO
30         <support_level>core</support_level>
31  ***/
32
33
34 #include "asterisk.h"
35
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
37
38 /* ------------------------------------------------------------------- */
39
40 #include "asterisk/channel.h"
41 #include "asterisk/pbx.h"
42 #include "asterisk/cli.h"
43 #include "asterisk/manager.h"
44 #include "asterisk/devicestate.h"
45 #include "asterisk/astobj2.h"
46 #include "asterisk/bridging.h"
47 #include "asterisk/core_unreal.h"
48 #include "asterisk/core_local.h"
49 #include "asterisk/_private.h"
50
51 /*** DOCUMENTATION
52         <manager name="LocalOptimizeAway" language="en_US">
53                 <synopsis>
54                         Optimize away a local channel when possible.
55                 </synopsis>
56                 <syntax>
57                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
58                         <parameter name="Channel" required="true">
59                                 <para>The channel name to optimize away.</para>
60                         </parameter>
61                 </syntax>
62                 <description>
63                         <para>A local channel created with "/n" will not automatically optimize away.
64                         Calling this command on the local channel will clear that flag and allow
65                         it to optimize away if it's bridged or when it becomes bridged.</para>
66                 </description>
67         </manager>
68  ***/
69
70 static const char tdesc[] = "Local Proxy Channel Driver";
71
72 static struct ao2_container *locals;
73
74 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
75 static int local_call(struct ast_channel *ast, const char *dest, int timeout);
76 static int local_hangup(struct ast_channel *ast);
77 static int local_devicestate(const char *data);
78
79 /* PBX interface structure for channel registration */
80 static struct ast_channel_tech local_tech = {
81         .type = "Local",
82         .description = tdesc,
83         .requester = local_request,
84         .send_digit_begin = ast_unreal_digit_begin,
85         .send_digit_end = ast_unreal_digit_end,
86         .call = local_call,
87         .hangup = local_hangup,
88         .answer = ast_unreal_answer,
89         .read = ast_unreal_read,
90         .write = ast_unreal_write,
91         .write_video = ast_unreal_write,
92         .exception = ast_unreal_read,
93         .indicate = ast_unreal_indicate,
94         .fixup = ast_unreal_fixup,
95         .send_html = ast_unreal_sendhtml,
96         .send_text = ast_unreal_sendtext,
97         .devicestate = local_devicestate,
98         .queryoption = ast_unreal_queryoption,
99         .setoption = ast_unreal_setoption,
100 };
101
102 /*! What to do with the ;2 channel when ast_call() happens. */
103 enum local_call_action {
104         /* The ast_call() will run dialplan on the ;2 channel. */
105         LOCAL_CALL_ACTION_DIALPLAN,
106         /* The ast_call() will impart the ;2 channel into a bridge. */
107         LOCAL_CALL_ACTION_BRIDGE,
108         /* The ast_call() will masquerade the ;2 channel into a channel. */
109         LOCAL_CALL_ACTION_MASQUERADE,
110 };
111
112 /*! Join a bridge on ast_call() parameters. */
113 struct local_bridge {
114         /*! Bridge to join. */
115         struct ast_bridge *join;
116         /*! Channel to swap with when joining bridge. */
117         struct ast_channel *swap;
118         /*! Features that are specific to this channel when pushed into the bridge. */
119         struct ast_bridge_features *features;
120 };
121
122 /*!
123  * \brief the local pvt structure for all channels
124  *
125  * The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
126  *
127  * ast_chan owner -> local_pvt -> ast_chan chan
128  */
129 struct local_pvt {
130         /*! Unreal channel driver base class values. */
131         struct ast_unreal_pvt base;
132         /*! Additional action arguments */
133         union {
134                 /*! Make ;2 join a bridge on ast_call(). */
135                 struct local_bridge bridge;
136                 /*! Make ;2 masquerade into this channel on ast_call(). */
137                 struct ast_channel *masq;
138         } action;
139         /*! What to do with the ;2 channel on ast_call(). */
140         enum local_call_action type;
141         /*! Context to call */
142         char context[AST_MAX_CONTEXT];
143         /*! Extension to call */
144         char exten[AST_MAX_EXTENSION];
145 };
146
147 struct ast_channel *ast_local_get_peer(struct ast_channel *ast)
148 {
149         struct local_pvt *p = ast_channel_tech_pvt(ast);
150         struct local_pvt *found;
151         struct ast_channel *peer;
152
153         if (!p) {
154                 return NULL;
155         }
156
157         found = p ? ao2_find(locals, p, 0) : NULL;
158         if (!found) {
159                 /* ast is either not a local channel or it has alredy been hungup */
160                 return NULL;
161         }
162         ao2_lock(found);
163         if (ast == p->base.owner) {
164                 peer = p->base.chan;
165         } else if (ast == p->base.chan) {
166                 peer = p->base.owner;
167         } else {
168                 peer = NULL;
169         }
170         if (peer) {
171                 ast_channel_ref(peer);
172         }
173         ao2_unlock(found);
174         ao2_ref(found, -1);
175         return peer;
176 }
177
178 /*! \brief Adds devicestate to local channels */
179 static int local_devicestate(const char *data)
180 {
181         int is_inuse = 0;
182         int res = AST_DEVICE_INVALID;
183         char *exten = ast_strdupa(data);
184         char *context;
185         char *opts;
186         struct local_pvt *lp;
187         struct ao2_iterator it;
188
189         /* Strip options if they exist */
190         opts = strchr(exten, '/');
191         if (opts) {
192                 *opts = '\0';
193         }
194
195         context = strchr(exten, '@');
196         if (!context) {
197                 ast_log(LOG_WARNING,
198                         "Someone used Local/%s somewhere without a @context. This is bad.\n", data);
199                 return AST_DEVICE_INVALID;
200         }
201         *context++ = '\0';
202
203         it = ao2_iterator_init(locals, 0);
204         for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) {
205                 ao2_lock(lp);
206                 if (!strcmp(exten, lp->exten)
207                         && !strcmp(context, lp->context)) {
208                         res = AST_DEVICE_NOT_INUSE;
209                         if (lp->base.owner
210                                 && ast_test_flag(&lp->base, AST_UNREAL_CARETAKER_THREAD)) {
211                                 is_inuse = 1;
212                         }
213                 }
214                 ao2_unlock(lp);
215                 if (is_inuse) {
216                         res = AST_DEVICE_INUSE;
217                         ao2_ref(lp, -1);
218                         break;
219                 }
220         }
221         ao2_iterator_destroy(&it);
222
223         if (res == AST_DEVICE_INVALID) {
224                 ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
225                 if (ast_exists_extension(NULL, context, exten, 1, NULL)) {
226                         res = AST_DEVICE_NOT_INUSE;
227                 }
228         }
229
230         return res;
231 }
232
233 /*!
234  * \internal
235  * \brief Post the LocalBridge AMI event.
236  * \since 12.0.0
237  *
238  * \param p local_pvt to raise the bridge event.
239  *
240  * \return Nothing
241  */
242 static void local_bridge_event(struct local_pvt *p)
243 {
244         ao2_lock(p);
245         /*** DOCUMENTATION
246                 <managerEventInstance>
247                         <synopsis>Raised when two halves of a Local Channel form a bridge.</synopsis>
248                         <syntax>
249                                 <parameter name="Channel1">
250                                         <para>The name of the Local Channel half that bridges to another channel.</para>
251                                 </parameter>
252                                 <parameter name="Channel2">
253                                         <para>The name of the Local Channel half that executes the dialplan.</para>
254                                 </parameter>
255                                 <parameter name="Context">
256                                         <para>The context in the dialplan that Channel2 starts in.</para>
257                                 </parameter>
258                                 <parameter name="Exten">
259                                         <para>The extension in the dialplan that Channel2 starts in.</para>
260                                 </parameter>
261                                 <parameter name="LocalOptimization">
262                                         <enumlist>
263                                                 <enum name="Yes"/>
264                                                 <enum name="No"/>
265                                         </enumlist>
266                                 </parameter>
267                         </syntax>
268                 </managerEventInstance>
269         ***/
270         manager_event(EVENT_FLAG_CALL, "LocalBridge",
271                 "Channel1: %s\r\n"
272                 "Channel2: %s\r\n"
273                 "Uniqueid1: %s\r\n"
274                 "Uniqueid2: %s\r\n"
275                 "Context: %s\r\n"
276                 "Exten: %s\r\n"
277                 "LocalOptimization: %s\r\n",
278                 ast_channel_name(p->base.owner), ast_channel_name(p->base.chan),
279                 ast_channel_uniqueid(p->base.owner), ast_channel_uniqueid(p->base.chan),
280                 p->context, p->exten,
281                 ast_test_flag(&p->base, AST_UNREAL_NO_OPTIMIZATION) ? "Yes" : "No");
282         ao2_unlock(p);
283 }
284
285 int ast_local_setup_bridge(struct ast_channel *ast, struct ast_bridge *bridge, struct ast_channel *swap, struct ast_bridge_features *features)
286 {
287         struct local_pvt *p;
288         struct local_pvt *found;
289         int res = -1;
290
291         /* Sanity checks. */
292         if (!ast || !bridge) {
293                 ast_bridge_features_destroy(features);
294                 return -1;
295         }
296
297         ast_channel_lock(ast);
298         p = ast_channel_tech_pvt(ast);
299         ast_channel_unlock(ast);
300
301         found = p ? ao2_find(locals, p, 0) : NULL;
302         if (found) {
303                 ao2_lock(found);
304                 if (found->type == LOCAL_CALL_ACTION_DIALPLAN
305                         && found->base.owner
306                         && found->base.chan
307                         && !ast_test_flag(&found->base, AST_UNREAL_CARETAKER_THREAD)) {
308                         ao2_ref(bridge, +1);
309                         if (swap) {
310                                 ast_channel_ref(swap);
311                         }
312                         found->type = LOCAL_CALL_ACTION_BRIDGE;
313                         found->action.bridge.join = bridge;
314                         found->action.bridge.swap = swap;
315                         found->action.bridge.features = features;
316                         res = 0;
317                 } else {
318                         ast_bridge_features_destroy(features);
319                 }
320                 ao2_unlock(found);
321                 ao2_ref(found, -1);
322         }
323
324         return res;
325 }
326
327 int ast_local_setup_masquerade(struct ast_channel *ast, struct ast_channel *masq)
328 {
329         struct local_pvt *p;
330         struct local_pvt *found;
331         int res = -1;
332
333         /* Sanity checks. */
334         if (!ast || !masq) {
335                 return -1;
336         }
337
338         ast_channel_lock(ast);
339         p = ast_channel_tech_pvt(ast);
340         ast_channel_unlock(ast);
341
342         found = p ? ao2_find(locals, p, 0) : NULL;
343         if (found) {
344                 ao2_lock(found);
345                 if (found->type == LOCAL_CALL_ACTION_DIALPLAN
346                         && found->base.owner
347                         && found->base.chan
348                         && !ast_test_flag(&found->base, AST_UNREAL_CARETAKER_THREAD)) {
349                         ast_channel_ref(masq);
350                         found->type = LOCAL_CALL_ACTION_MASQUERADE;
351                         found->action.masq = masq;
352                         res = 0;
353                 }
354                 ao2_unlock(found);
355                 ao2_ref(found, -1);
356         }
357
358         return res;
359 }
360
361 /*! \brief Initiate new call, part of PBX interface
362  *         dest is the dial string */
363 static int local_call(struct ast_channel *ast, const char *dest, int timeout)
364 {
365         struct local_pvt *p = ast_channel_tech_pvt(ast);
366         int pvt_locked = 0;
367
368         struct ast_channel *owner = NULL;
369         struct ast_channel *chan = NULL;
370         int res;
371         char *reduced_dest = ast_strdupa(dest);
372         char *slash;
373         const char *chan_cid;
374
375         if (!p) {
376                 return -1;
377         }
378
379         /* since we are letting go of channel locks that were locked coming into
380          * this function, then we need to give the tech pvt a ref */
381         ao2_ref(p, 1);
382         ast_channel_unlock(ast);
383
384         ast_unreal_lock_all(&p->base, &chan, &owner);
385         pvt_locked = 1;
386
387         if (owner != ast) {
388                 res = -1;
389                 goto return_cleanup;
390         }
391
392         if (!owner || !chan) {
393                 res = -1;
394                 goto return_cleanup;
395         }
396
397         ast_unreal_call_setup(owner, chan);
398
399         /*
400          * If the local channel has /n on the end of it, we need to lop
401          * that off for our argument to setting up the CC_INTERFACES
402          * variable.
403          */
404         if ((slash = strrchr(reduced_dest, '/'))) {
405                 *slash = '\0';
406         }
407         ast_set_cc_interfaces_chanvar(chan, reduced_dest);
408
409         ao2_unlock(p);
410         pvt_locked = 0;
411
412         ast_channel_unlock(owner);
413
414         chan_cid = S_COR(ast_channel_caller(chan)->id.number.valid,
415                 ast_channel_caller(chan)->id.number.str, NULL);
416         if (chan_cid) {
417                 chan_cid = ast_strdupa(chan_cid);
418         }
419         ast_channel_unlock(chan);
420
421         res = -1;
422         switch (p->type) {
423         case LOCAL_CALL_ACTION_DIALPLAN:
424                 if (!ast_exists_extension(NULL, p->context, p->exten, 1, chan_cid)) {
425                         ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n",
426                                 p->exten, p->context);
427                 } else {
428                         local_bridge_event(p);
429
430                         /* Start switch on sub channel */
431                         res = ast_pbx_start(chan);
432                 }
433                 break;
434         case LOCAL_CALL_ACTION_BRIDGE:
435                 local_bridge_event(p);
436                 ast_answer(chan);
437                 res = ast_bridge_impart(p->action.bridge.join, chan, p->action.bridge.swap,
438                         p->action.bridge.features, 1);
439                 ao2_ref(p->action.bridge.join, -1);
440                 p->action.bridge.join = NULL;
441                 ao2_cleanup(p->action.bridge.swap);
442                 p->action.bridge.swap = NULL;
443                 p->action.bridge.features = NULL;
444                 break;
445         case LOCAL_CALL_ACTION_MASQUERADE:
446                 local_bridge_event(p);
447                 ast_answer(chan);
448                 res = ast_channel_move(p->action.masq, chan);
449                 if (!res) {
450                         /* Chan is now an orphaned zombie.  Destroy it. */
451                         ast_hangup(chan);
452                 }
453                 p->action.masq = ast_channel_unref(p->action.masq);
454                 break;
455         }
456         if (!res) {
457                 ao2_lock(p);
458                 ast_set_flag(&p->base, AST_UNREAL_CARETAKER_THREAD);
459                 ao2_unlock(p);
460         }
461
462         /* we already unlocked them, clear them here so the cleanup label won't touch them. */
463         owner = ast_channel_unref(owner);
464         chan = ast_channel_unref(chan);
465
466 return_cleanup:
467         if (p) {
468                 if (pvt_locked) {
469                         ao2_unlock(p);
470                 }
471                 ao2_ref(p, -1);
472         }
473         if (chan) {
474                 ast_channel_unlock(chan);
475                 ast_channel_unref(chan);
476         }
477
478         /*
479          * owner is supposed to be == to ast, if it is, don't unlock it
480          * because ast must exit locked
481          */
482         if (owner) {
483                 if (owner != ast) {
484                         ast_channel_unlock(owner);
485                         ast_channel_lock(ast);
486                 }
487                 ast_channel_unref(owner);
488         } else {
489                 /* we have to exit with ast locked */
490                 ast_channel_lock(ast);
491         }
492
493         return res;
494 }
495
496 /*! \brief Hangup a call through the local proxy channel */
497 static int local_hangup(struct ast_channel *ast)
498 {
499         struct local_pvt *p = ast_channel_tech_pvt(ast);
500         int res;
501
502         if (!p) {
503                 return -1;
504         }
505
506         /* give the pvt a ref to fulfill calling requirements. */
507         ao2_ref(p, +1);
508         res = ast_unreal_hangup(&p->base, ast);
509         if (!res) {
510                 int unlink;
511
512                 ao2_lock(p);
513                 unlink = !p->base.owner && !p->base.chan;
514                 ao2_unlock(p);
515                 if (unlink) {
516                         ao2_unlink(locals, p);
517                 }
518         }
519         ao2_ref(p, -1);
520
521         return res;
522 }
523
524 /*!
525  * \internal
526  * \brief struct local_pvt destructor.
527  *
528  * \param vdoomed Object to destroy.
529  *
530  * \return Nothing
531  */
532 static void local_pvt_destructor(void *vdoomed)
533 {
534         struct local_pvt *doomed = vdoomed;
535
536         switch (doomed->type) {
537         case LOCAL_CALL_ACTION_DIALPLAN:
538                 break;
539         case LOCAL_CALL_ACTION_BRIDGE:
540                 ao2_cleanup(doomed->action.bridge.join);
541                 ao2_cleanup(doomed->action.bridge.swap);
542                 ast_bridge_features_destroy(doomed->action.bridge.features);
543                 break;
544         case LOCAL_CALL_ACTION_MASQUERADE:
545                 ao2_cleanup(doomed->action.masq);
546                 break;
547         }
548         ast_unreal_destructor(&doomed->base);
549 }
550
551 /*! \brief Create a call structure */
552 static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
553 {
554         struct local_pvt *pvt;
555         char *parse;
556         char *context;
557         char *opts;
558
559         pvt = (struct local_pvt *) ast_unreal_alloc(sizeof(*pvt), local_pvt_destructor, cap);
560         if (!pvt) {
561                 return NULL;
562         }
563
564         parse = ast_strdupa(data);
565
566         /*
567          * Local channels intercept MOH by default.
568          *
569          * This is a silly default because it represents state held by
570          * the local channels.  Unless local channel optimization is
571          * disabled, the state will dissapear when the local channels
572          * optimize out.
573          */
574         ast_set_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
575
576         /* Look for options */
577         if ((opts = strchr(parse, '/'))) {
578                 *opts++ = '\0';
579                 if (strchr(opts, 'n')) {
580                         ast_set_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION);
581                 }
582                 if (strchr(opts, 'j')) {
583                         if (ast_test_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION)) {
584                                 ast_set_flag(&pvt->base.jb_conf, AST_JB_ENABLED);
585                         } else {
586                                 ast_log(LOG_ERROR, "You must use the 'n' option with the 'j' option to enable the jitter buffer\n");
587                         }
588                 }
589                 if (strchr(opts, 'm')) {
590                         ast_clear_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
591                 }
592         }
593
594         /* Look for a context */
595         if ((context = strchr(parse, '@'))) {
596                 *context++ = '\0';
597         }
598
599         ast_copy_string(pvt->context, S_OR(context, "default"), sizeof(pvt->context));
600         ast_copy_string(pvt->exten, parse, sizeof(pvt->exten));
601         snprintf(pvt->base.name, sizeof(pvt->base.name), "%s@%s", pvt->exten, pvt->context);
602
603         return pvt; /* this is returned with a ref */
604 }
605
606 /*! \brief Part of PBX interface */
607 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
608 {
609         struct local_pvt *p;
610         struct ast_channel *chan;
611         struct ast_callid *callid;
612
613         /* Allocate a new private structure and then Asterisk channels */
614         p = local_alloc(data, cap);
615         if (!p) {
616                 return NULL;
617         }
618         callid = ast_read_threadstorage_callid();
619         chan = ast_unreal_new_channels(&p->base, &local_tech, AST_STATE_DOWN, AST_STATE_RING,
620                 p->exten, p->context, requestor, callid);
621         if (chan) {
622                 ao2_link(locals, p);
623         }
624         if (callid) {
625                 ast_callid_unref(callid);
626         }
627         ao2_ref(p, -1); /* kill the ref from the alloc */
628
629         return chan;
630 }
631
632 /*! \brief CLI command "local show channels" */
633 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
634 {
635         struct local_pvt *p;
636         struct ao2_iterator it;
637
638         switch (cmd) {
639         case CLI_INIT:
640                 e->command = "local show channels";
641                 e->usage =
642                         "Usage: local show channels\n"
643                         "       Provides summary information on active local proxy channels.\n";
644                 return NULL;
645         case CLI_GENERATE:
646                 return NULL;
647         }
648
649         if (a->argc != 3) {
650                 return CLI_SHOWUSAGE;
651         }
652
653         if (ao2_container_count(locals) == 0) {
654                 ast_cli(a->fd, "No local channels in use\n");
655                 return RESULT_SUCCESS;
656         }
657
658         it = ao2_iterator_init(locals, 0);
659         while ((p = ao2_iterator_next(&it))) {
660                 ao2_lock(p);
661                 ast_cli(a->fd, "%s -- %s\n",
662                         p->base.owner ? ast_channel_name(p->base.owner) : "<unowned>",
663                         p->base.name);
664                 ao2_unlock(p);
665                 ao2_ref(p, -1);
666         }
667         ao2_iterator_destroy(&it);
668
669         return CLI_SUCCESS;
670 }
671
672 static struct ast_cli_entry cli_local[] = {
673         AST_CLI_DEFINE(locals_show, "List status of local channels"),
674 };
675
676 static int manager_optimize_away(struct mansession *s, const struct message *m)
677 {
678         const char *channel;
679         struct local_pvt *p;
680         struct local_pvt *found;
681         struct ast_channel *chan;
682
683         channel = astman_get_header(m, "Channel");
684         if (ast_strlen_zero(channel)) {
685                 astman_send_error(s, m, "'Channel' not specified.");
686                 return 0;
687         }
688
689         chan = ast_channel_get_by_name(channel);
690         if (!chan) {
691                 astman_send_error(s, m, "Channel does not exist.");
692                 return 0;
693         }
694
695         p = ast_channel_tech_pvt(chan);
696         ast_channel_unref(chan);
697
698         found = p ? ao2_find(locals, p, 0) : NULL;
699         if (found) {
700                 ao2_lock(found);
701                 ast_clear_flag(&found->base, AST_UNREAL_NO_OPTIMIZATION);
702                 ao2_unlock(found);
703                 ao2_ref(found, -1);
704                 astman_send_ack(s, m, "Queued channel to be optimized away");
705         } else {
706                 astman_send_error(s, m, "Unable to find channel");
707         }
708
709         return 0;
710 }
711
712
713 static int locals_cmp_cb(void *obj, void *arg, int flags)
714 {
715         return (obj == arg) ? CMP_MATCH : 0;
716 }
717
718 /*!
719  * \internal
720  * \brief Shutdown the local proxy channel.
721  * \since 12.0.0
722  *
723  * \return Nothing
724  */
725 static void local_shutdown(void)
726 {
727         struct local_pvt *p;
728         struct ao2_iterator it;
729
730         /* First, take us out of the channel loop */
731         ast_cli_unregister_multiple(cli_local, ARRAY_LEN(cli_local));
732         ast_manager_unregister("LocalOptimizeAway");
733         ast_channel_unregister(&local_tech);
734
735         it = ao2_iterator_init(locals, 0);
736         while ((p = ao2_iterator_next(&it))) {
737                 if (p->base.owner) {
738                         ast_softhangup(p->base.owner, AST_SOFTHANGUP_APPUNLOAD);
739                 }
740                 ao2_ref(p, -1);
741         }
742         ao2_iterator_destroy(&it);
743         ao2_ref(locals, -1);
744         locals = NULL;
745
746         ast_format_cap_destroy(local_tech.capabilities);
747 }
748
749 int ast_local_init(void)
750 {
751         if (!(local_tech.capabilities = ast_format_cap_alloc())) {
752                 return -1;
753         }
754         ast_format_cap_add_all(local_tech.capabilities);
755
756         locals = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, locals_cmp_cb);
757         if (!locals) {
758                 ast_format_cap_destroy(local_tech.capabilities);
759                 return -1;
760         }
761
762         /* Make sure we can register our channel type */
763         if (ast_channel_register(&local_tech)) {
764                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
765                 ao2_ref(locals, -1);
766                 ast_format_cap_destroy(local_tech.capabilities);
767                 return -1;
768         }
769         ast_cli_register_multiple(cli_local, ARRAY_LEN(cli_local));
770         ast_manager_register_xml_core("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
771
772         ast_register_atexit(local_shutdown);
773         return 0;
774 }