7e457f4849eebdc7578b880be111db347e755e71
[asterisk/asterisk.git] / main / core_unreal.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 Unreal channel derivatives framework for channel drivers like local channels.
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 #include "asterisk.h"
34
35 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36
37 #include "asterisk/causes.h"
38 #include "asterisk/channel.h"
39 #include "asterisk/pbx.h"
40 #include "asterisk/musiconhold.h"
41 #include "asterisk/astobj2.h"
42 #include "asterisk/bridge.h"
43 #include "asterisk/core_unreal.h"
44
45 static unsigned int name_sequence = 0;
46
47 void ast_unreal_lock_all(struct ast_unreal_pvt *p, struct ast_channel **outchan, struct ast_channel **outowner)
48 {
49         struct ast_channel *chan = NULL;
50         struct ast_channel *owner = NULL;
51
52         ao2_lock(p);
53         for (;;) {
54                 if (p->chan) {
55                         chan = p->chan;
56                         ast_channel_ref(chan);
57                 }
58                 if (p->owner) {
59                         owner = p->owner;
60                         ast_channel_ref(owner);
61                 }
62                 ao2_unlock(p);
63
64                 /* if we don't have both channels, then this is very easy */
65                 if (!owner || !chan) {
66                         if (owner) {
67                                 ast_channel_lock(owner);
68                         } else if(chan) {
69                                 ast_channel_lock(chan);
70                         }
71                 } else {
72                         /* lock both channels first, then get the pvt lock */
73                         ast_channel_lock_both(chan, owner);
74                 }
75                 ao2_lock(p);
76
77                 /* Now that we have all the locks, validate that nothing changed */
78                 if (p->owner != owner || p->chan != chan) {
79                         if (owner) {
80                                 ast_channel_unlock(owner);
81                                 owner = ast_channel_unref(owner);
82                         }
83                         if (chan) {
84                                 ast_channel_unlock(chan);
85                                 chan = ast_channel_unref(chan);
86                         }
87                         continue;
88                 }
89
90                 break;
91         }
92         *outowner = p->owner;
93         *outchan = p->chan;
94 }
95
96 /* Called with ast locked */
97 int ast_unreal_setoption(struct ast_channel *ast, int option, void *data, int datalen)
98 {
99         int res = 0;
100         struct ast_unreal_pvt *p;
101         struct ast_channel *otherchan = NULL;
102         ast_chan_write_info_t *write_info;
103
104         if (option != AST_OPTION_CHANNEL_WRITE) {
105                 return -1;
106         }
107
108         write_info = data;
109
110         if (write_info->version != AST_CHAN_WRITE_INFO_T_VERSION) {
111                 ast_log(LOG_ERROR, "The chan_write_info_t type has changed, and this channel hasn't been updated!\n");
112                 return -1;
113         }
114
115         if (!strcmp(write_info->function, "CHANNEL")
116                 && !strncasecmp(write_info->data, "hangup_handler_", 15)) {
117                 /* Block CHANNEL(hangup_handler_xxx) writes to the other unreal channel. */
118                 return 0;
119         }
120
121         /* get the tech pvt */
122         if (!(p = ast_channel_tech_pvt(ast))) {
123                 return -1;
124         }
125         ao2_ref(p, 1);
126         ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
127
128         /* get the channel we are supposed to write to */
129         ao2_lock(p);
130         otherchan = (write_info->chan == p->owner) ? p->chan : p->owner;
131         if (!otherchan || otherchan == write_info->chan) {
132                 res = -1;
133                 otherchan = NULL;
134                 ao2_unlock(p);
135                 goto setoption_cleanup;
136         }
137         ast_channel_ref(otherchan);
138
139         /* clear the pvt lock before grabbing the channel */
140         ao2_unlock(p);
141
142         ast_channel_lock(otherchan);
143         res = write_info->write_fn(otherchan, write_info->function, write_info->data, write_info->value);
144         ast_channel_unlock(otherchan);
145
146 setoption_cleanup:
147         ao2_ref(p, -1);
148         if (otherchan) {
149                 ast_channel_unref(otherchan);
150         }
151         ast_channel_lock(ast); /* Lock back before we leave */
152         return res;
153 }
154
155 /* Called with ast locked */
156 int ast_unreal_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
157 {
158         struct ast_unreal_pvt *p;
159         struct ast_channel *peer;
160         struct ast_channel *other;
161         int res = 0;
162
163         if (option != AST_OPTION_T38_STATE) {
164                 /* AST_OPTION_T38_STATE is the only supported option at this time */
165                 return -1;
166         }
167
168         /* for some reason the channel is not locked in channel.c when this function is called */
169         if (!(p = ast_channel_tech_pvt(ast))) {
170                 return -1;
171         }
172
173         ao2_lock(p);
174         other = AST_UNREAL_IS_OUTBOUND(ast, p) ? p->owner : p->chan;
175         if (!other) {
176                 ao2_unlock(p);
177                 return -1;
178         }
179         ast_channel_ref(other);
180         ao2_unlock(p);
181         ast_channel_unlock(ast); /* Held when called, unlock before locking another channel */
182
183         peer = ast_channel_bridge_peer(other);
184         if (peer) {
185                 res = ast_channel_queryoption(peer, option, data, datalen, 0);
186                 ast_channel_unref(peer);
187         }
188         ast_channel_unref(other);
189         ast_channel_lock(ast); /* Lock back before we leave */
190
191         return res;
192 }
193
194 /*!
195  * \brief queue a frame onto either the p->owner or p->chan
196  *
197  * \note the ast_unreal_pvt MUST have it's ref count bumped before entering this function and
198  * decremented after this function is called.  This is a side effect of the deadlock
199  * avoidance that is necessary to lock 2 channels and a tech_pvt.  Without a ref counted
200  * ast_unreal_pvt, it is impossible to guarantee it will not be destroyed by another thread
201  * during deadlock avoidance.
202  */
203 static int unreal_queue_frame(struct ast_unreal_pvt *p, int isoutbound, struct ast_frame *f,
204         struct ast_channel *us, int us_locked)
205 {
206         struct ast_channel *other;
207
208         /* Recalculate outbound channel */
209         other = isoutbound ? p->owner : p->chan;
210         if (!other) {
211                 return 0;
212         }
213
214         /* do not queue frame if generator is on both unreal channels */
215         if (us && ast_channel_generator(us) && ast_channel_generator(other)) {
216                 return 0;
217         }
218
219         /* grab a ref on the channel before unlocking the pvt,
220          * other can not go away from us now regardless of locking */
221         ast_channel_ref(other);
222         if (us && us_locked) {
223                 ast_channel_unlock(us);
224         }
225         ao2_unlock(p);
226
227         if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
228                 ast_setstate(other, AST_STATE_RINGING);
229         }
230         ast_queue_frame(other, f);
231
232         other = ast_channel_unref(other);
233         if (us && us_locked) {
234                 ast_channel_lock(us);
235         }
236         ao2_lock(p);
237
238         return 0;
239 }
240
241 int ast_unreal_answer(struct ast_channel *ast)
242 {
243         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
244         int isoutbound;
245         int res = -1;
246
247         if (!p) {
248                 return -1;
249         }
250
251         ao2_ref(p, 1);
252         ao2_lock(p);
253         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
254         if (isoutbound) {
255                 /* Pass along answer since somebody answered us */
256                 struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
257
258                 res = unreal_queue_frame(p, isoutbound, &answer, ast, 1);
259         } else {
260                 ast_log(LOG_WARNING, "Huh?  %s is being asked to answer?\n",
261                         ast_channel_name(ast));
262         }
263         ao2_unlock(p);
264         ao2_ref(p, -1);
265         return res;
266 }
267
268 /*!
269  * \internal
270  * \brief Check and optimize out the unreal channels between bridges.
271  * \since 12.0.0
272  *
273  * \param ast Channel writing a frame into the unreal channels.
274  * \param p Unreal channel private.
275  *
276  * \note It is assumed that ast is locked.
277  * \note It is assumed that p is locked.
278  *
279  * \retval 0 if unreal channels were not optimized out.
280  * \retval non-zero if unreal channels were optimized out.
281  */
282 static int got_optimized_out(struct ast_channel *ast, struct ast_unreal_pvt *p)
283 {
284         int res = 0;
285
286         /* Do a few conditional checks early on just to see if this optimization is possible */
287         if (ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION) || !p->chan || !p->owner) {
288                 return res;
289         }
290
291         if (ast == p->owner) {
292                 res = ast_bridge_unreal_optimize_out(p->owner, p->chan, p);
293         } else if (ast == p->chan) {
294                 res = ast_bridge_unreal_optimize_out(p->chan, p->owner, p);
295         }
296
297         return res;
298 }
299
300 struct ast_frame  *ast_unreal_read(struct ast_channel *ast)
301 {
302         return &ast_null_frame;
303 }
304
305 int ast_unreal_write(struct ast_channel *ast, struct ast_frame *f)
306 {
307         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
308         int res = -1;
309
310         if (!p) {
311                 return -1;
312         }
313
314         /* Just queue for delivery to the other side */
315         ao2_ref(p, 1);
316         ao2_lock(p);
317         switch (f->frametype) {
318         case AST_FRAME_VOICE:
319         case AST_FRAME_VIDEO:
320                 if (got_optimized_out(ast, p)) {
321                         break;
322                 }
323                 /* fall through */
324         default:
325                 res = unreal_queue_frame(p, AST_UNREAL_IS_OUTBOUND(ast, p), f, ast, 1);
326                 break;
327         }
328         ao2_unlock(p);
329         ao2_ref(p, -1);
330
331         return res;
332 }
333
334 int ast_unreal_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
335 {
336         struct ast_unreal_pvt *p = ast_channel_tech_pvt(newchan);
337         struct ast_bridge *bridge_owner;
338         struct ast_bridge *bridge_chan;
339
340         if (!p) {
341                 return -1;
342         }
343
344         ao2_lock(p);
345
346         if ((p->owner != oldchan) && (p->chan != oldchan)) {
347                 ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
348                 ao2_unlock(p);
349                 return -1;
350         }
351         if (p->owner == oldchan) {
352                 p->owner = newchan;
353         } else {
354                 p->chan = newchan;
355         }
356
357         if (ast_check_hangup(newchan) || !p->owner || !p->chan) {
358                 ao2_unlock(p);
359                 return 0;
360         }
361
362         /* Do not let a masquerade cause an unreal channel to be bridged to itself! */
363         bridge_owner = ast_channel_internal_bridge(p->owner);
364         bridge_chan = ast_channel_internal_bridge(p->chan);
365         if (bridge_owner && bridge_owner == bridge_chan) {
366                 ast_log(LOG_WARNING, "You can not bridge an unreal channel (%s) to itself!\n",
367                         ast_channel_name(newchan));
368                 ao2_unlock(p);
369                 ast_queue_hangup(newchan);
370                 return -1;
371         }
372
373         ao2_unlock(p);
374         return 0;
375 }
376
377 /*!
378  * \internal
379  * \brief Queue up a frame representing the indication as a control frame.
380  * \since 12.0.0
381  *
382  * \param p Unreal private structure.
383  * \param ast Channel indicating the condition.
384  * \param condition What is being indicated.
385  * \param data Extra data.
386  * \param datalen Length of extra data.
387  *
388  * \retval 0 on success.
389  * \retval AST_T38_REQUEST_PARMS if successful and condition is AST_CONTROL_T38_PARAMETERS.
390  * \retval -1 on error.
391  */
392 static int unreal_queue_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition, const void *data, size_t datalen)
393 {
394         int res = 0;
395         int isoutbound;
396
397         ao2_lock(p);
398         /*
399          * Block -1 stop tones events if we are to be optimized out.  We
400          * don't need a flurry of these events on an unreal channel chain
401          * when initially connected to slow the optimization process.
402          */
403         if (0 <= condition || ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION)) {
404                 struct ast_frame f = {
405                         .frametype = AST_FRAME_CONTROL,
406                         .subclass.integer = condition,
407                         .data.ptr = (void *) data,
408                         .datalen = datalen,
409                 };
410
411                 isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
412                 res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
413                 if (!res
414                         && condition == AST_CONTROL_T38_PARAMETERS
415                         && datalen == sizeof(struct ast_control_t38_parameters)) {
416                         const struct ast_control_t38_parameters *parameters = data;
417
418                         if (parameters->request_response == AST_T38_REQUEST_PARMS) {
419                                 res = AST_T38_REQUEST_PARMS;
420                         }
421                 }
422         } else {
423                 ast_debug(4, "Blocked indication %d\n", condition);
424         }
425         ao2_unlock(p);
426
427         return res;
428 }
429
430 /*!
431  * \internal
432  * \brief Handle COLP and redirecting conditions.
433  * \since 12.0.0
434  *
435  * \param p Unreal private structure.
436  * \param ast Channel indicating the condition.
437  * \param condition What is being indicated.
438  *
439  * \retval 0 on success.
440  * \retval -1 on error.
441  */
442 static int unreal_colp_redirect_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition)
443 {
444         struct ast_channel *my_chan;
445         struct ast_channel *my_owner;
446         struct ast_channel *this_channel;
447         struct ast_channel *the_other_channel;
448         int isoutbound;
449         int res = 0;
450         unsigned char frame_data[1024];
451         struct ast_frame f = {
452                 .frametype = AST_FRAME_CONTROL,
453                 .subclass.integer = condition,
454                 .data.ptr = frame_data,
455         };
456
457         /*
458          * A connected line update frame may only contain a partial
459          * amount of data, such as just a source, or just a ton, and not
460          * the full amount of information.  However, the collected
461          * information is all stored in the outgoing channel's
462          * connectedline structure, so when receiving a connected line
463          * update on an outgoing unreal channel, we need to transmit the
464          * collected connected line information instead of whatever
465          * happens to be in this control frame.  The same applies for
466          * redirecting information, which is why it is handled here as
467          * well.
468          */
469         ast_channel_unlock(ast);
470         ast_unreal_lock_all(p, &my_chan, &my_owner);
471         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
472         if (isoutbound) {
473                 this_channel = p->chan;
474                 the_other_channel = p->owner;
475         } else {
476                 this_channel = p->owner;
477                 the_other_channel = p->chan;
478         }
479         if (the_other_channel) {
480                 if (condition == AST_CONTROL_CONNECTED_LINE) {
481                         ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel),
482                                 ast_channel_connected(this_channel));
483                         f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data),
484                                 ast_channel_connected(this_channel), NULL);
485                 } else {
486                         f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data),
487                                 ast_channel_redirecting(this_channel), NULL);
488                 }
489         }
490         if (my_chan) {
491                 ast_channel_unlock(my_chan);
492                 ast_channel_unref(my_chan);
493         }
494         if (my_owner) {
495                 ast_channel_unlock(my_owner);
496                 ast_channel_unref(my_owner);
497         }
498         if (the_other_channel) {
499                 res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
500         }
501         ao2_unlock(p);
502         ast_channel_lock(ast);
503
504         return res;
505 }
506
507 int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
508 {
509         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
510         int res = 0;
511
512         if (!p) {
513                 return -1;
514         }
515
516         ao2_ref(p, 1); /* ref for unreal_queue_frame */
517
518         switch (condition) {
519         case AST_CONTROL_CONNECTED_LINE:
520         case AST_CONTROL_REDIRECTING:
521                 res = unreal_colp_redirect_indicate(p, ast, condition);
522                 break;
523         case AST_CONTROL_HOLD:
524                 if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
525                         ast_moh_start(ast, data, NULL);
526                         break;
527                 }
528                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
529                 break;
530         case AST_CONTROL_UNHOLD:
531                 if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
532                         ast_moh_stop(ast);
533                         break;
534                 }
535                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
536                 break;
537         default:
538                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
539                 break;
540         }
541
542         ao2_ref(p, -1);
543         return res;
544 }
545
546 int ast_unreal_digit_begin(struct ast_channel *ast, char digit)
547 {
548         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
549         int res = -1;
550         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
551         int isoutbound;
552
553         if (!p) {
554                 return -1;
555         }
556
557         ao2_ref(p, 1); /* ref for unreal_queue_frame */
558         ao2_lock(p);
559         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
560         f.subclass.integer = digit;
561         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
562         ao2_unlock(p);
563         ao2_ref(p, -1);
564
565         return res;
566 }
567
568 int ast_unreal_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
569 {
570         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
571         int res = -1;
572         struct ast_frame f = { AST_FRAME_DTMF_END, };
573         int isoutbound;
574
575         if (!p) {
576                 return -1;
577         }
578
579         ao2_ref(p, 1); /* ref for unreal_queue_frame */
580         ao2_lock(p);
581         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
582         f.subclass.integer = digit;
583         f.len = duration;
584         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
585         ao2_unlock(p);
586         ao2_ref(p, -1);
587
588         return res;
589 }
590
591 int ast_unreal_sendtext(struct ast_channel *ast, const char *text)
592 {
593         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
594         int res = -1;
595         struct ast_frame f = { AST_FRAME_TEXT, };
596         int isoutbound;
597
598         if (!p) {
599                 return -1;
600         }
601
602         ao2_ref(p, 1); /* ref for unreal_queue_frame */
603         ao2_lock(p);
604         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
605         f.data.ptr = (char *) text;
606         f.datalen = strlen(text) + 1;
607         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
608         ao2_unlock(p);
609         ao2_ref(p, -1);
610         return res;
611 }
612
613 int ast_unreal_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
614 {
615         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
616         int res = -1;
617         struct ast_frame f = { AST_FRAME_HTML, };
618         int isoutbound;
619
620         if (!p) {
621                 return -1;
622         }
623
624         ao2_ref(p, 1); /* ref for unreal_queue_frame */
625         ao2_lock(p);
626         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
627         f.subclass.integer = subclass;
628         f.data.ptr = (char *)data;
629         f.datalen = datalen;
630         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
631         ao2_unlock(p);
632         ao2_ref(p, -1);
633
634         return res;
635 }
636
637 void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
638 {
639         struct ast_var_t *varptr;
640         struct ast_var_t *clone_var;
641
642         /*
643          * Note that cid_num and cid_name aren't passed in the
644          * ast_channel_alloc calls in ast_unreal_new_channels().  It's
645          * done here instead.
646          */
647         ast_party_redirecting_copy(ast_channel_redirecting(semi2), ast_channel_redirecting(semi1));
648
649         ast_party_dialed_copy(ast_channel_dialed(semi2), ast_channel_dialed(semi1));
650
651         ast_connected_line_copy_to_caller(ast_channel_caller(semi2), ast_channel_connected(semi1));
652         ast_connected_line_copy_from_caller(ast_channel_connected(semi2), ast_channel_caller(semi1));
653
654         ast_channel_language_set(semi2, ast_channel_language(semi1));
655         ast_channel_accountcode_set(semi2, ast_channel_accountcode(semi1));
656         ast_channel_musicclass_set(semi2, ast_channel_musicclass(semi1));
657
658         ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1));
659
660         /*
661          * Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's
662          * set on the queue/dial call request in the dialplan.
663          */
664         if (ast_channel_hangupcause(semi1) == AST_CAUSE_ANSWERED_ELSEWHERE) {
665                 ast_channel_hangupcause_set(semi2, AST_CAUSE_ANSWERED_ELSEWHERE);
666         }
667
668         /*
669          * Copy the channel variables from the semi1 channel to the
670          * outgoing channel.
671          *
672          * Note that due to certain assumptions, they MUST be in the
673          * same order.
674          */
675         AST_LIST_TRAVERSE(ast_channel_varshead(semi1), varptr, entries) {
676                 clone_var = ast_var_assign(varptr->name, varptr->value);
677                 if (clone_var) {
678                         AST_LIST_INSERT_TAIL(ast_channel_varshead(semi2), clone_var, entries);
679                 }
680         }
681         ast_channel_datastore_inherit(semi1, semi2);
682 }
683
684 int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
685 {
686         struct ast_bridge_features *features;
687         struct ast_channel *chan;
688         struct ast_channel *owner;
689         RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);
690
691         RAII_VAR(struct ast_callid *, bridge_callid, NULL, ast_callid_cleanup);
692
693         ast_bridge_lock(bridge);
694         bridge_callid = bridge->callid ? ast_callid_ref(bridge->callid) : NULL;
695         ast_bridge_unlock(bridge);
696
697         {
698                 SCOPED_CHANNELLOCK(lock, ast);
699                 p = ast_channel_tech_pvt(ast);
700                 if (!p) {
701                         return -1;
702                 }
703                 ao2_ref(p, +1);
704         }
705
706         {
707                 SCOPED_AO2LOCK(lock, p);
708                 chan = p->chan;
709                 if (!chan) {
710                         return -1;
711                 }
712
713                 owner = p->owner;
714                 if (!owner) {
715                         return -1;
716                 }
717
718                 ast_channel_ref(chan);
719                 ast_channel_ref(owner);
720         }
721
722         if (bridge_callid) {
723                 struct ast_callid *chan_callid;
724                 struct ast_callid *owner_callid;
725
726                 /* chan side call ID setting */
727                 ast_channel_lock(chan);
728
729                 chan_callid = ast_channel_callid(chan);
730                 if (!chan_callid) {
731                         ast_channel_callid_set(chan, bridge_callid);
732                 }
733                 ast_channel_unlock(chan);
734                 ast_callid_cleanup(chan_callid);
735
736                 /* owner side call ID setting */
737                 ast_channel_lock(owner);
738
739                 owner_callid = ast_channel_callid(owner);
740                 if (!owner_callid) {
741                         ast_channel_callid_set(owner, bridge_callid);
742                 }
743
744                 ast_channel_unlock(owner);
745                 ast_callid_cleanup(owner_callid);
746         }
747
748         /* We are done with the owner now that its call ID matches the bridge */
749         ast_channel_unref(owner);
750         owner = NULL;
751
752         features = ast_bridge_features_new();
753         if (!features) {
754                 ast_channel_unref(chan);
755                 return -1;
756         }
757
758         ast_set_flag(&features->feature_flags, flags);
759
760         /* Impart the semi2 channel into the bridge */
761         if (ast_bridge_impart(bridge, chan, NULL, features,
762                 AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
763                 ast_bridge_features_destroy(features);
764                 ast_channel_unref(chan);
765                 return -1;
766         }
767
768         ao2_lock(p);
769         ast_set_flag(p, AST_UNREAL_CARETAKER_THREAD);
770         ao2_unlock(p);
771         ast_channel_unref(chan);
772
773         return 0;
774 }
775
776 int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
777 {
778         int hangup_chan = 0;
779         int res = 0;
780         int cause;
781         struct ast_channel *owner = NULL;
782         struct ast_channel *chan = NULL;
783
784         /* the pvt isn't going anywhere, it has a ref */
785         ast_channel_unlock(ast);
786
787         /* lock everything */
788         ast_unreal_lock_all(p, &chan, &owner);
789
790         if (ast != chan && ast != owner) {
791                 res = -1;
792                 goto unreal_hangup_cleanup;
793         }
794
795         cause = ast_channel_hangupcause(ast);
796
797         if (ast == p->chan) {
798                 /* Outgoing side is hanging up. */
799                 ast_clear_flag(p, AST_UNREAL_CARETAKER_THREAD);
800                 p->chan = NULL;
801                 if (p->owner) {
802                         const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
803
804                         if (status) {
805                                 ast_channel_hangupcause_set(p->owner, cause);
806                                 pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
807                         }
808                         ast_queue_hangup_with_cause(p->owner, cause);
809                 }
810         } else {
811                 /* Owner side is hanging up. */
812                 p->owner = NULL;
813                 if (p->chan) {
814                         if (cause == AST_CAUSE_ANSWERED_ELSEWHERE) {
815                                 ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
816                                 ast_debug(2, "%s has AST_CAUSE_ANSWERED_ELSEWHERE set.\n",
817                                         ast_channel_name(p->chan));
818                         }
819                         if (!ast_test_flag(p, AST_UNREAL_CARETAKER_THREAD)) {
820                                 /*
821                                  * Need to actually hangup p->chan since nothing else is taking
822                                  * care of it.
823                                  */
824                                 hangup_chan = 1;
825                         } else {
826                                 ast_queue_hangup_with_cause(p->chan, cause);
827                         }
828                 }
829         }
830
831         /* this is one of our locked channels, doesn't matter which */
832         ast_channel_tech_pvt_set(ast, NULL);
833         ao2_ref(p, -1);
834
835 unreal_hangup_cleanup:
836         ao2_unlock(p);
837         if (owner) {
838                 ast_channel_unlock(owner);
839                 ast_channel_unref(owner);
840         }
841         if (chan) {
842                 ast_channel_unlock(chan);
843                 if (hangup_chan) {
844                         ast_hangup(chan);
845                 }
846                 ast_channel_unref(chan);
847         }
848
849         /* leave with the channel locked that came in */
850         ast_channel_lock(ast);
851
852         return res;
853 }
854
855 void ast_unreal_destructor(void *vdoomed)
856 {
857         struct ast_unreal_pvt *doomed = vdoomed;
858
859         doomed->reqcap = ast_format_cap_destroy(doomed->reqcap);
860 }
861
862 struct ast_unreal_pvt *ast_unreal_alloc(size_t size, ao2_destructor_fn destructor, struct ast_format_cap *cap)
863 {
864         struct ast_unreal_pvt *unreal;
865
866         static const struct ast_jb_conf jb_conf = {
867                 .flags = 0,
868                 .max_size = -1,
869                 .resync_threshold = -1,
870                 .impl = "",
871                 .target_extra = -1,
872         };
873
874         unreal = ao2_alloc(size, destructor);
875         if (!unreal) {
876                 return NULL;
877         }
878         unreal->reqcap = ast_format_cap_dup(cap);
879         if (!unreal->reqcap) {
880                 ao2_ref(unreal, -1);
881                 return NULL;
882         }
883
884         memcpy(&unreal->jb_conf, &jb_conf, sizeof(unreal->jb_conf));
885
886         return unreal;
887 }
888
889 struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
890         const struct ast_channel_tech *tech, int semi1_state, int semi2_state,
891         const char *exten, const char *context, const struct ast_channel *requestor,
892         struct ast_callid *callid)
893 {
894         struct ast_channel *owner;
895         struct ast_channel *chan;
896         const char *linkedid = requestor ? ast_channel_linkedid(requestor) : NULL;
897         struct ast_format fmt;
898         int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
899
900         /*
901          * Allocate two new Asterisk channels
902          *
903          * Make sure that the ;2 channel gets the same linkedid as ;1.
904          * You can't pass linkedid to both allocations since if linkedid
905          * isn't set, then each channel will generate its own linkedid.
906          */
907         if (!(owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
908                         exten, context, linkedid, 0,
909                         "%s/%s-%08x;1", tech->type, p->name, generated_seqno))
910                 || !(chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
911                         exten, context, ast_channel_linkedid(owner), 0,
912                         "%s/%s-%08x;2", tech->type, p->name, generated_seqno))) {
913                 if (owner) {
914                         owner = ast_channel_release(owner);
915                 }
916                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
917                 return NULL;
918         }
919
920         if (callid) {
921                 ast_channel_callid_set(owner, callid);
922                 ast_channel_callid_set(chan, callid);
923         }
924
925         ast_channel_tech_set(owner, tech);
926         ast_channel_tech_set(chan, tech);
927         ast_channel_tech_pvt_set(owner, p);
928         ast_channel_tech_pvt_set(chan, p);
929
930         ast_format_cap_copy(ast_channel_nativeformats(owner), p->reqcap);
931         ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
932
933         /* Determine our read/write format and set it on each channel */
934         ast_best_codec(p->reqcap, &fmt);
935         ast_format_copy(ast_channel_writeformat(owner), &fmt);
936         ast_format_copy(ast_channel_writeformat(chan), &fmt);
937         ast_format_copy(ast_channel_rawwriteformat(owner), &fmt);
938         ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
939         ast_format_copy(ast_channel_readformat(owner), &fmt);
940         ast_format_copy(ast_channel_readformat(chan), &fmt);
941         ast_format_copy(ast_channel_rawreadformat(owner), &fmt);
942         ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
943
944         ast_set_flag(ast_channel_flags(owner), AST_FLAG_DISABLE_DEVSTATE_CACHE);
945         ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
946
947         ast_jb_configure(owner, &p->jb_conf);
948
949         if (ast_channel_cc_params_init(owner, requestor
950                 ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) {
951                 ast_channel_release(owner);
952                 ast_channel_release(chan);
953                 return NULL;
954         }
955
956         /* Give the private a ref for each channel. */
957         ao2_ref(p, +2);
958         p->owner = owner;
959         p->chan = chan;
960
961         return owner;
962 }