core_unreal: Fix off by one buffer overwrite error.
[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 media frames if a generator is on both unreal channels */
215         if (us
216                 && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)
217                 && ast_channel_generator(us)
218                 && ast_channel_generator(other)) {
219                 return 0;
220         }
221
222         /* grab a ref on the channel before unlocking the pvt,
223          * other can not go away from us now regardless of locking */
224         ast_channel_ref(other);
225         if (us && us_locked) {
226                 ast_channel_unlock(us);
227         }
228         ao2_unlock(p);
229
230         if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_RINGING) {
231                 ast_setstate(other, AST_STATE_RINGING);
232         }
233         ast_queue_frame(other, f);
234
235         other = ast_channel_unref(other);
236         if (us && us_locked) {
237                 ast_channel_lock(us);
238         }
239         ao2_lock(p);
240
241         return 0;
242 }
243
244 int ast_unreal_answer(struct ast_channel *ast)
245 {
246         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
247         int isoutbound;
248         int res = -1;
249
250         if (!p) {
251                 return -1;
252         }
253
254         ao2_ref(p, 1);
255         ao2_lock(p);
256         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
257         if (isoutbound) {
258                 /* Pass along answer since somebody answered us */
259                 struct ast_frame answer = { AST_FRAME_CONTROL, { AST_CONTROL_ANSWER } };
260
261                 res = unreal_queue_frame(p, isoutbound, &answer, ast, 1);
262         } else {
263                 ast_log(LOG_WARNING, "Huh?  %s is being asked to answer?\n",
264                         ast_channel_name(ast));
265         }
266         ao2_unlock(p);
267         ao2_ref(p, -1);
268         return res;
269 }
270
271 /*!
272  * \internal
273  * \brief Check and optimize out the unreal channels between bridges.
274  * \since 12.0.0
275  *
276  * \param ast Channel writing a frame into the unreal channels.
277  * \param p Unreal channel private.
278  *
279  * \note It is assumed that ast is locked.
280  * \note It is assumed that p is locked.
281  *
282  * \retval 0 if unreal channels were not optimized out.
283  * \retval non-zero if unreal channels were optimized out.
284  */
285 static int got_optimized_out(struct ast_channel *ast, struct ast_unreal_pvt *p)
286 {
287         int res = 0;
288
289         /* Do a few conditional checks early on just to see if this optimization is possible */
290         if (ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION) || !p->chan || !p->owner) {
291                 return res;
292         }
293
294         if (ast == p->owner) {
295                 res = ast_bridge_unreal_optimize_out(p->owner, p->chan, p);
296         } else if (ast == p->chan) {
297                 res = ast_bridge_unreal_optimize_out(p->chan, p->owner, p);
298         }
299
300         return res;
301 }
302
303 struct ast_frame  *ast_unreal_read(struct ast_channel *ast)
304 {
305         return &ast_null_frame;
306 }
307
308 int ast_unreal_write(struct ast_channel *ast, struct ast_frame *f)
309 {
310         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
311         int res = -1;
312
313         if (!p) {
314                 return -1;
315         }
316
317         /* Just queue for delivery to the other side */
318         ao2_ref(p, 1);
319         ao2_lock(p);
320         switch (f->frametype) {
321         case AST_FRAME_VOICE:
322         case AST_FRAME_VIDEO:
323                 if (got_optimized_out(ast, p)) {
324                         break;
325                 }
326                 /* fall through */
327         default:
328                 res = unreal_queue_frame(p, AST_UNREAL_IS_OUTBOUND(ast, p), f, ast, 1);
329                 break;
330         }
331         ao2_unlock(p);
332         ao2_ref(p, -1);
333
334         return res;
335 }
336
337 int ast_unreal_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
338 {
339         struct ast_unreal_pvt *p = ast_channel_tech_pvt(newchan);
340         struct ast_bridge *bridge_owner;
341         struct ast_bridge *bridge_chan;
342
343         if (!p) {
344                 return -1;
345         }
346
347         ao2_lock(p);
348
349         if ((p->owner != oldchan) && (p->chan != oldchan)) {
350                 ast_log(LOG_WARNING, "Old channel %p wasn't %p or %p\n", oldchan, p->owner, p->chan);
351                 ao2_unlock(p);
352                 return -1;
353         }
354         if (p->owner == oldchan) {
355                 p->owner = newchan;
356         } else {
357                 p->chan = newchan;
358         }
359
360         if (ast_check_hangup(newchan) || !p->owner || !p->chan) {
361                 ao2_unlock(p);
362                 return 0;
363         }
364
365         /* Do not let a masquerade cause an unreal channel to be bridged to itself! */
366         bridge_owner = ast_channel_internal_bridge(p->owner);
367         bridge_chan = ast_channel_internal_bridge(p->chan);
368         if (bridge_owner && bridge_owner == bridge_chan) {
369                 ast_log(LOG_WARNING, "You can not bridge an unreal channel (%s) to itself!\n",
370                         ast_channel_name(newchan));
371                 ao2_unlock(p);
372                 ast_queue_hangup(newchan);
373                 return -1;
374         }
375
376         ao2_unlock(p);
377         return 0;
378 }
379
380 /*!
381  * \internal
382  * \brief Queue up a frame representing the indication as a control frame.
383  * \since 12.0.0
384  *
385  * \param p Unreal private structure.
386  * \param ast Channel indicating the condition.
387  * \param condition What is being indicated.
388  * \param data Extra data.
389  * \param datalen Length of extra data.
390  *
391  * \retval 0 on success.
392  * \retval AST_T38_REQUEST_PARMS if successful and condition is AST_CONTROL_T38_PARAMETERS.
393  * \retval -1 on error.
394  */
395 static int unreal_queue_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition, const void *data, size_t datalen)
396 {
397         int res = 0;
398         int isoutbound;
399
400         ao2_lock(p);
401         /*
402          * Block -1 stop tones events if we are to be optimized out.  We
403          * don't need a flurry of these events on an unreal channel chain
404          * when initially connected to slow the optimization process.
405          */
406         if (0 <= condition || ast_test_flag(p, AST_UNREAL_NO_OPTIMIZATION)) {
407                 struct ast_frame f = {
408                         .frametype = AST_FRAME_CONTROL,
409                         .subclass.integer = condition,
410                         .data.ptr = (void *) data,
411                         .datalen = datalen,
412                 };
413
414                 isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
415                 res = unreal_queue_frame(p, isoutbound, &f, ast, 1);
416                 if (!res
417                         && condition == AST_CONTROL_T38_PARAMETERS
418                         && datalen == sizeof(struct ast_control_t38_parameters)) {
419                         const struct ast_control_t38_parameters *parameters = data;
420
421                         if (parameters->request_response == AST_T38_REQUEST_PARMS) {
422                                 res = AST_T38_REQUEST_PARMS;
423                         }
424                 }
425         } else {
426                 ast_debug(4, "Blocked indication %d\n", condition);
427         }
428         ao2_unlock(p);
429
430         return res;
431 }
432
433 /*!
434  * \internal
435  * \brief Handle COLP and redirecting conditions.
436  * \since 12.0.0
437  *
438  * \param p Unreal private structure.
439  * \param ast Channel indicating the condition.
440  * \param condition What is being indicated.
441  *
442  * \retval 0 on success.
443  * \retval -1 on error.
444  */
445 static int unreal_colp_redirect_indicate(struct ast_unreal_pvt *p, struct ast_channel *ast, int condition)
446 {
447         struct ast_channel *my_chan;
448         struct ast_channel *my_owner;
449         struct ast_channel *this_channel;
450         struct ast_channel *the_other_channel;
451         int isoutbound;
452         int res = 0;
453         unsigned char frame_data[1024];
454         struct ast_frame f = {
455                 .frametype = AST_FRAME_CONTROL,
456                 .subclass.integer = condition,
457                 .data.ptr = frame_data,
458         };
459
460         /*
461          * A connected line update frame may only contain a partial
462          * amount of data, such as just a source, or just a ton, and not
463          * the full amount of information.  However, the collected
464          * information is all stored in the outgoing channel's
465          * connectedline structure, so when receiving a connected line
466          * update on an outgoing unreal channel, we need to transmit the
467          * collected connected line information instead of whatever
468          * happens to be in this control frame.  The same applies for
469          * redirecting information, which is why it is handled here as
470          * well.
471          */
472         ast_channel_unlock(ast);
473         ast_unreal_lock_all(p, &my_chan, &my_owner);
474         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
475         if (isoutbound) {
476                 this_channel = p->chan;
477                 the_other_channel = p->owner;
478         } else {
479                 this_channel = p->owner;
480                 the_other_channel = p->chan;
481         }
482         if (the_other_channel) {
483                 if (condition == AST_CONTROL_CONNECTED_LINE) {
484                         ast_connected_line_copy_to_caller(ast_channel_caller(the_other_channel),
485                                 ast_channel_connected(this_channel));
486                         f.datalen = ast_connected_line_build_data(frame_data, sizeof(frame_data),
487                                 ast_channel_connected(this_channel), NULL);
488                 } else {
489                         f.datalen = ast_redirecting_build_data(frame_data, sizeof(frame_data),
490                                 ast_channel_redirecting(this_channel), NULL);
491                 }
492         }
493         if (my_chan) {
494                 ast_channel_unlock(my_chan);
495                 ast_channel_unref(my_chan);
496         }
497         if (my_owner) {
498                 ast_channel_unlock(my_owner);
499                 ast_channel_unref(my_owner);
500         }
501         if (the_other_channel) {
502                 res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
503         }
504         ao2_unlock(p);
505         ast_channel_lock(ast);
506
507         return res;
508 }
509
510 int ast_unreal_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
511 {
512         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
513         int res = 0;
514
515         if (!p) {
516                 return -1;
517         }
518
519         ao2_ref(p, 1); /* ref for unreal_queue_frame */
520
521         switch (condition) {
522         case AST_CONTROL_CONNECTED_LINE:
523         case AST_CONTROL_REDIRECTING:
524                 res = unreal_colp_redirect_indicate(p, ast, condition);
525                 break;
526         case AST_CONTROL_HOLD:
527                 if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
528                         ast_moh_start(ast, data, NULL);
529                         break;
530                 }
531                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
532                 break;
533         case AST_CONTROL_UNHOLD:
534                 if (ast_test_flag(p, AST_UNREAL_MOH_INTERCEPT)) {
535                         ast_moh_stop(ast);
536                         break;
537                 }
538                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
539                 break;
540         default:
541                 res = unreal_queue_indicate(p, ast, condition, data, datalen);
542                 break;
543         }
544
545         ao2_ref(p, -1);
546         return res;
547 }
548
549 int ast_unreal_digit_begin(struct ast_channel *ast, char digit)
550 {
551         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
552         int res = -1;
553         struct ast_frame f = { AST_FRAME_DTMF_BEGIN, };
554         int isoutbound;
555
556         if (!p) {
557                 return -1;
558         }
559
560         ao2_ref(p, 1); /* ref for unreal_queue_frame */
561         ao2_lock(p);
562         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
563         f.subclass.integer = digit;
564         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
565         ao2_unlock(p);
566         ao2_ref(p, -1);
567
568         return res;
569 }
570
571 int ast_unreal_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
572 {
573         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
574         int res = -1;
575         struct ast_frame f = { AST_FRAME_DTMF_END, };
576         int isoutbound;
577
578         if (!p) {
579                 return -1;
580         }
581
582         ao2_ref(p, 1); /* ref for unreal_queue_frame */
583         ao2_lock(p);
584         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
585         f.subclass.integer = digit;
586         f.len = duration;
587         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
588         ao2_unlock(p);
589         ao2_ref(p, -1);
590
591         return res;
592 }
593
594 int ast_unreal_sendtext(struct ast_channel *ast, const char *text)
595 {
596         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
597         int res = -1;
598         struct ast_frame f = { AST_FRAME_TEXT, };
599         int isoutbound;
600
601         if (!p) {
602                 return -1;
603         }
604
605         ao2_ref(p, 1); /* ref for unreal_queue_frame */
606         ao2_lock(p);
607         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
608         f.data.ptr = (char *) text;
609         f.datalen = strlen(text) + 1;
610         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
611         ao2_unlock(p);
612         ao2_ref(p, -1);
613         return res;
614 }
615
616 int ast_unreal_sendhtml(struct ast_channel *ast, int subclass, const char *data, int datalen)
617 {
618         struct ast_unreal_pvt *p = ast_channel_tech_pvt(ast);
619         int res = -1;
620         struct ast_frame f = { AST_FRAME_HTML, };
621         int isoutbound;
622
623         if (!p) {
624                 return -1;
625         }
626
627         ao2_ref(p, 1); /* ref for unreal_queue_frame */
628         ao2_lock(p);
629         isoutbound = AST_UNREAL_IS_OUTBOUND(ast, p);
630         f.subclass.integer = subclass;
631         f.data.ptr = (char *)data;
632         f.datalen = datalen;
633         res = unreal_queue_frame(p, isoutbound, &f, ast, 0);
634         ao2_unlock(p);
635         ao2_ref(p, -1);
636
637         return res;
638 }
639
640 void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
641 {
642         struct ast_var_t *varptr;
643         struct ast_var_t *clone_var;
644
645         /*
646          * Note that cid_num and cid_name aren't passed in the
647          * ast_channel_alloc calls in ast_unreal_new_channels().  It's
648          * done here instead.
649          */
650         ast_party_redirecting_copy(ast_channel_redirecting(semi2), ast_channel_redirecting(semi1));
651
652         ast_party_dialed_copy(ast_channel_dialed(semi2), ast_channel_dialed(semi1));
653
654         ast_connected_line_copy_to_caller(ast_channel_caller(semi2), ast_channel_connected(semi1));
655         ast_connected_line_copy_from_caller(ast_channel_connected(semi2), ast_channel_caller(semi1));
656
657         ast_channel_language_set(semi2, ast_channel_language(semi1));
658         ast_channel_accountcode_set(semi2, ast_channel_accountcode(semi1));
659         ast_channel_musicclass_set(semi2, ast_channel_musicclass(semi1));
660
661         ast_channel_cc_params_init(semi2, ast_channel_get_cc_config_params(semi1));
662
663         /*
664          * Make sure we inherit the AST_CAUSE_ANSWERED_ELSEWHERE if it's
665          * set on the queue/dial call request in the dialplan.
666          */
667         if (ast_channel_hangupcause(semi1) == AST_CAUSE_ANSWERED_ELSEWHERE) {
668                 ast_channel_hangupcause_set(semi2, AST_CAUSE_ANSWERED_ELSEWHERE);
669         }
670
671         /*
672          * Copy the channel variables from the semi1 channel to the
673          * outgoing channel.
674          *
675          * Note that due to certain assumptions, they MUST be in the
676          * same order.
677          */
678         AST_LIST_TRAVERSE(ast_channel_varshead(semi1), varptr, entries) {
679                 clone_var = ast_var_assign(varptr->name, varptr->value);
680                 if (clone_var) {
681                         AST_LIST_INSERT_TAIL(ast_channel_varshead(semi2), clone_var, entries);
682                 }
683         }
684         ast_channel_datastore_inherit(semi1, semi2);
685 }
686
687 int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge, unsigned int flags)
688 {
689         struct ast_bridge_features *features;
690         struct ast_channel *chan;
691         struct ast_channel *owner;
692         RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);
693
694         RAII_VAR(struct ast_callid *, bridge_callid, NULL, ast_callid_cleanup);
695
696         ast_bridge_lock(bridge);
697         bridge_callid = bridge->callid ? ast_callid_ref(bridge->callid) : NULL;
698         ast_bridge_unlock(bridge);
699
700         {
701                 SCOPED_CHANNELLOCK(lock, ast);
702                 p = ast_channel_tech_pvt(ast);
703                 if (!p) {
704                         return -1;
705                 }
706                 ao2_ref(p, +1);
707         }
708
709         {
710                 SCOPED_AO2LOCK(lock, p);
711                 chan = p->chan;
712                 if (!chan) {
713                         return -1;
714                 }
715
716                 owner = p->owner;
717                 if (!owner) {
718                         return -1;
719                 }
720
721                 ast_channel_ref(chan);
722                 ast_channel_ref(owner);
723         }
724
725         if (bridge_callid) {
726                 struct ast_callid *chan_callid;
727                 struct ast_callid *owner_callid;
728
729                 /* chan side call ID setting */
730                 ast_channel_lock(chan);
731
732                 chan_callid = ast_channel_callid(chan);
733                 if (!chan_callid) {
734                         ast_channel_callid_set(chan, bridge_callid);
735                 }
736                 ast_channel_unlock(chan);
737                 ast_callid_cleanup(chan_callid);
738
739                 /* owner side call ID setting */
740                 ast_channel_lock(owner);
741
742                 owner_callid = ast_channel_callid(owner);
743                 if (!owner_callid) {
744                         ast_channel_callid_set(owner, bridge_callid);
745                 }
746
747                 ast_channel_unlock(owner);
748                 ast_callid_cleanup(owner_callid);
749         }
750
751         /* We are done with the owner now that its call ID matches the bridge */
752         ast_channel_unref(owner);
753         owner = NULL;
754
755         features = ast_bridge_features_new();
756         if (!features) {
757                 ast_channel_unref(chan);
758                 return -1;
759         }
760
761         ast_set_flag(&features->feature_flags, flags);
762
763         /* Impart the semi2 channel into the bridge */
764         if (ast_bridge_impart(bridge, chan, NULL, features,
765                 AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
766                 ast_bridge_features_destroy(features);
767                 ast_channel_unref(chan);
768                 return -1;
769         }
770
771         ao2_lock(p);
772         ast_set_flag(p, AST_UNREAL_CARETAKER_THREAD);
773         ao2_unlock(p);
774         ast_channel_unref(chan);
775
776         return 0;
777 }
778
779 int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
780 {
781         int hangup_chan = 0;
782         int res = 0;
783         int cause;
784         struct ast_channel *owner = NULL;
785         struct ast_channel *chan = NULL;
786
787         /* the pvt isn't going anywhere, it has a ref */
788         ast_channel_unlock(ast);
789
790         /* lock everything */
791         ast_unreal_lock_all(p, &chan, &owner);
792
793         if (ast != chan && ast != owner) {
794                 res = -1;
795                 goto unreal_hangup_cleanup;
796         }
797
798         cause = ast_channel_hangupcause(ast);
799
800         if (ast == p->chan) {
801                 /* Outgoing side is hanging up. */
802                 ast_clear_flag(p, AST_UNREAL_CARETAKER_THREAD);
803                 p->chan = NULL;
804                 if (p->owner) {
805                         const char *status = pbx_builtin_getvar_helper(p->chan, "DIALSTATUS");
806
807                         if (status) {
808                                 ast_channel_hangupcause_set(p->owner, cause);
809                                 pbx_builtin_setvar_helper(p->owner, "CHANLOCALSTATUS", status);
810                         }
811                         ast_queue_hangup_with_cause(p->owner, cause);
812                 }
813         } else {
814                 /* Owner side is hanging up. */
815                 p->owner = NULL;
816                 if (p->chan) {
817                         if (cause == AST_CAUSE_ANSWERED_ELSEWHERE) {
818                                 ast_channel_hangupcause_set(p->chan, AST_CAUSE_ANSWERED_ELSEWHERE);
819                                 ast_debug(2, "%s has AST_CAUSE_ANSWERED_ELSEWHERE set.\n",
820                                         ast_channel_name(p->chan));
821                         }
822                         if (!ast_test_flag(p, AST_UNREAL_CARETAKER_THREAD)) {
823                                 /*
824                                  * Need to actually hangup p->chan since nothing else is taking
825                                  * care of it.
826                                  */
827                                 hangup_chan = 1;
828                         } else {
829                                 ast_queue_hangup_with_cause(p->chan, cause);
830                         }
831                 }
832         }
833
834         /* this is one of our locked channels, doesn't matter which */
835         ast_channel_tech_pvt_set(ast, NULL);
836         ao2_ref(p, -1);
837
838 unreal_hangup_cleanup:
839         ao2_unlock(p);
840         if (owner) {
841                 ast_channel_unlock(owner);
842                 ast_channel_unref(owner);
843         }
844         if (chan) {
845                 ast_channel_unlock(chan);
846                 if (hangup_chan) {
847                         ast_hangup(chan);
848                 }
849                 ast_channel_unref(chan);
850         }
851
852         /* leave with the channel locked that came in */
853         ast_channel_lock(ast);
854
855         return res;
856 }
857
858 void ast_unreal_destructor(void *vdoomed)
859 {
860         struct ast_unreal_pvt *doomed = vdoomed;
861
862         doomed->reqcap = ast_format_cap_destroy(doomed->reqcap);
863 }
864
865 struct ast_unreal_pvt *ast_unreal_alloc(size_t size, ao2_destructor_fn destructor, struct ast_format_cap *cap)
866 {
867         struct ast_unreal_pvt *unreal;
868
869         static const struct ast_jb_conf jb_conf = {
870                 .flags = 0,
871                 .max_size = -1,
872                 .resync_threshold = -1,
873                 .impl = "",
874                 .target_extra = -1,
875         };
876
877         unreal = ao2_alloc(size, destructor);
878         if (!unreal) {
879                 return NULL;
880         }
881         unreal->reqcap = ast_format_cap_dup(cap);
882         if (!unreal->reqcap) {
883                 ao2_ref(unreal, -1);
884                 return NULL;
885         }
886
887         memcpy(&unreal->jb_conf, &jb_conf, sizeof(unreal->jb_conf));
888
889         return unreal;
890 }
891
892 struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
893         const struct ast_channel_tech *tech, int semi1_state, int semi2_state,
894         const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
895         const struct ast_channel *requestor, struct ast_callid *callid)
896 {
897         struct ast_channel *owner;
898         struct ast_channel *chan;
899         struct ast_format fmt;
900         struct ast_assigned_ids id1 = {NULL, NULL};
901         struct ast_assigned_ids id2 = {NULL, NULL};
902         int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
903
904         /* set unique ids for the two channels */
905         if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
906                 id1.uniqueid = assignedids->uniqueid;
907                 id2.uniqueid = assignedids->uniqueid2;
908         }
909
910         /* if id1 given but not id2, use default of id1;2 */
911         if (id1.uniqueid && ast_strlen_zero(id2.uniqueid)) {
912                 char *uniqueid2;
913
914                 uniqueid2 = ast_alloca(strlen(id1.uniqueid) + 3);
915                 strcpy(uniqueid2, id1.uniqueid);/* Safe */
916                 strcat(uniqueid2, ";2");/* Safe */
917                 id2.uniqueid = uniqueid2;
918         }
919
920         /*
921          * Allocate two new Asterisk channels
922          *
923          * Make sure that the ;2 channel gets the same linkedid as ;1.
924          * You can't pass linkedid to both allocations since if linkedid
925          * isn't set, then each channel will generate its own linkedid.
926          */
927         owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
928                 exten, context, &id1, requestor, 0,
929                 "%s/%s-%08x;1", tech->type, p->name, (unsigned)generated_seqno);
930         if (!owner) {
931                 ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n");
932                 return NULL;
933         }
934
935         if (callid) {
936                 ast_channel_callid_set(owner, callid);
937         }
938
939         ast_channel_tech_set(owner, tech);
940         ao2_ref(p, +1);
941         ast_channel_tech_pvt_set(owner, p);
942
943         ast_format_cap_copy(ast_channel_nativeformats(owner), p->reqcap);
944
945         /* Determine our read/write format and set it on each channel */
946         ast_best_codec(p->reqcap, &fmt);
947         ast_format_copy(ast_channel_writeformat(owner), &fmt);
948         ast_format_copy(ast_channel_rawwriteformat(owner), &fmt);
949         ast_format_copy(ast_channel_readformat(owner), &fmt);
950         ast_format_copy(ast_channel_rawreadformat(owner), &fmt);
951
952         ast_set_flag(ast_channel_flags(owner), AST_FLAG_DISABLE_DEVSTATE_CACHE);
953
954         ast_jb_configure(owner, &p->jb_conf);
955
956         if (ast_channel_cc_params_init(owner, requestor
957                 ? ast_channel_get_cc_config_params((struct ast_channel *) requestor) : NULL)) {
958                 ao2_ref(p, -1);
959                 ast_channel_tech_pvt_set(owner, NULL);
960                 ast_channel_unlock(owner);
961                 ast_channel_release(owner);
962                 return NULL;
963         }
964
965         p->owner = owner;
966         ast_channel_unlock(owner);
967
968         chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
969                 exten, context, &id2, owner, 0,
970                 "%s/%s-%08x;2", tech->type, p->name, (unsigned)generated_seqno);
971         if (!chan) {
972                 ast_log(LOG_WARNING, "Unable to allocate chan channel structure\n");
973                 ao2_ref(p, -1);
974                 ast_channel_tech_pvt_set(owner, NULL);
975                 ast_channel_release(owner);
976                 return NULL;
977         }
978
979         if (callid) {
980                 ast_channel_callid_set(chan, callid);
981         }
982
983         ast_channel_tech_set(chan, tech);
984         ao2_ref(p, +1);
985         ast_channel_tech_pvt_set(chan, p);
986
987         ast_format_cap_copy(ast_channel_nativeformats(chan), p->reqcap);
988
989         /* Format was already determined when setting up owner */
990         ast_format_copy(ast_channel_writeformat(chan), &fmt);
991         ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
992         ast_format_copy(ast_channel_readformat(chan), &fmt);
993         ast_format_copy(ast_channel_rawreadformat(chan), &fmt);
994
995         ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_DEVSTATE_CACHE);
996
997         p->chan = chan;
998         ast_channel_unlock(chan);
999
1000         return owner;
1001 }