Asterisk - The Open Source Telephony Project GIT-master-2de1a68
bridge_native_dahdi.c
Go to the documentation of this file.
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 Native DAHDI bridging support.
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#include "../sig_analog.h"
36#if defined(HAVE_PRI)
37#include "../sig_pri.h"
38#endif /* defined(HAVE_PRI) */
39#include "../chan_dahdi.h"
40
41#include "bridge_native_dahdi.h"
42#include "asterisk/bridge.h"
44#include "asterisk/frame.h"
46
47/* ------------------------------------------------------------------- */
48
49static const struct ast_channel_tech *dahdi_tech;
50
52 /*! Original private. */
53 struct dahdi_pvt *pvt;
54 /*! Original private owner. */
56 /*! Original owner index. */
57 int index;
58 /*! Original file descriptor 0. */
59 int fd0;
60 /*! Original channel state. */
61 int state;
62 /*! Original inthreeway. */
63 unsigned int inthreeway:1;
64};
65
67 /*! Master channel in the native bridge. */
69 /*! Slave channel in the native bridge. */
71 /*! TRUE if the bridge can start when ready. */
72 unsigned int saw_start:1;
73 /*! TRUE if the channels are connected in a conference. */
74 unsigned int connected:1;
75#if defined(HAVE_PRI) && defined(PRI_2BCT)
76 /*!
77 * \brief TRUE if tried to eliminate possible PRI tromboned call.
78 *
79 * \note A tromboned call uses two B channels of the same ISDN
80 * span. One leg comes into Asterisk, the other leg goes out of
81 * Asterisk, and Asterisk is natively bridging the two legs.
82 */
83 unsigned int tried_trombone_removal:1;
84#endif /* defined(HAVE_PRI) && defined(PRI_2BCT) */
85};
86
87/*!
88 * \internal
89 * \brief Create a bridge technology instance for a bridge.
90 * \since 12.0.0
91 *
92 * \retval 0 on success
93 * \retval -1 on failure
94 *
95 * \note On entry, bridge may or may not already be locked.
96 * However, it can be accessed as if it were locked.
97 */
98static int native_bridge_create(struct ast_bridge *bridge)
99{
100 struct native_pvt_bridge *tech_pvt;
101
102 ast_assert(!bridge->tech_pvt);
103
104 tech_pvt = ast_calloc(1, sizeof(*tech_pvt));
105 if (!tech_pvt) {
106 return -1;
107 }
108
109 bridge->tech_pvt = tech_pvt;
110 return 0;
111}
112
113/*!
114 * \internal
115 * \brief Destroy a bridging technology instance for a bridge.
116 * \since 12.0.0
117 *
118 * \note On entry, bridge must NOT be locked.
119 */
120static void native_bridge_destroy(struct ast_bridge *bridge)
121{
122 struct native_pvt_bridge *tech_pvt;
123
124 tech_pvt = bridge->tech_pvt;
125 bridge->tech_pvt = NULL;
126 ast_free(tech_pvt);
127}
128
129/*!
130 * \internal
131 * \brief Stop native bridging activity.
132 * \since 12.0.0
133 *
134 * \param bridge What to operate upon.
135 *
136 * \note On entry, bridge is already locked.
137 */
138static void native_stop(struct ast_bridge *bridge)
139{
140 struct native_pvt_bridge *bridge_tech_pvt;
141 struct ast_bridge_channel *cur;
142
144
146 struct native_pvt_chan *chan_tech_pvt;
147
148 chan_tech_pvt = cur->tech_pvt;
149 if (!chan_tech_pvt) {
150 continue;
151 }
152
153 ast_mutex_lock(&chan_tech_pvt->pvt->lock);
154 if (chan_tech_pvt->pvt == ast_channel_tech_pvt(cur->chan)) {
155 dahdi_ec_enable(chan_tech_pvt->pvt);
156 }
157 if (chan_tech_pvt->index == SUB_REAL) {
158 dahdi_dtmf_detect_enable(chan_tech_pvt->pvt);
159 }
160 ast_mutex_unlock(&chan_tech_pvt->pvt->lock);
161 }
162
163 bridge_tech_pvt = bridge->tech_pvt;
164 dahdi_master_slave_unlink(bridge_tech_pvt->slave, bridge_tech_pvt->master, 1);
165
166 ast_debug(2, "Stop native bridging %s and %s\n",
168 ast_channel_name(AST_LIST_LAST(&bridge->channels)->chan));
169}
170
171/*!
172 * \internal
173 * \brief Request to stop native bridging activity.
174 * \since 12.0.0
175 *
176 * \param bridge What to operate upon.
177 *
178 * \note On entry, bridge is already locked.
179 */
180static void native_request_stop(struct ast_bridge *bridge)
181{
182 struct native_pvt_bridge *tech_pvt;
183
184 ast_assert(bridge->tech_pvt != NULL);
185
186 tech_pvt = bridge->tech_pvt;
187 if (!tech_pvt->connected) {
188 return;
189 }
190 tech_pvt->connected = 0;
191
192 /* Now to actually stop the bridge. */
193 native_stop(bridge);
194}
195
196/*!
197 * \internal
198 * \brief Start native bridging activity.
199 * \since 12.0.0
200 *
201 * \param bridge What to operate upon.
202 *
203 * \retval 0 on success.
204 * \retval -1 on error. Could not start the bridge.
205 *
206 * \note On entry, bridge may or may not already be locked.
207 * However, it can be accessed as if it were locked.
208 */
209static int native_start(struct ast_bridge *bridge)
210{
211 struct native_pvt_bridge *tech_pvt;
212 struct ast_bridge_channel *bc0;
213 struct ast_bridge_channel *bc1;
214 struct native_pvt_chan *npc0;
215 struct native_pvt_chan *npc1;
216 struct ast_channel *c0;
217 struct ast_channel *c1;
218 struct dahdi_pvt *p0;
219 struct dahdi_pvt *p1;
220 struct dahdi_pvt *master;
221 struct dahdi_pvt *slave;
222 int inconf;
223 int nothing_ok;
224
225 ast_assert(bridge->tech_pvt != NULL);
226
227 bc0 = AST_LIST_FIRST(&bridge->channels);
228 bc1 = AST_LIST_LAST(&bridge->channels);
229 c0 = bc0->chan;
230 c1 = bc1->chan;
231
232 /* Lock channels and privates */
233 for (;;) {
235 if (!ast_channel_trylock(c1)) {
236 p0 = ast_channel_tech_pvt(c0);
237 if (!ast_mutex_trylock(&p0->lock)) {
238 p1 = ast_channel_tech_pvt(c1);
239 if (!ast_mutex_trylock(&p1->lock)) {
240 /* Got all locks */
241 break;
242 }
244 }
246 }
248 sched_yield();
249 }
250
251 npc0 = bc0->tech_pvt;
252 ast_assert(npc0 != NULL);
253 npc0->pvt = p0;
254 npc0->owner = p0->owner;
255 npc0->index = dahdi_get_index(c0, p0, 0);
256 npc0->fd0 = ast_channel_fd(c0, 0);
257 npc0->state = -1;
258 npc0->inthreeway = p0->subs[SUB_REAL].inthreeway;
259
260 npc1 = bc1->tech_pvt;
261 ast_assert(npc1 != NULL);
262 npc1->pvt = p1;
263 npc1->owner = p1->owner;
264 npc1->index = dahdi_get_index(c1, p1, 0);
265 npc1->fd0 = ast_channel_fd(c1, 0);
266 npc1->state = -1;
267 npc1->inthreeway = p1->subs[SUB_REAL].inthreeway;
268
269 /*
270 * Check things that can change on the privates while in native
271 * bridging and cause native to not activate.
272 */
273 if (npc0->index < 0 || npc1->index < 0
274#if defined(HAVE_PRI)
275 /*
276 * PRI nobch channels (hold and call waiting) are equivalent to
277 * pseudo channels and cannot be natively bridged.
278 */
280 && ((struct sig_pri_chan *) p0->sig_pvt)->no_b_channel)
282 && ((struct sig_pri_chan *) p1->sig_pvt)->no_b_channel)
283#endif /* defined(HAVE_PRI) */
284 ) {
289 return -1;
290 }
291
292 inconf = 0;
293 nothing_ok = 1;
294 master = NULL;
295 slave = NULL;
296 if (npc0->index == SUB_REAL && npc1->index == SUB_REAL) {
297 if (p0->owner && p1->owner) {
298 /*
299 * If we don't have a call-wait in a 3-way, and we aren't in a
300 * 3-way, we can be master.
301 */
302 if (!p0->subs[SUB_CALLWAIT].inthreeway && !p1->subs[SUB_REAL].inthreeway) {
303 master = p0;
304 slave = p1;
305 inconf = 1;
306 } else if (!p1->subs[SUB_CALLWAIT].inthreeway && !p0->subs[SUB_REAL].inthreeway) {
307 master = p1;
308 slave = p0;
309 inconf = 1;
310 } else {
311 ast_log(LOG_WARNING, "Huh? Both calls are callwaits or 3-ways? That's clever...?\n");
312 ast_log(LOG_WARNING, "p0: chan %d/%d/CW%d/3W%d, p1: chan %d/%d/CW%d/3W%d\n",
313 p0->channel,
314 npc0->index, (p0->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
316 p0->channel,
317 npc0->index, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
319 }
320 nothing_ok = 0;
321 }
322 } else if (npc0->index == SUB_REAL && npc1->index == SUB_THREEWAY) {
323 if (p1->subs[SUB_THREEWAY].inthreeway) {
324 master = p1;
325 slave = p0;
326 nothing_ok = 0;
327 }
328 } else if (npc0->index == SUB_THREEWAY && npc1->index == SUB_REAL) {
329 if (p0->subs[SUB_THREEWAY].inthreeway) {
330 master = p0;
331 slave = p1;
332 nothing_ok = 0;
333 }
334 } else if (npc0->index == SUB_REAL && npc1->index == SUB_CALLWAIT) {
335 /*
336 * We have a real and a call wait. If we're in a three way
337 * call, put us in it, otherwise, don't put us in anything.
338 */
339 if (p1->subs[SUB_CALLWAIT].inthreeway) {
340 master = p1;
341 slave = p0;
342 nothing_ok = 0;
343 }
344 } else if (npc0->index == SUB_CALLWAIT && npc1->index == SUB_REAL) {
345 /* Same as previous */
346 if (p0->subs[SUB_CALLWAIT].inthreeway) {
347 master = p0;
348 slave = p1;
349 nothing_ok = 0;
350 }
351 }
352 ast_debug(3, "master: %d, slave: %d, nothing_ok: %d\n",
353 master ? master->channel : 0,
354 slave ? slave->channel : 0,
355 nothing_ok);
356 if (master && slave) {
357 /*
358 * Stop any tones, or play ringtone as appropriate. If they are
359 * bridged in an active threeway call with a channel that is
360 * ringing, we should indicate ringing.
361 */
362 if (npc1->index == SUB_THREEWAY
364 && p1->subs[SUB_REAL].owner
365 && p1->subs[SUB_REAL].inthreeway
367 ast_debug(2,
368 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
369 p0->channel, npc0->index, ast_channel_name(c0),
370 p1->channel, npc1->index, ast_channel_name(c1));
371 tone_zone_play_tone(p0->subs[npc0->index].dfd, DAHDI_TONE_RINGTONE);
373 } else {
374 ast_debug(2, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
375 p0->channel, npc0->index, ast_channel_name(c0),
376 p1->channel, npc1->index, ast_channel_name(c1));
377 tone_zone_play_tone(p0->subs[npc0->index].dfd, -1);
378 }
379
380 if (npc0->index == SUB_THREEWAY
382 && p0->subs[SUB_REAL].owner
383 && p0->subs[SUB_REAL].inthreeway
385 ast_debug(2,
386 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
387 p1->channel, npc1->index, ast_channel_name(c1),
388 p0->channel, npc0->index, ast_channel_name(c0));
389 tone_zone_play_tone(p1->subs[npc1->index].dfd, DAHDI_TONE_RINGTONE);
391 } else {
392 ast_debug(2, "Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
393 p1->channel, npc1->index, ast_channel_name(c1),
394 p0->channel, npc0->index, ast_channel_name(c0));
395 tone_zone_play_tone(p1->subs[npc1->index].dfd, -1);
396 }
397
398 if (npc0->index == SUB_REAL && npc1->index == SUB_REAL) {
399 if (!p0->echocanbridged || !p1->echocanbridged) {
400 /* Disable echo cancellation if appropriate */
403 }
404 }
406 master->inconference = inconf;
407 } else if (!nothing_ok) {
408 ast_log(LOG_WARNING, "Can't link %d/%s with %d/%s\n",
409 p0->channel, subnames[npc0->index],
410 p1->channel, subnames[npc1->index]);
411 }
414
417
418 /* Native bridge failed */
419 if ((!master || !slave) && !nothing_ok) {
422 return -1;
423 }
424
425 if (npc0->index == SUB_REAL) {
427 }
428 if (npc1->index == SUB_REAL) {
430 }
431
434
435 tech_pvt = bridge->tech_pvt;
436 tech_pvt->master = master;
437 tech_pvt->slave = slave;
438
439 ast_debug(2, "Start native bridging %s and %s\n",
441
442#if defined(HAVE_PRI) && defined(PRI_2BCT)
443 if (!tech_pvt->tried_trombone_removal) {
444 tech_pvt->tried_trombone_removal = 1;
445
446 if (p0->pri && p0->pri == p1->pri && p0->pri->transfer) {
447 q931_call *q931_c0;
448 q931_call *q931_c1;
449
450 /* Try to eliminate the tromboned call. */
451 ast_mutex_lock(&p0->pri->lock);
454 q931_c0 = ((struct sig_pri_chan *) (p0->sig_pvt))->call;
455 q931_c1 = ((struct sig_pri_chan *) (p1->sig_pvt))->call;
456 if (q931_c0 && q931_c1) {
457 pri_channel_bridge(q931_c0, q931_c1);
458 ast_debug(2, "Attempt to eliminate tromboned call with %s and %s\n",
460 }
461 ast_mutex_unlock(&p0->pri->lock);
462 }
463 }
464#endif /* defined(HAVE_PRI) && defined(PRI_2BCT) */
465 return 0;
466}
467
468/*!
469 * \internal
470 * \brief Request to start native bridging activity.
471 * \since 12.0.0
472 *
473 * \param bridge What to operate upon.
474 *
475 * \note On entry, bridge may or may not already be locked.
476 * However, it can be accessed as if it were locked.
477 */
478static void native_request_start(struct ast_bridge *bridge)
479{
480 struct native_pvt_bridge *tech_pvt;
481 struct ast_bridge_channel *cur;
482
484
486
487 if (bridge->num_channels != 2 || !tech_pvt->saw_start || tech_pvt->connected) {
488 return;
489 }
491 if (cur->suspended || !cur->tech_pvt) {
492 return;
493 }
494 }
495
496 /* Actually try starting the native bridge. */
497 if (native_start(bridge)) {
498 return;
499 }
500 tech_pvt->connected = 1;
501}
502
503/*!
504 * \internal
505 * \brief Request a bridge technology instance start operations.
506 * \since 12.0.0
507 *
508 * \retval 0 on success
509 * \retval -1 on failure
510 *
511 * \note On entry, bridge may or may not already be locked.
512 * However, it can be accessed as if it were locked.
513 */
515{
516 struct native_pvt_bridge *tech_pvt;
517
518 ast_assert(bridge->tech_pvt != NULL);
519
520 tech_pvt = bridge->tech_pvt;
521 tech_pvt->saw_start = 1;
522
523 native_request_start(bridge);
524 return 0;
525}
526
527/*!
528 * \internal
529 * \brief Request a bridge technology instance stop in preparation for being destroyed.
530 * \since 12.0.0
531 *
532 * \note On entry, bridge is already locked.
533 */
534static void native_bridge_stop(struct ast_bridge *bridge)
535{
536 struct native_pvt_bridge *tech_pvt;
537
538 tech_pvt = bridge->tech_pvt;
539 if (!tech_pvt) {
540 return;
541 }
542
543 tech_pvt->saw_start = 0;
544 native_request_stop(bridge);
545}
546
547/*!
548 * \internal
549 * \brief Add a channel to a bridging technology instance for a bridge.
550 * \since 12.0.0
551 *
552 * \retval 0 on success
553 * \retval -1 on failure
554 *
555 * \note On entry, bridge is already locked.
556 */
557static int native_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
558{
559 struct native_pvt_chan *tech_pvt;
560 struct ast_channel *c0;
561 struct ast_channel *c1;
562
564
565 tech_pvt = ast_calloc(1, sizeof(*tech_pvt));
566 if (!tech_pvt) {
567 return -1;
568 }
569
572
573 /*
574 * Make the channels compatible in case the native bridge did
575 * not start for some reason and we need to fallback to 1-1
576 * bridging.
577 */
578 c0 = AST_LIST_FIRST(&bridge->channels)->chan;
579 c1 = AST_LIST_LAST(&bridge->channels)->chan;
580 if (c0 == c1) {
581 return 0;
582 }
583 return ast_channel_make_compatible(c0, c1);
584}
585
586/*!
587 * \internal
588 * \brief Remove a channel from a bridging technology instance for a bridge.
589 * \since 12.0.0
590 *
591 * \note On entry, bridge is already locked.
592 */
594{
595 struct native_pvt_chan *tech_pvt;
596
597 native_request_stop(bridge);
598
599 tech_pvt = bridge_channel->tech_pvt;
600 bridge_channel->tech_pvt = NULL;
601 ast_free(tech_pvt);
602}
603
604/*!
605 * \internal
606 * \brief Suspend a channel on a bridging technology instance for a bridge.
607 * \since 12.0.0
608 *
609 * \note On entry, bridge is already locked.
610 */
611static void native_bridge_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
612{
613 native_request_stop(bridge);
614}
615
616/*!
617 * \internal
618 * \brief Unsuspend a channel on a bridging technology instance for a bridge.
619 * \since 12.0.0
620 *
621 * \note On entry, bridge is already locked.
622 */
623static void native_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
624{
625 native_request_start(bridge);
626}
627
628/*!
629 * \internal
630 * \brief Check if channel is compatible.
631 * \since 12.0.0
632 *
633 * \param bridge_channel Is this channel compatible.
634 *
635 * \retval TRUE if channel is compatible with native DAHDI bridge.
636 */
637static int native_bridge_is_capable(struct ast_bridge_channel *bridge_channel)
638{
639 struct ast_channel *chan = bridge_channel->chan;
640 struct dahdi_pvt *pvt;
641 int is_capable;
642
643 if (ao2_container_count(bridge_channel->features->dtmf_hooks)) {
644 ast_debug(2, "Channel '%s' has DTMF hooks.\n", ast_channel_name(chan));
645 return 0;
646 }
647
648 ast_channel_lock(chan);
649
650 if (dahdi_tech != ast_channel_tech(chan)) {
651 ast_debug(2, "Channel '%s' is not %s.\n",
653 ast_channel_unlock(chan);
654 return 0;
655 }
657 ast_debug(2, "Channel '%s' has an active monitor, audiohook, or framehook.\n",
658 ast_channel_name(chan));
659 ast_channel_unlock(chan);
660 return 0;
661 }
662 pvt = ast_channel_tech_pvt(chan);
663 if (!pvt || !pvt->sig) {
664 /* No private; or signaling is for a pseudo channel. */
665 ast_channel_unlock(chan);
666 return 0;
667 }
668
669 is_capable = 1;
670 ast_mutex_lock(&pvt->lock);
671
672 if (pvt->callwaiting && pvt->callwaitingcallerid) {
673 /*
674 * Call Waiting Caller ID requires DTMF detection to know if it
675 * can send the CID spill.
676 */
677 ast_debug(2, "Channel '%s' has call waiting caller ID enabled.\n",
678 ast_channel_name(chan));
679 is_capable = 0;
680 }
681
682 ast_mutex_unlock(&pvt->lock);
683 ast_channel_unlock(chan);
684
685 return is_capable;
686}
687
688/*!
689 * \internal
690 * \brief Check if a bridge is compatible with the bridging technology.
691 * \since 12.0.0
692 *
693 * \retval 0 if not compatible
694 * \retval non-zero if compatible
695 *
696 * \note On entry, bridge may or may not already be locked.
697 * However, it can be accessed as if it were locked.
698 */
699static int native_bridge_compatible(struct ast_bridge *bridge)
700{
701 struct ast_bridge_channel *cur;
702
703 /* We require two channels before even considering native bridging. */
704 if (bridge->num_channels != 2) {
705 ast_debug(1, "Bridge %s: Cannot use native DAHDI. Must have two channels.\n",
707 return 0;
708 }
709
711 if (!native_bridge_is_capable(cur)) {
712 ast_debug(1, "Bridge %s: Cannot use native DAHDI. Channel '%s' not compatible.\n",
714 return 0;
715 }
716 }
717
718 return -1;
719}
720
721/*!
722 * \internal
723 * \brief Check if something changed on the channel.
724 * \since 12.0.0
725 *
726 * \param bridge_channel What to operate upon.
727 *
728 * \retval 0 Nothing changed.
729 * \retval -1 Something changed.
730 *
731 * \note On entry, bridge_channel->bridge is already locked.
732 */
733static int native_chan_changed(struct ast_bridge_channel *bridge_channel)
734{
735 struct native_pvt_chan *tech_pvt;
736 struct ast_channel *chan;
737 struct dahdi_pvt *pvt;
738 int idx = -1;
739
740 ast_assert(bridge_channel->tech_pvt != NULL);
741
742 tech_pvt = bridge_channel->tech_pvt;
743
744 chan = bridge_channel->chan;
745 ast_channel_lock(chan);
746 pvt = ast_channel_tech_pvt(chan);
747 if (tech_pvt->pvt == pvt) {
748 idx = dahdi_get_index(chan, pvt, 1);
749 }
750 ast_channel_unlock(chan);
751
752 if (/* Did chan get masqueraded or PRI change associated B channel? */
753 tech_pvt->pvt != pvt
754 /* Did the pvt active owner change? */
755 || tech_pvt->owner != pvt->owner
756 /* Did the pvt three way call status change? */
757 || tech_pvt->inthreeway != pvt->subs[SUB_REAL].inthreeway
758 /* Did the owner index change? */
759 || tech_pvt->index != idx
760 /*
761 * Did chan file descriptor change? (This seems redundant with
762 * masquerade and active owner change checks.)
763 */
764 || tech_pvt->fd0 != ast_channel_fd(chan, 0)
765 /* Did chan state change? i.e. Did it stop ringing? */
766 || (pvt->subs[SUB_REAL].owner
767 && tech_pvt->state > -1
768 && tech_pvt->state != ast_channel_state(pvt->subs[SUB_REAL].owner))) {
769 return -1;
770 }
771
772 return 0;
773}
774
775/*!
776 * \internal
777 * \brief Check if something changed on the bridge channels.
778 * \since 12.0.0
779 *
780 * \param bridge What to operate upon.
781 *
782 * \retval 0 Nothing changed.
783 * \retval -1 Something changed.
784 *
785 * \note On entry, bridge is already locked.
786 */
787static int native_bridge_changed(struct ast_bridge *bridge)
788{
789 struct ast_bridge_channel *cur;
790
792 if (native_chan_changed(cur)) {
793 ast_debug(1, "Bridge %s: Something changed on channel '%s'.\n",
795 return -1;
796 }
797 }
798 return 0;
799}
800
801/*!
802 * \internal
803 * \brief Write a frame into the bridging technology instance for a bridge.
804 * \since 12.0.0
805 *
806 * \note The bridge must be tolerant of bridge_channel being NULL.
807 *
808 * \retval 0 Frame accepted into the bridge.
809 * \retval -1 Frame needs to be deferred.
810 *
811 * \note On entry, bridge is already locked.
812 */
813static int native_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
814{
815 struct native_pvt_bridge *tech_pvt;
816
817 /*
818 * When we are not native bridged by DAHDI, we are like a normal
819 * 1-1 bridge.
820 */
821
822 ast_assert(bridge->tech_pvt != NULL);
823
824 /* Recheck native bridging validity. */
825 tech_pvt = bridge->tech_pvt;
826 switch (frame->frametype) {
827 case AST_FRAME_VOICE:
828 case AST_FRAME_VIDEO:
829 if (!tech_pvt->connected) {
830 /* Don't try to start native mode on media frames. */
831 break;
832 }
833 if (native_bridge_changed(bridge)) {
834 native_request_stop(bridge);
835 native_request_start(bridge);
836 if (!tech_pvt->connected) {
837 break;
838 }
839 }
840
841 /*
842 * Native bridge handles voice frames in hardware. However, it
843 * also passes the frames up to Asterisk anyway. Discard the
844 * media frames.
845 */
846 return 0;
847 default:
848 if (!tech_pvt->connected) {
849 native_request_start(bridge);
850 break;
851 }
852 if (native_bridge_changed(bridge)) {
853 native_request_stop(bridge);
854 native_request_start(bridge);
855 }
856 break;
857 }
858
859 return ast_bridge_queue_everyone_else(bridge, bridge_channel, frame);
860}
861
863 .name = "native_dahdi",
864 .capabilities = AST_BRIDGE_CAPABILITY_NATIVE,
866 .create = native_bridge_create,
867 .start = native_bridge_start,
868 .stop = native_bridge_stop,
869 .destroy = native_bridge_destroy,
870 .join = native_bridge_join,
871 .leave = native_bridge_leave,
872 .suspend = native_bridge_suspend,
873 .unsuspend = native_bridge_unsuspend,
874 .compatible = native_bridge_compatible,
875 .write = native_bridge_write,
876};
877
878/*!
879 * \internal
880 * \brief Destroy the DAHDI native bridge support.
881 * \since 12.0.0
882 */
884{
886}
887
888/*!
889 * \internal
890 * \brief Initialize the DAHDI native bridge support.
891 * \since 12.0.0
892 *
893 * \retval 0 on success.
894 * \retval -1 on error.
895 */
896int dahdi_native_load(const struct ast_channel_tech *tech)
897{
898 dahdi_tech = tech;
899
902 return -1;
903 }
904
905 return 0;
906}
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
Bridging API.
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:90
int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Queue the given frame to everyone else.
static void native_stop(struct ast_bridge *bridge)
static const struct ast_channel_tech * dahdi_tech
static int native_chan_changed(struct ast_bridge_channel *bridge_channel)
static int native_start(struct ast_bridge *bridge)
void dahdi_native_unload(void)
static int native_bridge_changed(struct ast_bridge *bridge)
static void native_bridge_destroy(struct ast_bridge *bridge)
static void native_bridge_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
static void native_bridge_stop(struct ast_bridge *bridge)
static int native_bridge_is_capable(struct ast_bridge_channel *bridge_channel)
static void native_request_stop(struct ast_bridge *bridge)
static int native_bridge_compatible(struct ast_bridge *bridge)
static int native_bridge_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
static void native_bridge_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
static int native_bridge_create(struct ast_bridge *bridge)
static int native_bridge_write(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
static void native_request_start(struct ast_bridge *bridge)
static struct ast_bridge_technology native_bridge
static int native_bridge_start(struct ast_bridge *bridge)
static void native_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
int dahdi_native_load(const struct ast_channel_tech *tech)
Native DAHDI bridging support.
Channel Bridging API.
@ AST_BRIDGE_PREFERENCE_BASE_NATIVE
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
Definition: bridge.c:263
void dahdi_ec_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4877
void dahdi_conf_update(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4822
void dahdi_dtmf_detect_enable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:6756
void dahdi_ec_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:4949
void dahdi_master_slave_unlink(struct dahdi_pvt *slave, struct dahdi_pvt *master, int needlock)
Definition: chan_dahdi.c:7323
void dahdi_dtmf_detect_disable(struct dahdi_pvt *p)
Definition: chan_dahdi.c:6742
void dahdi_master_slave_link(struct dahdi_pvt *slave, struct dahdi_pvt *master)
Definition: chan_dahdi.c:7379
const char *const subnames[]
Definition: chan_dahdi.c:907
static int dahdi_sig_pri_lib_handles(int signaling)
Definition: chan_dahdi.h:825
#define SUB_REAL
Definition: chan_dahdi.h:57
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58
#define dahdi_get_index(ast, p, nullok)
Definition: chan_dahdi.h:882
static int call(void *data)
Definition: chan_pjsip.c:2391
const char * ast_channel_name(const struct ast_channel *chan)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
#define ast_channel_lock(chan)
Definition: channel.h:2922
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6719
#define ast_channel_trylock(chan)
Definition: channel.h:2924
int ast_channel_fd(const struct ast_channel *chan, int which)
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
int ast_channel_has_audio_frame_or_monitor(struct ast_channel *chan)
Check if the channel has active audiohooks, active framehooks, or a monitor.
Definition: channel.c:2518
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_RINGING
Definition: channelstate.h:41
Media Format Cache API.
Asterisk internal frame definitions.
@ AST_FRAME_VIDEO
@ AST_FRAME_VOICE
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
#define ast_mutex_unlock(a)
Definition: lock.h:190
#define ast_mutex_trylock(a)
Definition: lock.h:191
#define ast_mutex_lock(a)
Definition: lock.h:189
#define NULL
Definition: resample.c:96
Structure that contains information regarding a channel in a bridge.
void * tech_pvt
Private information unique to the bridge technology.
unsigned int suspended
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_features * features
struct ast_channel * chan
struct ao2_container * dtmf_hooks
Structure that is the essence of a bridge technology.
Structure that contains information about a bridge.
Definition: bridge.h:349
void * tech_pvt
Definition: bridge.h:357
const ast_string_field uniqueid
Definition: bridge.h:401
struct ast_bridge_channels_list channels
Definition: bridge.h:363
unsigned int num_channels
Definition: bridge.h:373
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition: channel.h:628
const char *const type
Definition: channel.h:629
Main Channel structure associated with a channel.
struct ast_bridge_channel * bridge_channel
struct ast_bridge * bridge
Data structure associated with a single frame of data.
enum ast_frame_type frametype
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:231
struct dahdi_subchannel subs[3]
Definition: chan_dahdi.h:131
unsigned int callwaiting
TRUE if busy extensions will hear the call-waiting tone and can use hook-flash to switch between call...
Definition: chan_dahdi.h:226
struct ast_channel * owner
Definition: chan_dahdi.h:127
void * sig_pvt
Definition: chan_dahdi.h:764
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
Definition: chan_dahdi.h:270
unsigned int transfer
TRUE if call transfer is enabled.
Definition: chan_dahdi.h:382
ast_mutex_t lock
Definition: chan_dahdi.h:125
int channel
Definition: chan_dahdi.h:585
int inconference
Definition: chan_dahdi.h:136
unsigned int inthreeway
Definition: chan_dahdi.h:91
struct ast_channel * owner
Definition: chan_dahdi.h:79
Definition: search.h:40
struct dahdi_pvt * master
struct dahdi_pvt * slave
unsigned int inthreeway
struct ast_channel * owner
struct dahdi_pvt * pvt
#define ast_assert(a)
Definition: utils.h:739