Asterisk - The Open Source Telephony Project  21.4.1
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"
45 #include "asterisk/format_cache.h"
46 
47 /* ------------------------------------------------------------------- */
48 
49 static const struct ast_channel_tech *dahdi_tech;
50 
52  /*! Original private. */
53  struct dahdi_pvt *pvt;
54  /*! Original private owner. */
55  struct ast_channel *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. */
68  struct dahdi_pvt *master;
69  /*! Slave channel in the native bridge. */
70  struct dahdi_pvt *slave;
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  */
98 static 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  */
120 static 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  */
138 static void native_stop(struct ast_bridge *bridge)
139 {
140  struct native_pvt_bridge *bridge_tech_pvt;
141  struct ast_bridge_channel *cur;
142 
143  ast_assert(bridge->tech_pvt != NULL);
144 
145  AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
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",
167  ast_channel_name(AST_LIST_FIRST(&bridge->channels)->chan),
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  */
180 static 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  */
209 static 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 (;;) {
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)) {
240  /* Got all locks */
241  break;
242  }
243  ast_mutex_unlock(&p0->lock);
244  }
245  ast_channel_unlock(c1);
246  }
247  ast_channel_unlock(c0);
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  */
279  || (dahdi_sig_pri_lib_handles(p0->sig)
280  && ((struct sig_pri_chan *) p0->sig_pvt)->no_b_channel)
281  || (dahdi_sig_pri_lib_handles(p1->sig)
282  && ((struct sig_pri_chan *) p1->sig_pvt)->no_b_channel)
283 #endif /* defined(HAVE_PRI) */
284  ) {
285  ast_mutex_unlock(&p0->lock);
286  ast_mutex_unlock(&p1->lock);
287  ast_channel_unlock(c0);
288  ast_channel_unlock(c1);
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,
315  p0->subs[SUB_REAL].inthreeway,
316  p0->channel,
317  npc0->index, (p1->subs[SUB_CALLWAIT].dfd > -1) ? 1 : 0,
318  p1->subs[SUB_REAL].inthreeway);
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
363  && p1->subs[SUB_THREEWAY].inthreeway
364  && p1->subs[SUB_REAL].owner
365  && p1->subs[SUB_REAL].inthreeway
366  && ast_channel_state(p1->subs[SUB_REAL].owner) == AST_STATE_RINGING) {
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);
372  npc1->state = ast_channel_state(p1->subs[SUB_REAL].owner);
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
381  && p0->subs[SUB_THREEWAY].inthreeway
382  && p0->subs[SUB_REAL].owner
383  && p0->subs[SUB_REAL].inthreeway
384  && ast_channel_state(p0->subs[SUB_REAL].owner) == AST_STATE_RINGING) {
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);
390  npc0->state = ast_channel_state(p0->subs[SUB_REAL].owner);
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 */
401  dahdi_ec_disable(p0);
402  dahdi_ec_disable(p1);
403  }
404  }
405  dahdi_master_slave_link(slave, master);
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  }
412  dahdi_conf_update(p0);
413  dahdi_conf_update(p1);
414 
415  ast_channel_unlock(c0);
416  ast_channel_unlock(c1);
417 
418  /* Native bridge failed */
419  if ((!master || !slave) && !nothing_ok) {
420  ast_mutex_unlock(&p0->lock);
421  ast_mutex_unlock(&p1->lock);
422  return -1;
423  }
424 
425  if (npc0->index == SUB_REAL) {
426  dahdi_dtmf_detect_disable(p0);
427  }
428  if (npc1->index == SUB_REAL) {
429  dahdi_dtmf_detect_disable(p1);
430  }
431 
432  ast_mutex_unlock(&p0->lock);
433  ast_mutex_unlock(&p1->lock);
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",
440  ast_channel_name(c0), ast_channel_name(c1));
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);
452  ast_assert(dahdi_sig_pri_lib_handles(p0->sig));
453  ast_assert(dahdi_sig_pri_lib_handles(p1->sig));
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",
459  ast_channel_name(c0), ast_channel_name(c1));
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  */
478 static void native_request_start(struct ast_bridge *bridge)
479 {
480  struct native_pvt_bridge *tech_pvt;
481  struct ast_bridge_channel *cur;
482 
483  ast_assert(bridge->tech_pvt != NULL);
484 
485  tech_pvt = bridge->tech_pvt;
486 
487  if (bridge->num_channels != 2 || !tech_pvt->saw_start || tech_pvt->connected) {
488  return;
489  }
490  AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
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  */
514 static int native_bridge_start(struct ast_bridge *bridge)
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  */
534 static 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  */
557 static 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 
563  ast_assert(!bridge_channel->tech_pvt);
564 
565  tech_pvt = ast_calloc(1, sizeof(*tech_pvt));
566  if (!tech_pvt) {
567  return -1;
568  }
569 
570  bridge_channel->tech_pvt = tech_pvt;
571  native_request_start(bridge);
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  */
593 static void native_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
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  */
611 static 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  */
623 static 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  */
637 static 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",
652  ast_channel_name(chan), dahdi_tech->type);
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  */
699 static 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",
706  bridge->uniqueid);
707  return 0;
708  }
709 
710  AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
711  if (!native_bridge_is_capable(cur)) {
712  ast_debug(1, "Bridge %s: Cannot use native DAHDI. Channel '%s' not compatible.\n",
713  bridge->uniqueid, ast_channel_name(cur->chan));
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  */
733 static 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  */
787 static int native_bridge_changed(struct ast_bridge *bridge)
788 {
789  struct ast_bridge_channel *cur;
790 
791  AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
792  if (native_chan_changed(cur)) {
793  ast_debug(1, "Bridge %s: Something changed on channel '%s'.\n",
794  bridge->uniqueid, ast_channel_name(cur->chan));
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  */
813 static 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 
862 static struct ast_bridge_technology native_bridge = {
863  .name = "native_dahdi",
864  .capabilities = AST_BRIDGE_CAPABILITY_NATIVE,
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,
876 };
877 
878 /*!
879  * \internal
880  * \brief Destroy the DAHDI native bridge support.
881  * \since 12.0.0
882  */
883 void dahdi_native_unload(void)
884 {
885  ast_bridge_technology_unregister(&native_bridge);
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  */
896 int dahdi_native_load(const struct ast_channel_tech *tech)
897 {
898  dahdi_tech = tech;
899 
900  if (ast_bridge_technology_register(&native_bridge)) {
901  dahdi_native_unload();
902  return -1;
903  }
904 
905  return 0;
906 }
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.
Definition: linkedlists.h:421
const ast_string_field uniqueid
Definition: bridge.h:401
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
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]
Definition: chan_dahdi.h:131
unsigned int callwaitingcallerid
TRUE if send caller ID for Call Waiting.
Definition: chan_dahdi.h:231
unsigned int transfer
TRUE if call transfer is enabled for the span.
Definition: sig_pri.h:478
#define SUB_THREEWAY
Definition: chan_dahdi.h:59
struct dahdi_pvt * master
Definition: chan_dahdi.h:135
q931_call * call
Definition: sig_pri.h:356
Native DAHDI bridging support.
struct ast_channel * owner
Definition: chan_dahdi.h:127
unsigned int suspended
ast_channel_state
ast_channel states
Definition: channelstate.h:35
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 inconference
Definition: chan_dahdi.h:136
ast_mutex_t lock
Definition: sig_pri.h:616
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
Make the frame formats of two channels compatible.
Definition: channel.c:6720
Channel Bridging API.
Asterisk internal frame definitions.
ast_mutex_t lock
Definition: chan_dahdi.h:125
#define ast_debug(level,...)
Log a DEBUG message.
unsigned int inthreeway
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()
Structure that contains information about a bridge.
Definition: bridge.h:349
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
Definition: bridge.c:263
#define SUB_REAL
Definition: chan_dahdi.h:57
#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
struct dahdi_pvt * master
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void * tech_pvt
Private information unique to the bridge technology.
struct ast_bridge_channels_list channels
Definition: bridge.h:363
struct ast_channel * chan
struct dahdi_pvt * slave
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.
void * tech_pvt
Definition: bridge.h:357
Definition: search.h:40
struct dahdi_pvt * pvt
unsigned int echocanbridged
TRUE if echo cancellation enabled when bridged.
Definition: chan_dahdi.h:270
enum ast_frame_type frametype
struct ast_channel * owner
Bridging API.
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
int channel
Definition: chan_dahdi.h:585
unsigned int num_channels
Definition: bridge.h:373
Media Format Cache API.
#define SUB_CALLWAIT
Definition: chan_dahdi.h:58