4a047032ce4f91db42fbc6c69a81a0c6bcc24268
[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/bridge.h"
47 #include "asterisk/core_unreal.h"
48 #include "asterisk/core_local.h"
49 #include "asterisk/stasis.h"
50 #include "asterisk/stasis_channels.h"
51 #include "asterisk/_private.h"
52 #include "asterisk/stasis_channels.h"
53
54 /*** DOCUMENTATION
55         <manager name="LocalOptimizeAway" language="en_US">
56                 <synopsis>
57                         Optimize away a local channel when possible.
58                 </synopsis>
59                 <syntax>
60                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
61                         <parameter name="Channel" required="true">
62                                 <para>The channel name to optimize away.</para>
63                         </parameter>
64                 </syntax>
65                 <description>
66                         <para>A local channel created with "/n" will not automatically optimize away.
67                         Calling this command on the local channel will clear that flag and allow
68                         it to optimize away if it's bridged or when it becomes bridged.</para>
69                 </description>
70         </manager>
71         <managerEvent language="en_US" name="LocalBridge">
72                 <managerEventInstance class="EVENT_FLAG_CALL">
73                         <synopsis>Raised when two halves of a Local Channel form a bridge.</synopsis>
74                         <syntax>
75                                 <channel_snapshot prefix="LocalOne"/>
76                                 <channel_snapshot prefix="LocalTwo"/>
77                                 <parameter name="Context">
78                                         <para>The context in the dialplan that Channel2 starts in.</para>
79                                 </parameter>
80                                 <parameter name="Exten">
81                                         <para>The extension in the dialplan that Channel2 starts in.</para>
82                                 </parameter>
83                                 <parameter name="LocalOptimization">
84                                         <enumlist>
85                                                 <enum name="Yes"/>
86                                                 <enum name="No"/>
87                                         </enumlist>
88                                 </parameter>
89                         </syntax>
90                 </managerEventInstance>
91         </managerEvent>
92         <managerEvent language="en_US" name="LocalOptimizationBegin">
93                 <managerEventInstance class="EVENT_FLAG_CALL">
94                         <synopsis>Raised when two halves of a Local Channel begin to optimize
95                         themselves out of the media path.</synopsis>
96                         <syntax>
97                                 <channel_snapshot prefix="LocalOne"/>
98                                 <channel_snapshot prefix="LocalTwo"/>
99                                 <channel_snapshot prefix="Source"/>
100                                 <parameter name="DestUniqueId">
101                                         <para>The unique ID of the bridge into which the local channel is optimizing.</para>
102                                 </parameter>
103                                 <parameter name="Id">
104                                         <para>Identification for the optimization operation.</para>
105                                 </parameter>
106                         </syntax>
107                         <see-also>
108                                 <ref type="managerEvent">LocalOptimizationEnd</ref>
109                                 <ref type="manager">LocalOptimizeAway</ref>
110                         </see-also>
111                 </managerEventInstance>
112         </managerEvent>
113         <managerEvent language="en_US" name="LocalOptimizationEnd">
114                 <managerEventInstance class="EVENT_FLAG_CALL">
115                         <synopsis>Raised when two halves of a Local Channel have finished optimizing
116                         themselves out of the media path.</synopsis>
117                         <syntax>
118                                 <channel_snapshot prefix="LocalOne"/>
119                                 <channel_snapshot prefix="LocalTwo"/>
120                                 <parameter name="Success">
121                                         <para>Indicates whether the local optimization succeeded.</para>
122                                 </parameter>
123                                 <parameter name="Id">
124                                         <para>Identification for the optimization operation. Matches the <replaceable>Id</replaceable>
125                                         from a previous <literal>LocalOptimizationBegin</literal></para>
126                                 </parameter>
127                         </syntax>
128                         <see-also>
129                                 <ref type="managerEvent">LocalOptimizationBegin</ref>
130                                 <ref type="manager">LocalOptimizeAway</ref>
131                         </see-also>
132                 </managerEventInstance>
133         </managerEvent>
134  ***/
135
136 static const char tdesc[] = "Local Proxy Channel Driver";
137
138 static struct ao2_container *locals;
139
140 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
141 static int local_call(struct ast_channel *ast, const char *dest, int timeout);
142 static int local_hangup(struct ast_channel *ast);
143 static int local_devicestate(const char *data);
144 static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct ast_channel *source,
145                 enum ast_unreal_channel_indicator dest, unsigned int id);
146 static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int success, unsigned int id);
147
148 static struct ast_manager_event_blob *local_message_to_ami(struct stasis_message *msg);
149
150 /*!
151  * @{ \brief Define local channel message types.
152  */
153 STASIS_MESSAGE_TYPE_DEFN(ast_local_bridge_type,
154         .to_ami = local_message_to_ami,
155         );
156 STASIS_MESSAGE_TYPE_DEFN(ast_local_optimization_begin_type,
157         .to_ami = local_message_to_ami,
158         );
159 STASIS_MESSAGE_TYPE_DEFN(ast_local_optimization_end_type,
160         .to_ami = local_message_to_ami,
161         );
162 /*! @} */
163
164 /*! \brief Callbacks from the unreal core when channel optimization occurs */
165 struct ast_unreal_pvt_callbacks local_unreal_callbacks = {
166         .optimization_started = local_optimization_started_cb,
167         .optimization_finished = local_optimization_finished_cb,
168 };
169
170 /* PBX interface structure for channel registration */
171 static struct ast_channel_tech local_tech = {
172         .type = "Local",
173         .description = tdesc,
174         .requester = local_request,
175         .send_digit_begin = ast_unreal_digit_begin,
176         .send_digit_end = ast_unreal_digit_end,
177         .call = local_call,
178         .hangup = local_hangup,
179         .answer = ast_unreal_answer,
180         .read = ast_unreal_read,
181         .write = ast_unreal_write,
182         .write_video = ast_unreal_write,
183         .exception = ast_unreal_read,
184         .indicate = ast_unreal_indicate,
185         .fixup = ast_unreal_fixup,
186         .send_html = ast_unreal_sendhtml,
187         .send_text = ast_unreal_sendtext,
188         .devicestate = local_devicestate,
189         .queryoption = ast_unreal_queryoption,
190         .setoption = ast_unreal_setoption,
191 };
192
193 /*! What to do with the ;2 channel when ast_call() happens. */
194 enum local_call_action {
195         /* The ast_call() will run dialplan on the ;2 channel. */
196         LOCAL_CALL_ACTION_DIALPLAN,
197         /* The ast_call() will impart the ;2 channel into a bridge. */
198         LOCAL_CALL_ACTION_BRIDGE,
199         /* The ast_call() will masquerade the ;2 channel into a channel. */
200         LOCAL_CALL_ACTION_MASQUERADE,
201 };
202
203 /*! Join a bridge on ast_call() parameters. */
204 struct local_bridge {
205         /*! Bridge to join. */
206         struct ast_bridge *join;
207         /*! Channel to swap with when joining bridge. */
208         struct ast_channel *swap;
209         /*! Features that are specific to this channel when pushed into the bridge. */
210         struct ast_bridge_features *features;
211 };
212
213 /*!
214  * \brief the local pvt structure for all channels
215  *
216  * The local channel pvt has two ast_chan objects - the "owner" and the "next channel", the outbound channel
217  *
218  * ast_chan owner -> local_pvt -> ast_chan chan
219  */
220 struct local_pvt {
221         /*! Unreal channel driver base class values. */
222         struct ast_unreal_pvt base;
223         /*! Additional action arguments */
224         union {
225                 /*! Make ;2 join a bridge on ast_call(). */
226                 struct local_bridge bridge;
227                 /*! Make ;2 masquerade into this channel on ast_call(). */
228                 struct ast_channel *masq;
229         } action;
230         /*! What to do with the ;2 channel on ast_call(). */
231         enum local_call_action type;
232         /*! Context to call */
233         char context[AST_MAX_CONTEXT];
234         /*! Extension to call */
235         char exten[AST_MAX_EXTENSION];
236 };
237
238 struct ast_channel *ast_local_get_peer(struct ast_channel *ast)
239 {
240         struct local_pvt *p = ast_channel_tech_pvt(ast);
241         struct local_pvt *found;
242         struct ast_channel *peer;
243
244         if (!p) {
245                 return NULL;
246         }
247
248         found = p ? ao2_find(locals, p, 0) : NULL;
249         if (!found) {
250                 /* ast is either not a local channel or it has alredy been hungup */
251                 return NULL;
252         }
253         ao2_lock(found);
254         if (ast == p->base.owner) {
255                 peer = p->base.chan;
256         } else if (ast == p->base.chan) {
257                 peer = p->base.owner;
258         } else {
259                 peer = NULL;
260         }
261         if (peer) {
262                 ast_channel_ref(peer);
263         }
264         ao2_unlock(found);
265         ao2_ref(found, -1);
266         return peer;
267 }
268
269 /*! \brief Adds devicestate to local channels */
270 static int local_devicestate(const char *data)
271 {
272         int is_inuse = 0;
273         int res = AST_DEVICE_INVALID;
274         char *exten = ast_strdupa(data);
275         char *context;
276         char *opts;
277         struct local_pvt *lp;
278         struct ao2_iterator it;
279
280         /* Strip options if they exist */
281         opts = strchr(exten, '/');
282         if (opts) {
283                 *opts = '\0';
284         }
285
286         context = strchr(exten, '@');
287         if (!context) {
288                 ast_log(LOG_WARNING,
289                         "Someone used Local/%s somewhere without a @context. This is bad.\n", data);
290                 return AST_DEVICE_INVALID;
291         }
292         *context++ = '\0';
293
294         it = ao2_iterator_init(locals, 0);
295         for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) {
296                 ao2_lock(lp);
297                 if (!strcmp(exten, lp->exten)
298                         && !strcmp(context, lp->context)) {
299                         res = AST_DEVICE_NOT_INUSE;
300                         if (lp->base.owner
301                                 && ast_test_flag(&lp->base, AST_UNREAL_CARETAKER_THREAD)) {
302                                 is_inuse = 1;
303                         }
304                 }
305                 ao2_unlock(lp);
306                 if (is_inuse) {
307                         res = AST_DEVICE_INUSE;
308                         ao2_ref(lp, -1);
309                         break;
310                 }
311         }
312         ao2_iterator_destroy(&it);
313
314         if (res == AST_DEVICE_INVALID) {
315                 ast_debug(3, "Checking if extension %s@%s exists (devicestate)\n", exten, context);
316                 if (ast_exists_extension(NULL, context, exten, 1, NULL)) {
317                         res = AST_DEVICE_NOT_INUSE;
318                 }
319         }
320
321         return res;
322 }
323
324 static struct ast_multi_channel_blob *local_channel_optimization_blob(struct local_pvt *p,
325                 struct ast_json *json_object)
326 {
327         struct ast_multi_channel_blob *payload;
328         RAII_VAR(struct ast_channel_snapshot *, local_one_snapshot, NULL, ao2_cleanup);
329         RAII_VAR(struct ast_channel_snapshot *, local_two_snapshot, NULL, ao2_cleanup);
330
331         local_one_snapshot = ast_channel_snapshot_create(p->base.owner);
332         if (!local_one_snapshot) {
333                 return NULL;
334         }
335
336         local_two_snapshot = ast_channel_snapshot_create(p->base.chan);
337         if (!local_two_snapshot) {
338                 return NULL;
339         }
340
341         payload = ast_multi_channel_blob_create(json_object);
342         if (!payload) {
343                 return NULL;
344         }
345         ast_multi_channel_blob_add_channel(payload, "1", local_one_snapshot);
346         ast_multi_channel_blob_add_channel(payload, "2", local_two_snapshot);
347
348         return payload;
349 }
350
351 /*! \brief Callback for \ref ast_unreal_pvt_callbacks \ref optimization_started_cb */
352 static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct ast_channel *source,
353                 enum ast_unreal_channel_indicator dest, unsigned int id)
354 {
355         RAII_VAR(struct ast_json *, json_object, ast_json_null(), ast_json_unref);
356         RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
357         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
358         struct local_pvt *p = (struct local_pvt *)base;
359
360         json_object = ast_json_pack("{s: i, s: i}",
361                         "dest", dest, "id", id);
362
363         if (!json_object) {
364                 return;
365         }
366
367         payload = local_channel_optimization_blob(p, json_object);
368         if (!payload) {
369                 return;
370         }
371
372         if (source) {
373                 RAII_VAR(struct ast_channel_snapshot *, source_snapshot, NULL, ao2_cleanup);
374                 source_snapshot = ast_channel_snapshot_create(source);
375                 if (!source_snapshot) {
376                         return;
377                 }
378
379                 ast_multi_channel_blob_add_channel(payload, "source", source_snapshot);
380         }
381
382         msg = stasis_message_create(ast_local_optimization_begin_type(), payload);
383         if (!msg) {
384                 return;
385         }
386
387         stasis_publish(ast_channel_topic(p->base.owner), msg);
388 }
389
390 /*! \brief Callback for \ref ast_unreal_pvt_callbacks \ref optimization_finished_cb */
391 static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int success, unsigned int id)
392 {
393         RAII_VAR(struct ast_json *, json_object, ast_json_null(), ast_json_unref);
394         RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
395         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
396         struct local_pvt *p = (struct local_pvt *)base;
397
398         json_object = ast_json_pack("{s: i, s: i}", "success", success, "id", id);
399
400         if (!json_object) {
401                 return;
402         }
403
404         payload = local_channel_optimization_blob(p, json_object);
405         if (!payload) {
406                 return;
407         }
408
409         msg = stasis_message_create(ast_local_optimization_end_type(), payload);
410         if (!msg) {
411                 return;
412         }
413
414         stasis_publish(ast_channel_topic(p->base.owner), msg);
415 }
416
417 static struct ast_manager_event_blob *local_message_to_ami(struct stasis_message *message)
418 {
419         struct ast_multi_channel_blob *obj = stasis_message_data(message);
420         struct ast_json *blob = ast_multi_channel_blob_get_json(obj);
421         struct ast_channel_snapshot *local_snapshot_one;
422         struct ast_channel_snapshot *local_snapshot_two;
423         RAII_VAR(struct ast_str *, local_channel_one, NULL, ast_free);
424         RAII_VAR(struct ast_str *, local_channel_two, NULL, ast_free);
425         RAII_VAR(struct ast_str *, event_buffer, NULL, ast_free);
426         const char *event;
427
428         local_snapshot_one = ast_multi_channel_blob_get_channel(obj, "1");
429         local_snapshot_two = ast_multi_channel_blob_get_channel(obj, "2");
430         if (!local_snapshot_one || !local_snapshot_two) {
431                 return NULL;
432         }
433
434         event_buffer = ast_str_create(1024);
435         local_channel_one = ast_manager_build_channel_state_string_prefix(local_snapshot_one, "LocalOne");
436         local_channel_two = ast_manager_build_channel_state_string_prefix(local_snapshot_two, "LocalTwo");
437         if (!event_buffer || !local_channel_one || !local_channel_two) {
438                 return NULL;
439         }
440
441         if (stasis_message_type(message) == ast_local_optimization_begin_type()) {
442                 struct ast_channel_snapshot *source_snapshot;
443                 RAII_VAR(struct ast_str *, source_str, NULL, ast_free);
444                 const char *dest_uniqueid;
445
446                 source_snapshot = ast_multi_channel_blob_get_channel(obj, "source");
447                 if (source_snapshot) {
448                         source_str = ast_manager_build_channel_state_string_prefix(source_snapshot, "Source");
449                         if (!source_str) {
450                                 return NULL;
451                         }
452                 }
453
454                 dest_uniqueid = ast_json_object_get(blob, "dest") == AST_UNREAL_OWNER ?
455                                 local_snapshot_one->uniqueid : local_snapshot_two->uniqueid;
456
457                 event = "LocalOptimizationBegin";
458                 if (source_str) {
459                         ast_str_append(&event_buffer, 0, "%s", ast_str_buffer(source_str));
460                 }
461                 ast_str_append(&event_buffer, 0, "DestUniqueId: %s\r\n", dest_uniqueid);
462                 ast_str_append(&event_buffer, 0, "Id: %u\r\n", (unsigned int) ast_json_integer_get(ast_json_object_get(blob, "id")));
463         } else if (stasis_message_type(message) == ast_local_optimization_end_type()) {
464                 event = "LocalOptimizationEnd";
465                 ast_str_append(&event_buffer, 0, "Success: %s\r\n", ast_json_integer_get(ast_json_object_get(blob, "success")) ? "Yes" : "No");
466                 ast_str_append(&event_buffer, 0, "Id: %u\r\n", (unsigned int) ast_json_integer_get(ast_json_object_get(blob, "id")));
467         } else if (stasis_message_type(message) == ast_local_bridge_type()) {
468                 event = "LocalBridge";
469                 ast_str_append(&event_buffer, 0, "Context: %s\r\n", ast_json_string_get(ast_json_object_get(blob, "context")));
470                 ast_str_append(&event_buffer, 0, "Exten: %s\r\n", ast_json_string_get(ast_json_object_get(blob, "exten")));
471                 ast_str_append(&event_buffer, 0, "LocalOptimization: %s\r\n", ast_json_is_true(ast_json_object_get(blob, "can_optimize")) ? "Yes" : "No");
472         } else {
473                 return NULL;
474         }
475
476         return ast_manager_event_blob_create(EVENT_FLAG_CALL, event,
477                 "%s"
478                 "%s"
479                 "%s",
480                 ast_str_buffer(local_channel_one),
481                 ast_str_buffer(local_channel_two),
482                 ast_str_buffer(event_buffer));
483 }
484
485 /*!
486  * \internal
487  * \brief Post the \ref ast_local_bridge_type \ref stasis message
488  * \since 12.0.0
489  *
490  * \param p local_pvt to raise the local bridge message
491  *
492  * \return Nothing
493  */
494 static void publish_local_bridge_message(struct local_pvt *p)
495 {
496         RAII_VAR(struct ast_multi_channel_blob *, multi_blob, NULL, ao2_cleanup);
497         RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
498         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
499         RAII_VAR(struct ast_channel_snapshot *, one_snapshot, NULL, ao2_cleanup);
500         RAII_VAR(struct ast_channel_snapshot *, two_snapshot, NULL, ao2_cleanup);
501         SCOPED_AO2LOCK(lock, p);
502
503         blob = ast_json_pack("{s: s, s: s, s: b}",
504                 "context", p->context,
505                 "exten", p->exten,
506                 "can_optimize", !ast_test_flag(&p->base, AST_UNREAL_NO_OPTIMIZATION));
507         if (!blob) {
508                 return;
509         }
510
511         multi_blob = ast_multi_channel_blob_create(blob);
512         if (!multi_blob) {
513                 return;
514         }
515
516         one_snapshot = ast_channel_snapshot_create(p->base.owner);
517         if (!one_snapshot) {
518                 return;
519         }
520
521         two_snapshot = ast_channel_snapshot_create(p->base.chan);
522         if (!two_snapshot) {
523                 return;
524         }
525
526         ast_multi_channel_blob_add_channel(multi_blob, "1", one_snapshot);
527         ast_multi_channel_blob_add_channel(multi_blob, "2", two_snapshot);
528
529         msg = stasis_message_create(ast_local_bridge_type(), multi_blob);
530         if (!msg) {
531                 return;
532         }
533
534         stasis_publish(ast_channel_topic(p->base.owner), msg);
535 }
536
537 int ast_local_setup_bridge(struct ast_channel *ast, struct ast_bridge *bridge, struct ast_channel *swap, struct ast_bridge_features *features)
538 {
539         struct local_pvt *p;
540         struct local_pvt *found;
541         int res = -1;
542
543         /* Sanity checks. */
544         if (!ast || !bridge) {
545                 ast_bridge_features_destroy(features);
546                 return -1;
547         }
548
549         ast_channel_lock(ast);
550         p = ast_channel_tech_pvt(ast);
551         ast_channel_unlock(ast);
552
553         found = p ? ao2_find(locals, p, 0) : NULL;
554         if (found) {
555                 ao2_lock(found);
556                 if (found->type == LOCAL_CALL_ACTION_DIALPLAN
557                         && found->base.owner
558                         && found->base.chan
559                         && !ast_test_flag(&found->base, AST_UNREAL_CARETAKER_THREAD)) {
560                         ao2_ref(bridge, +1);
561                         if (swap) {
562                                 ast_channel_ref(swap);
563                         }
564                         found->type = LOCAL_CALL_ACTION_BRIDGE;
565                         found->action.bridge.join = bridge;
566                         found->action.bridge.swap = swap;
567                         found->action.bridge.features = features;
568                         res = 0;
569                 } else {
570                         ast_bridge_features_destroy(features);
571                 }
572                 ao2_unlock(found);
573                 ao2_ref(found, -1);
574         }
575
576         return res;
577 }
578
579 int ast_local_setup_masquerade(struct ast_channel *ast, struct ast_channel *masq)
580 {
581         struct local_pvt *p;
582         struct local_pvt *found;
583         int res = -1;
584
585         /* Sanity checks. */
586         if (!ast || !masq) {
587                 return -1;
588         }
589
590         ast_channel_lock(ast);
591         p = ast_channel_tech_pvt(ast);
592         ast_channel_unlock(ast);
593
594         found = p ? ao2_find(locals, p, 0) : NULL;
595         if (found) {
596                 ao2_lock(found);
597                 if (found->type == LOCAL_CALL_ACTION_DIALPLAN
598                         && found->base.owner
599                         && found->base.chan
600                         && !ast_test_flag(&found->base, AST_UNREAL_CARETAKER_THREAD)) {
601                         ast_channel_ref(masq);
602                         found->type = LOCAL_CALL_ACTION_MASQUERADE;
603                         found->action.masq = masq;
604                         res = 0;
605                 }
606                 ao2_unlock(found);
607                 ao2_ref(found, -1);
608         }
609
610         return res;
611 }
612
613 /*! \brief Initiate new call, part of PBX interface
614  *         dest is the dial string */
615 static int local_call(struct ast_channel *ast, const char *dest, int timeout)
616 {
617         struct local_pvt *p = ast_channel_tech_pvt(ast);
618         int pvt_locked = 0;
619
620         struct ast_channel *owner = NULL;
621         struct ast_channel *chan = NULL;
622         int res;
623         char *reduced_dest = ast_strdupa(dest);
624         char *slash;
625         const char *chan_cid;
626
627         if (!p) {
628                 return -1;
629         }
630
631         /* since we are letting go of channel locks that were locked coming into
632          * this function, then we need to give the tech pvt a ref */
633         ao2_ref(p, 1);
634         ast_channel_unlock(ast);
635
636         ast_unreal_lock_all(&p->base, &chan, &owner);
637         pvt_locked = 1;
638
639         if (owner != ast) {
640                 res = -1;
641                 goto return_cleanup;
642         }
643
644         if (!owner || !chan) {
645                 res = -1;
646                 goto return_cleanup;
647         }
648
649         ast_unreal_call_setup(owner, chan);
650
651         /*
652          * If the local channel has /n on the end of it, we need to lop
653          * that off for our argument to setting up the CC_INTERFACES
654          * variable.
655          */
656         if ((slash = strrchr(reduced_dest, '/'))) {
657                 *slash = '\0';
658         }
659         ast_set_cc_interfaces_chanvar(chan, reduced_dest);
660
661         ao2_unlock(p);
662         pvt_locked = 0;
663
664         ast_channel_unlock(owner);
665
666         chan_cid = S_COR(ast_channel_caller(chan)->id.number.valid,
667                 ast_channel_caller(chan)->id.number.str, NULL);
668         if (chan_cid) {
669                 chan_cid = ast_strdupa(chan_cid);
670         }
671         ast_channel_unlock(chan);
672
673         res = -1;
674         switch (p->type) {
675         case LOCAL_CALL_ACTION_DIALPLAN:
676                 if (!ast_exists_extension(NULL, p->context, p->exten, 1, chan_cid)) {
677                         ast_log(LOG_NOTICE, "No such extension/context %s@%s while calling Local channel\n",
678                                 p->exten, p->context);
679                 } else {
680                         publish_local_bridge_message(p);
681
682                         /* Start switch on sub channel */
683                         res = ast_pbx_start(chan);
684                 }
685                 break;
686         case LOCAL_CALL_ACTION_BRIDGE:
687                 publish_local_bridge_message(p);
688                 ast_answer(chan);
689                 res = ast_bridge_impart(p->action.bridge.join, chan, p->action.bridge.swap,
690                         p->action.bridge.features, AST_BRIDGE_IMPART_CHAN_INDEPENDENT);
691                 ao2_ref(p->action.bridge.join, -1);
692                 p->action.bridge.join = NULL;
693                 ao2_cleanup(p->action.bridge.swap);
694                 p->action.bridge.swap = NULL;
695                 p->action.bridge.features = NULL;
696                 break;
697         case LOCAL_CALL_ACTION_MASQUERADE:
698                 publish_local_bridge_message(p);
699                 ast_answer(chan);
700                 res = ast_channel_move(p->action.masq, chan);
701                 if (!res) {
702                         /* Chan is now an orphaned zombie.  Destroy it. */
703                         ast_hangup(chan);
704                 }
705                 p->action.masq = ast_channel_unref(p->action.masq);
706                 break;
707         }
708         if (!res) {
709                 ao2_lock(p);
710                 ast_set_flag(&p->base, AST_UNREAL_CARETAKER_THREAD);
711                 ao2_unlock(p);
712         }
713
714         /* we already unlocked them, clear them here so the cleanup label won't touch them. */
715         owner = ast_channel_unref(owner);
716         chan = ast_channel_unref(chan);
717
718 return_cleanup:
719         if (p) {
720                 if (pvt_locked) {
721                         ao2_unlock(p);
722                 }
723                 ao2_ref(p, -1);
724         }
725         if (chan) {
726                 ast_channel_unlock(chan);
727                 ast_channel_unref(chan);
728         }
729
730         /*
731          * owner is supposed to be == to ast, if it is, don't unlock it
732          * because ast must exit locked
733          */
734         if (owner) {
735                 if (owner != ast) {
736                         ast_channel_unlock(owner);
737                         ast_channel_lock(ast);
738                 }
739                 ast_channel_unref(owner);
740         } else {
741                 /* we have to exit with ast locked */
742                 ast_channel_lock(ast);
743         }
744
745         return res;
746 }
747
748 /*! \brief Hangup a call through the local proxy channel */
749 static int local_hangup(struct ast_channel *ast)
750 {
751         struct local_pvt *p = ast_channel_tech_pvt(ast);
752         int res;
753
754         if (!p) {
755                 return -1;
756         }
757
758         /* give the pvt a ref to fulfill calling requirements. */
759         ao2_ref(p, +1);
760         res = ast_unreal_hangup(&p->base, ast);
761         if (!res) {
762                 int unlink;
763
764                 ao2_lock(p);
765                 unlink = !p->base.owner && !p->base.chan;
766                 ao2_unlock(p);
767                 if (unlink) {
768                         ao2_unlink(locals, p);
769                 }
770         }
771         ao2_ref(p, -1);
772
773         return res;
774 }
775
776 /*!
777  * \internal
778  * \brief struct local_pvt destructor.
779  *
780  * \param vdoomed Object to destroy.
781  *
782  * \return Nothing
783  */
784 static void local_pvt_destructor(void *vdoomed)
785 {
786         struct local_pvt *doomed = vdoomed;
787
788         switch (doomed->type) {
789         case LOCAL_CALL_ACTION_DIALPLAN:
790                 break;
791         case LOCAL_CALL_ACTION_BRIDGE:
792                 ao2_cleanup(doomed->action.bridge.join);
793                 ao2_cleanup(doomed->action.bridge.swap);
794                 ast_bridge_features_destroy(doomed->action.bridge.features);
795                 break;
796         case LOCAL_CALL_ACTION_MASQUERADE:
797                 ao2_cleanup(doomed->action.masq);
798                 break;
799         }
800         ast_unreal_destructor(&doomed->base);
801 }
802
803 /*! \brief Create a call structure */
804 static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
805 {
806         struct local_pvt *pvt;
807         char *parse;
808         char *context;
809         char *opts;
810
811         pvt = (struct local_pvt *) ast_unreal_alloc(sizeof(*pvt), local_pvt_destructor, cap);
812         if (!pvt) {
813                 return NULL;
814         }
815         pvt->base.callbacks = &local_unreal_callbacks;
816
817         parse = ast_strdupa(data);
818
819         /*
820          * Local channels intercept MOH by default.
821          *
822          * This is a silly default because it represents state held by
823          * the local channels.  Unless local channel optimization is
824          * disabled, the state will dissapear when the local channels
825          * optimize out.
826          */
827         ast_set_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
828
829         /* Look for options */
830         if ((opts = strchr(parse, '/'))) {
831                 *opts++ = '\0';
832                 if (strchr(opts, 'n')) {
833                         ast_set_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION);
834                 }
835                 if (strchr(opts, 'j')) {
836                         if (ast_test_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION)) {
837                                 ast_set_flag(&pvt->base.jb_conf, AST_JB_ENABLED);
838                         } else {
839                                 ast_log(LOG_ERROR, "You must use the 'n' option with the 'j' option to enable the jitter buffer\n");
840                         }
841                 }
842                 if (strchr(opts, 'm')) {
843                         ast_clear_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
844                 }
845         }
846
847         /* Look for a context */
848         if ((context = strchr(parse, '@'))) {
849                 *context++ = '\0';
850         }
851
852         ast_copy_string(pvt->context, S_OR(context, "default"), sizeof(pvt->context));
853         ast_copy_string(pvt->exten, parse, sizeof(pvt->exten));
854         snprintf(pvt->base.name, sizeof(pvt->base.name), "%s@%s", pvt->exten, pvt->context);
855
856         return pvt; /* this is returned with a ref */
857 }
858
859 /*! \brief Part of PBX interface */
860 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
861 {
862         struct local_pvt *p;
863         struct ast_channel *chan;
864         struct ast_callid *callid;
865
866         /* Allocate a new private structure and then Asterisk channels */
867         p = local_alloc(data, cap);
868         if (!p) {
869                 return NULL;
870         }
871         callid = ast_read_threadstorage_callid();
872         chan = ast_unreal_new_channels(&p->base, &local_tech, AST_STATE_DOWN, AST_STATE_RING,
873                 p->exten, p->context, requestor, callid);
874         if (chan) {
875                 ao2_link(locals, p);
876         }
877         if (callid) {
878                 ast_callid_unref(callid);
879         }
880         ao2_ref(p, -1); /* kill the ref from the alloc */
881
882         return chan;
883 }
884
885 /*! \brief CLI command "local show channels" */
886 static char *locals_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
887 {
888         struct local_pvt *p;
889         struct ao2_iterator it;
890
891         switch (cmd) {
892         case CLI_INIT:
893                 e->command = "local show channels";
894                 e->usage =
895                         "Usage: local show channels\n"
896                         "       Provides summary information on active local proxy channels.\n";
897                 return NULL;
898         case CLI_GENERATE:
899                 return NULL;
900         }
901
902         if (a->argc != 3) {
903                 return CLI_SHOWUSAGE;
904         }
905
906         if (ao2_container_count(locals) == 0) {
907                 ast_cli(a->fd, "No local channels in use\n");
908                 return RESULT_SUCCESS;
909         }
910
911         it = ao2_iterator_init(locals, 0);
912         while ((p = ao2_iterator_next(&it))) {
913                 ao2_lock(p);
914                 ast_cli(a->fd, "%s -- %s\n",
915                         p->base.owner ? ast_channel_name(p->base.owner) : "<unowned>",
916                         p->base.name);
917                 ao2_unlock(p);
918                 ao2_ref(p, -1);
919         }
920         ao2_iterator_destroy(&it);
921
922         return CLI_SUCCESS;
923 }
924
925 static struct ast_cli_entry cli_local[] = {
926         AST_CLI_DEFINE(locals_show, "List status of local channels"),
927 };
928
929 static int manager_optimize_away(struct mansession *s, const struct message *m)
930 {
931         const char *channel;
932         struct local_pvt *p;
933         struct local_pvt *found;
934         struct ast_channel *chan;
935
936         channel = astman_get_header(m, "Channel");
937         if (ast_strlen_zero(channel)) {
938                 astman_send_error(s, m, "'Channel' not specified.");
939                 return 0;
940         }
941
942         chan = ast_channel_get_by_name(channel);
943         if (!chan) {
944                 astman_send_error(s, m, "Channel does not exist.");
945                 return 0;
946         }
947
948         p = ast_channel_tech_pvt(chan);
949         ast_channel_unref(chan);
950
951         found = p ? ao2_find(locals, p, 0) : NULL;
952         if (found) {
953                 ao2_lock(found);
954                 ast_clear_flag(&found->base, AST_UNREAL_NO_OPTIMIZATION);
955                 ao2_unlock(found);
956                 ao2_ref(found, -1);
957                 astman_send_ack(s, m, "Queued channel to be optimized away");
958         } else {
959                 astman_send_error(s, m, "Unable to find channel");
960         }
961
962         return 0;
963 }
964
965
966 static int locals_cmp_cb(void *obj, void *arg, int flags)
967 {
968         return (obj == arg) ? CMP_MATCH : 0;
969 }
970
971 /*!
972  * \internal
973  * \brief Shutdown the local proxy channel.
974  * \since 12.0.0
975  *
976  * \return Nothing
977  */
978 static void local_shutdown(void)
979 {
980         struct local_pvt *p;
981         struct ao2_iterator it;
982
983         /* First, take us out of the channel loop */
984         ast_cli_unregister_multiple(cli_local, ARRAY_LEN(cli_local));
985         ast_manager_unregister("LocalOptimizeAway");
986         ast_channel_unregister(&local_tech);
987
988         it = ao2_iterator_init(locals, 0);
989         while ((p = ao2_iterator_next(&it))) {
990                 if (p->base.owner) {
991                         ast_softhangup(p->base.owner, AST_SOFTHANGUP_APPUNLOAD);
992                 }
993                 ao2_ref(p, -1);
994         }
995         ao2_iterator_destroy(&it);
996         ao2_ref(locals, -1);
997         locals = NULL;
998
999         ast_format_cap_destroy(local_tech.capabilities);
1000
1001         STASIS_MESSAGE_TYPE_CLEANUP(ast_local_optimization_begin_type);
1002         STASIS_MESSAGE_TYPE_CLEANUP(ast_local_optimization_end_type);
1003         STASIS_MESSAGE_TYPE_CLEANUP(ast_local_bridge_type);
1004 }
1005
1006 int ast_local_init(void)
1007 {
1008
1009         if (STASIS_MESSAGE_TYPE_INIT(ast_local_optimization_begin_type)) {
1010                 return -1;
1011         }
1012
1013         if (STASIS_MESSAGE_TYPE_INIT(ast_local_optimization_end_type)) {
1014                 return -1;
1015         }
1016
1017         if (STASIS_MESSAGE_TYPE_INIT(ast_local_bridge_type)) {
1018                 return -1;
1019         }
1020
1021         if (!(local_tech.capabilities = ast_format_cap_alloc(0))) {
1022                 return -1;
1023         }
1024         ast_format_cap_add_all(local_tech.capabilities);
1025
1026         locals = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, locals_cmp_cb);
1027         if (!locals) {
1028                 ast_format_cap_destroy(local_tech.capabilities);
1029                 return -1;
1030         }
1031
1032         /* Make sure we can register our channel type */
1033         if (ast_channel_register(&local_tech)) {
1034                 ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
1035                 ao2_ref(locals, -1);
1036                 ast_format_cap_destroy(local_tech.capabilities);
1037                 return -1;
1038         }
1039         ast_cli_register_multiple(cli_local, ARRAY_LEN(cli_local));
1040         ast_manager_register_xml_core("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
1041
1042         ast_register_atexit(local_shutdown);
1043         return 0;
1044 }