bridge_channel: Support the lonely flag and make ARI use it.
[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 *this_channel;
445         struct ast_channel *the_other_channel;
446         int isoutbound;
447         int res = 0;
448
449         /*
450          * A connected line update frame may only contain a partial
451          * amount of data, such as just a source, or just a ton, and not
452          * the full amount of information.  However, the collected
453          * information is all stored in the outgoing channel's
454          * connectedline structure, so when receiving a connected line
455          * update on an outgoing unreal channel, we need to transmit the
456          * collected connected line information instead of whatever
457          * happens to be in this control frame.  The same applies for
458          * redirecting information, which is why it is handled here as
459          * well.
460          */
461         ao2_lock(p);
462         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
463         if (isoutbound) {
464                 this_channel = p->chan;
465                 the_other_channel = p->owner;
466         } else {
467                 this_channel = p->owner;
468                 the_other_channel = p->chan;
469         }
470         if (the_other_channel) {
471                 unsigned char frame_data[1024];
472                 struct ast_frame f = {
473                         .frametype = AST_FRAME_CONTROL,
474                         .subclass.integer = condition,
475                         .data.ptr = frame_data,
476                 };
477
478                 if (condition == AST_CONTROL_CONNECTED_LINE) {
479                         ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel),
480                                 ast_channel_connected(this_channel));
481                         f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data),
482                                 ast_channel_connected(this_channel), NULL);
483                 } else {
484                         f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data),
485                                 ast_channel_redirecting(this_channel), NULL);
486                 }
487                 res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
488         }
489         ao2_unlock(p);
490
491         return res;
492 }
493
494 int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
495 {
496         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
497         int res = 0;
498
499         if (!p) {
500                 return -1;
501         }
502
503         ao2_ref(p, 1); /* ref for unreal_queue_frame */
504
505         switch (condition) {
506         case AST_CONTROL_CONNECTED_LINE:
507         case AST_CONTROL_REDIRECTING:
508                 res = unreal_colp_redirect_indicate(p, ast, condition);
509                 break;
510         case AST_CONTROL_HOLD:
511                 if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
512                         ast_moh_start(ast, data, NULL);
513                         break;
514                 }
515                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
516                 break;
517         case AST_CONTROL_UNHOLD:
518                 if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
519                         ast_moh_stop(ast);
520                         break;
521                 }
522                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
523                 break;
524         default:
525                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
526                 break;
527         }
528
529         ao2_ref(p, -1);
530         return res;
531 }
532
533 int ast_unreal_digit_begin(struct ast_channel *ast, char digit)
534 {
535         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
536         int res = -1;
537         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
538         int isoutbound;
539
540         if (!p) {
541                 return -1;
542         }
543
544         ao2_ref(p, 1); /* ref for unreal_queue_frame */
545         ao2_lock(p);
546         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
547         f.subclass.integer = digit;
548         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
549         ao2_unlock(p);
550         ao2_ref(p, -1);
551
552         return res;
553 }
554
555 int ast_unreal_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
556 {
557         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
558         int res = -1;
559         struct ast_frame f = { AST_FRAME_DTMF_END, };
560         int isoutbound;
561
562         if (!p) {
563                 return -1;
564         }
565
566         ao2_ref(p, 1); /* ref for unreal_queue_frame */
567         ao2_lock(p);
568         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
569         f.subclass.integer = digit;
570         f.len = duration;
571         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
572         ao2_unlock(p);
573         ao2_ref(p, -1);
574
575         return res;
576 }
577
578 int ast_unreal_sendtext(struct ast_channel *ast, const char *text)
579 {
580         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
581         int res = -1;
582         struct ast_frame f = { AST_FRAME_TEXT, };
583         int isoutbound;
584
585         if (!p) {
586                 return -1;
587         }
588
589         ao2_ref(p, 1); /* ref for unreal_queue_frame */
590         ao2_lock(p);
591         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
592         f.data.ptr = (char *) text;
593         f.datalen = strlen(text) + 1;
594         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
595         ao2_unlock(p);
596         ao2_ref(p, -1);
597         return res;
598 }
599
600 int ast_unreal_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
601 {
602         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
603         int res = -1;
604         struct ast_frame f = { AST_FRAME_HTML, };
605         int isoutbound;
606
607         if (!p) {
608                 return -1;
609         }
610
611         ao2_ref(p, 1); /* ref for unreal_queue_frame */
612         ao2_lock(p);
613         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
614         f.subclass.integer = subclass;
615         f.data.ptr = (char *)data;
616         f.datalen = datalen;
617         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
618         ao2_unlock(p);
619         ao2_ref(p, -1);
620
621         return res;
622 }
623
624 void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
625 {
626         struct ast_var_t *varptr;
627         struct ast_var_t *clone_var;
628
629         /*
630          * Note that cid_num and cid_name aren't passed in the
631          * ast_channel_alloc calls in ast_unreal_new_channels().  It's
632          * done here instead.
633          */
634         ast_party_redirecting_copy(ast_channel_redirecting(semi2), ast_channel_redirecting(semi1));
635
636         ast_party_dialed_copy(ast_channel_dialed(semi2), ast_channel_dialed(semi1));
637
638         ast_connected_line_copy_to_caller(ast_channel_caller(semi2), ast_channel_connected(semi1));
639         ast_connected_line_copy_from_caller(ast_channel_connected(semi2), ast_channel_caller(semi1));
640
641         ast_channel_language_set(semi2, ast_channel_language(semi1));
642         ast_channel_accountcode_set(semi2, ast_channel_accountcode(semi1));
643         ast_channel_musicclass_set(semi2, ast_channel_musicclass(semi1));
644
645         ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1));
646
647         /*
648          * Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's
649          * set on the queue/dial call request in the dialplan.
650          */
651         if (ast_channel_hangupcause(semi1) == AST_CAUSE_ANSWERED_ELSEWHERE) {
652                 ast_channel_hangupcause_set(semi2, AST_CAUSE_ANSWERED_ELSEWHERE);
653         }
654
655         /*
656          * Copy the channel variables from the semi1 channel to the
657          * outgoing channel.
658          *
659          * Note that due to certain assumptions, they MUST be in the
660          * same order.
661          */
662         AST_LIST_TRAVERSE(ast_channel_varshead(semi1), varptr, entries) {
663                 clone_var = ast_var_assign(varptr->name, varptr->value);
664                 if (clone_var) {
665                         AST_LIST_INSERT_TAIL(ast_channel_varshead(semi2), clone_var, entries);
666                 }
667         }
668         ast_channel_datastore_inherit(semi1, semi2);
669 }
670
671 int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
672 {
673         struct ast_bridge_features *features;
674         struct ast_channel *chan;
675         struct ast_channel *owner;
676         RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);
677
678         RAII_VAR(struct ast_callid *, bridge_callid, NULL, ast_callid_cleanup);
679
680         ast_bridge_lock(bridge);
681         bridge_callid = bridge->callid ? ast_callid_ref(bridge->callid) : NULL;
682         ast_bridge_unlock(bridge);
683
684         {
685                 SCOPED_CHANNELLOCK(lock, ast);
686                 p = ast_channel_tech_pvt(ast);
687                 if (!p) {
688                         return -1;
689                 }
690                 ao2_ref(p, +1);
691         }
692
693         {
694                 SCOPED_AO2LOCK(lock, p);
695                 chan = p->chan;
696                 if (!chan) {
697                         return -1;
698                 }
699
700                 owner = p->owner;
701                 if (!owner) {
702                         return -1;
703                 }
704
705                 ast_channel_ref(chan);
706                 ast_channel_ref(owner);
707         }
708
709         if (bridge_callid) {
710                 struct ast_callid *chan_callid;
711                 struct ast_callid *owner_callid;
712
713                 /* chan side call ID setting */
714                 ast_channel_lock(chan);
715
716                 chan_callid = ast_channel_callid(chan);
717                 if (!chan_callid) {
718                         ast_channel_callid_set(chan, bridge_callid);
719                 }
720                 ast_channel_unlock(chan);
721                 ast_callid_cleanup(chan_callid);
722
723                 /* owner side call ID setting */
724                 ast_channel_lock(owner);
725
726                 owner_callid = ast_channel_callid(owner);
727                 if (!owner_callid) {
728                         ast_channel_callid_set(owner, bridge_callid);
729                 }
730
731                 ast_channel_unlock(owner);
732                 ast_callid_cleanup(owner_callid);
733         }
734
735         /* We are done with the owner now that its call ID matches the bridge */
736         ast_channel_unref(owner);
737         owner = NULL;
738
739         features = ast_bridge_features_new();
740         if (!features) {
741                 ast_channel_unref(chan);
742                 return -1;
743         }
744
745         ast_set_flag(&features->feature_flags, flags);
746
747         /* Impart the semi2 channel into the bridge */
748         if (ast_bridge_impart(bridge, chan, NULL, features, 1)) {
749                 ast_bridge_features_destroy(features);
750                 ast_channel_unref(chan);
751                 return -1;
752         }
753
754         ao2_lock(p);
755         ast_set_flag(p, AST_UNREAL_CARETAKER_THREAD);
756         ao2_unlock(p);
757         ast_channel_unref(chan);
758
759         return 0;
760 }
761
762 int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
763 {
764         int hangup_chan = 0;
765         int res = 0;
766         int cause;
767         struct ast_channel *owner = NULL;
768         struct ast_channel *chan = NULL;
769
770         /* the pvt isn't going anywhere, it has a ref */
771         ast_channel_unlock(ast);
772
773         /* lock everything */
774         ast_unreal_lock_all(p, &chan, &owner);
775
776         if (ast != chan && ast != owner) {
777                 res = -1;
778                 goto unreal_hangup_cleanup;
779         }
780
781         cause = ast_channel_hangupcause(ast);
782
783         if (ast == p->chan) {
784                 /* Outgoing side is hanging up. */
785                 ast_clear_flag(p, AST_UNREAL_CARETAKER_THREAD);
786                 p->chan = NULL;
787                 if (p->owner) {
788                         const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
789
790                         if (status) {
791                                 ast_channel_hangupcause_set(p->owner, cause);
792                                 pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
793                         }
794                         ast_queue_hangup_with_cause(p->owner, cause);
795                 }
796         } else {
797                 /* Owner side is hanging up. */
798                 p->owner = NULL;
799                 if (p->chan) {
800                         if (cause == AST_CAUSE_ANSWERED_ELSEWHERE) {
801                                 ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
802                                 ast_debug(2, "%s has AST_CAUSE_ANSWERED_ELSEWHERE set.\n",
803                                         ast_channel_name(p->chan));
804                         }
805                         if (!ast_test_flag(p, AST_UNREAL_CARETAKER_THREAD)) {
806                                 /*
807                                  * Need to actually hangup p->chan since nothing else is taking
808                                  * care of it.
809                                  */
810                                 hangup_chan = 1;
811                         } else {
812                                 ast_queue_hangup_with_cause(p->chan, cause);
813                         }
814                 }
815         }
816
817         /* this is one of our locked channels, doesn't matter which */
818         ast_channel_tech_pvt_set(ast, NULL);
819         ao2_ref(p, -1);
820
821 unreal_hangup_cleanup:
822         ao2_unlock(p);
823         if (owner) {
824                 ast_channel_unlock(owner);
825                 ast_channel_unref(owner);
826         }
827         if (chan) {
828                 ast_channel_unlock(chan);
829                 if (hangup_chan) {
830                         ast_hangup(chan);
831                 }
832                 ast_channel_unref(chan);
833         }
834
835         /* leave with the channel locked that came in */
836         ast_channel_lock(ast);
837
838         return res;
839 }
840
841 void ast_unreal_destructor(void *vdoomed)
842 {
843         struct ast_unreal_pvt *doomed = vdoomed;
844
845         doomed->reqcap = ast_format_cap_destroy(doomed->reqcap);
846 }
847
848 struct ast_unreal_pvt *ast_unreal_alloc(size_t size, ao2_destructor_fn destructor, struct ast_format_cap *cap)
849 {
850         struct ast_unreal_pvt *unreal;
851
852         static const struct ast_jb_conf jb_conf = {
853                 .flags = 0,
854                 .max_size = -1,
855                 .resync_threshold = -1,
856                 .impl = "",
857                 .target_extra = -1,
858         };
859
860         unreal = ao2_alloc(size, destructor);
861         if (!unreal) {
862                 return NULL;
863         }
864         unreal->reqcap = ast_format_cap_dup(cap);
865         if (!unreal->reqcap) {
866                 ao2_ref(unreal, -1);
867                 return NULL;
868         }
869
870         memcpy(&unreal->jb_conf, &jb_conf, sizeof(unreal->jb_conf));
871
872         return unreal;
873 }
874
875 struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
876         const struct ast_channel_tech *tech, int semi1_state, int semi2_state,
877         const char *exten, const char *context, const struct ast_channel *requestor,
878         struct ast_callid *callid)
879 {
880         struct ast_channel *owner;
881         struct ast_channel *chan;
882         const char *linkedid = requestor ? ast_channel_linkedid(requestor) : NULL;
883         struct ast_format fmt;
884         int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
885
886         /*
887          * Allocate two new Asterisk channels
888          *
889          * Make sure that the ;2 channel gets the same linkedid as ;1.
890          * You can't pass linkedid to both allocations since if linkedid
891          * isn't set, then each channel will generate its own linkedid.
892          */
893         if (!(owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
894                         exten, context, linkedid, 0,
895                         "%s/%s-%08x;1", tech->type, p->name, generated_seqno))
896                 || !(chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
897                         exten, context, ast_channel_linkedid(owner), 0,
898                         "%s/%s-%08x;2", tech->type, p->name, generated_seqno))) {
899                 if (owner) {
900                         owner = ast_channel_release(owner);
901                 }
902                 ast_log(LOG_WARNING, "Unable to allocate channel structure(s)\n");
903                 return NULL;
904         }
905
906         if (callid) {
907                 ast_channel_callid_set(owner, callid);
908                 ast_channel_callid_set(chan, callid);
909         }
910
911         ast_channel_tech_set(owner, tech);
912         ast_channel_tech_set(chan, tech);
913         ast_channel_tech_pvt_set(owner, p);
914         ast_channel_tech_pvt_set(chan, p);
915
916         ast_format_cap_copy(ast_channel_nativeformats(owner), p->reqcap);
917         ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
918
919         /* Determine our read/write format and set it on each channel */
920         ast_best_codec(p->reqcap, &fmt);
921         ast_format_copy(ast_channel_writeformat(owner), &fmt);
922         ast_format_copy(ast_channel_writeformat(chan), &fmt);
923         ast_format_copy(ast_channel_rawwriteformat(owner), &fmt);
924         ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
925         ast_format_copy(ast_channel_readformat(owner), &fmt);
926         ast_format_copy(ast_channel_readformat(chan), &fmt);
927         ast_format_copy(ast_channel_rawreadformat(owner), &fmt);
928         ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
929
930         ast_set_flag(ast_channel_flags(owner), AST_FLAG_DISABLE_DEVSTATE_CACHE);
931         ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
932
933         ast_jb_configure(owner, &p->jb_conf);
934
935         if (ast_channel_cc_params_init(owner, requestor
936                 ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) {
937                 ast_channel_release(owner);
938                 ast_channel_release(chan);
939                 return NULL;
940         }
941
942         /* Give the private a ref for each channel. */
943         ao2_ref(p, +2);
944         p->owner = owner;
945         p->chan = chan;
946
947         return owner;
948 }