35 #include "../sig_analog.h"
37 #include "../sig_pri.h"
39 #include "../chan_dahdi.h"
75 #if defined(HAVE_PRI) && defined(PRI_2BCT)
83 unsigned int tried_trombone_removal:1;
98 static int native_bridge_create(
struct ast_bridge *bridge)
120 static void native_bridge_destroy(
struct ast_bridge *bridge)
138 static void native_stop(
struct ast_bridge *bridge)
143 ast_assert(bridge->
tech_pvt != NULL);
149 if (!chan_tech_pvt) {
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);
158 dahdi_dtmf_detect_enable(chan_tech_pvt->
pvt);
160 ast_mutex_unlock(&chan_tech_pvt->
pvt->
lock);
164 dahdi_master_slave_unlink(bridge_tech_pvt->
slave, bridge_tech_pvt->
master, 1);
166 ast_debug(2,
"Stop native bridging %s and %s\n",
180 static void native_request_stop(
struct ast_bridge *bridge)
184 ast_assert(bridge->
tech_pvt != NULL);
209 static int native_start(
struct ast_bridge *bridge)
225 ast_assert(bridge->
tech_pvt != NULL);
234 ast_channel_lock(c0);
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)) {
243 ast_mutex_unlock(&p0->
lock);
245 ast_channel_unlock(c1);
247 ast_channel_unlock(c0);
252 ast_assert(npc0 != NULL);
255 npc0->
index = dahdi_get_index(c0, p0, 0);
256 npc0->
fd0 = ast_channel_fd(c0, 0);
261 ast_assert(npc1 != NULL);
264 npc1->
index = dahdi_get_index(c1, p1, 0);
265 npc1->
fd0 = ast_channel_fd(c1, 0);
274 #
if defined(HAVE_PRI)
279 || (dahdi_sig_pri_lib_handles(p0->
sig)
281 || (dahdi_sig_pri_lib_handles(p1->
sig)
285 ast_mutex_unlock(&p0->
lock);
286 ast_mutex_unlock(&p1->
lock);
287 ast_channel_unlock(c0);
288 ast_channel_unlock(c1);
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",
352 ast_debug(3,
"master: %d, slave: %d, nothing_ok: %d\n",
356 if (master && slave) {
368 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
371 tone_zone_play_tone(p0->
subs[npc0->
index].dfd, DAHDI_TONE_RINGTONE);
374 ast_debug(2,
"Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
377 tone_zone_play_tone(p0->
subs[npc0->
index].dfd, -1);
386 "Playing ringback on %d/%d(%s) since %d/%d(%s) is in a ringing three-way\n",
389 tone_zone_play_tone(p1->
subs[npc1->
index].dfd, DAHDI_TONE_RINGTONE);
392 ast_debug(2,
"Stopping tones on %d/%d(%s) talking to %d/%d(%s)\n",
395 tone_zone_play_tone(p1->
subs[npc1->
index].dfd, -1);
401 dahdi_ec_disable(p0);
402 dahdi_ec_disable(p1);
405 dahdi_master_slave_link(slave, master);
407 }
else if (!nothing_ok) {
408 ast_log(LOG_WARNING,
"Can't link %d/%s with %d/%s\n",
412 dahdi_conf_update(p0);
413 dahdi_conf_update(p1);
415 ast_channel_unlock(c0);
416 ast_channel_unlock(c1);
419 if ((!master || !slave) && !nothing_ok) {
420 ast_mutex_unlock(&p0->
lock);
421 ast_mutex_unlock(&p1->
lock);
426 dahdi_dtmf_detect_disable(p0);
429 dahdi_dtmf_detect_disable(p1);
432 ast_mutex_unlock(&p0->
lock);
433 ast_mutex_unlock(&p1->
lock);
437 tech_pvt->
slave = slave;
439 ast_debug(2,
"Start native bridging %s and %s\n",
440 ast_channel_name(c0), ast_channel_name(c1));
442 #if defined(HAVE_PRI) && defined(PRI_2BCT)
443 if (!tech_pvt->tried_trombone_removal) {
444 tech_pvt->tried_trombone_removal = 1;
446 if (p0->pri && p0->pri == p1->pri && p0->pri->
transfer) {
451 ast_mutex_lock(&p0->pri->
lock);
452 ast_assert(dahdi_sig_pri_lib_handles(p0->
sig));
453 ast_assert(dahdi_sig_pri_lib_handles(p1->
sig));
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",
459 ast_channel_name(c0), ast_channel_name(c1));
461 ast_mutex_unlock(&p0->pri->
lock);
478 static void native_request_start(
struct ast_bridge *bridge)
483 ast_assert(bridge->
tech_pvt != NULL);
497 if (native_start(bridge)) {
514 static int native_bridge_start(
struct ast_bridge *bridge)
518 ast_assert(bridge->
tech_pvt != NULL);
523 native_request_start(bridge);
534 static void native_bridge_stop(
struct ast_bridge *bridge)
544 native_request_stop(bridge);
563 ast_assert(!bridge_channel->
tech_pvt);
571 native_request_start(bridge);
597 native_request_stop(bridge);
599 tech_pvt = bridge_channel->
tech_pvt;
613 native_request_stop(bridge);
625 native_request_start(bridge);
644 ast_debug(2,
"Channel '%s' has DTMF hooks.\n", ast_channel_name(chan));
648 ast_channel_lock(chan);
651 ast_debug(2,
"Channel '%s' is not %s.\n",
652 ast_channel_name(chan), dahdi_tech->type);
653 ast_channel_unlock(chan);
657 ast_debug(2,
"Channel '%s' has an active monitor, audiohook, or framehook.\n",
658 ast_channel_name(chan));
659 ast_channel_unlock(chan);
662 pvt = ast_channel_tech_pvt(chan);
663 if (!pvt || !pvt->
sig) {
665 ast_channel_unlock(chan);
670 ast_mutex_lock(&pvt->
lock);
677 ast_debug(2,
"Channel '%s' has call waiting caller ID enabled.\n",
678 ast_channel_name(chan));
682 ast_mutex_unlock(&pvt->
lock);
683 ast_channel_unlock(chan);
699 static int native_bridge_compatible(
struct ast_bridge *bridge)
705 ast_debug(1,
"Bridge %s: Cannot use native DAHDI. Must have two channels.\n",
711 if (!native_bridge_is_capable(cur)) {
712 ast_debug(1,
"Bridge %s: Cannot use native DAHDI. Channel '%s' not compatible.\n",
740 ast_assert(bridge_channel->
tech_pvt != NULL);
742 tech_pvt = bridge_channel->
tech_pvt;
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);
750 ast_channel_unlock(chan);
759 || tech_pvt->
index != idx
764 || tech_pvt->
fd0 != ast_channel_fd(chan, 0)
767 && tech_pvt->
state > -1
787 static int native_bridge_changed(
struct ast_bridge *bridge)
792 if (native_chan_changed(cur)) {
793 ast_debug(1,
"Bridge %s: Something changed on channel '%s'.\n",
822 ast_assert(bridge->
tech_pvt != NULL);
833 if (native_bridge_changed(bridge)) {
834 native_request_stop(bridge);
835 native_request_start(bridge);
849 native_request_start(bridge);
852 if (native_bridge_changed(bridge)) {
853 native_request_stop(bridge);
854 native_request_start(bridge);
863 .
name =
"native_dahdi",
865 .preference = AST_BRIDGE_PREFERENCE_BASE_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,
883 void dahdi_native_unload(
void)
901 dahdi_native_unload();
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
const ast_string_field uniqueid
unsigned int callwaiting
TRUE if busy extensions will hear the call-waiting tone and can use hook-flash to switch between call...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_bridge_features * features
struct dahdi_subchannel subs[3]
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
unsigned int transfer
TRUE if call transfer is enabled for the span.
struct dahdi_pvt * master
Native DAHDI bridging support.
struct ast_channel * owner
ast_channel_state
ast_channel states
struct ao2_container * dtmf_hooks
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.
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Asterisk internal frame definitions.
#define ast_debug(level,...)
Log a DEBUG message.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()
Structure that contains information about a bridge.
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
struct dahdi_pvt * master
#define ast_calloc(num, len)
A wrapper for calloc()
void * tech_pvt
Private information unique to the bridge technology.
struct ast_bridge_channels_list channels
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
Structure that is the essence of a bridge technology.
Data structure associated with a single frame of data.
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
enum ast_frame_type frametype
struct ast_channel * owner
int ast_channel_has_audio_frame_or_monitor(struct ast_channel *chan)
Check if the channel has active audiohooks, active framehooks, or a monitor.
unsigned int num_channels