38 #include "asterisk/alertpipe.h"
50 #include "asterisk/stasis_bridges.h"
51 #include "asterisk/stasis_channels.h"
53 #include "asterisk/features_config.h"
127 memset(sync_struct, 0,
sizeof(*sync_struct));
128 sync_struct->id =
id;
132 AST_RWLIST_INSERT_TAIL(&sync_structs, sync_struct, list);
154 if (iter->
id == sync_struct->
id) {
179 #define PLAYBACK_TIMEOUT (600 * 1000)
189 struct timespec timeout_spec = {
190 .tv_sec = timeout_val.tv_sec,
191 .tv_nsec = timeout_val.tv_usec * 1000,
216 ao2_lock(bridge_channel);
218 ao2_unlock(bridge_channel);
230 bridge = bridge_channel->
bridge;
236 if (bridge == bridge_channel->
bridge) {
249 .subclass.integer = started_talking
262 if (!pthread_equal(pthread_self(), bridge_channel->
thread)) {
279 static int channel_set_cause(
struct ast_channel *chan,
int cause)
281 ast_channel_lock(chan);
283 cause = ast_channel_hangupcause(chan);
285 cause = AST_CAUSE_NORMAL_CLEARING;
288 ast_channel_hangupcause_set(chan, cause);
289 ast_channel_unlock(chan);
299 ast_debug(1,
"Setting %p(%s) state from:%u to:%u\n",
300 bridge_channel, ast_channel_name(bridge_channel->
chan), bridge_channel->
state,
303 channel_set_cause(bridge_channel->
chan, cause);
305 ast_channel_lock(bridge_channel->
chan);
307 ast_channel_unlock(bridge_channel->
chan);
310 bridge_channel->
state = new_state;
312 bridge_channel_poke(bridge_channel);
329 if (other != bridge_channel) {
343 ast_channel_lock(bridge_channel->
chan);
347 ast_debug(1,
"Bridge is returning %p(%s) to read format %s\n",
348 bridge_channel, ast_channel_name(bridge_channel->
chan),
351 ast_debug(1,
"Bridge failed to return %p(%s) to read format %s\n",
352 bridge_channel, ast_channel_name(bridge_channel->
chan),
357 ast_debug(1,
"Bridge is returning %p(%s) to write format %s\n",
358 bridge_channel, ast_channel_name(bridge_channel->
chan),
361 ast_debug(1,
"Bridge failed to return %p(%s) to write format %s\n",
362 bridge_channel, ast_channel_name(bridge_channel->
chan),
367 ast_channel_unlock(bridge_channel->
chan);
375 bridge = bridge_channel->
bridge;
377 bridge_merge_inhibit_nolock(bridge, request);
393 oldest_linkedid_chan, other->
chan);
396 ast_channel_lock(bridge_channel->
chan);
398 ast_channel_unlock(bridge_channel->
chan);
403 ast_channel_lock(other->
chan);
405 ast_channel_unlock(other->
chan);
421 if (ast_strlen_zero(ast_channel_peeraccount(dest))
422 && !ast_strlen_zero(ast_channel_accountcode(src))) {
423 ast_debug(1,
"Setting channel %s peeraccount with channel %s accountcode '%s'.\n",
424 ast_channel_name(dest),
425 ast_channel_name(src), ast_channel_accountcode(src));
426 ast_channel_peeraccount_set(dest, ast_channel_accountcode(src));
442 if (ast_strlen_zero(ast_channel_accountcode(dest))
443 && !ast_strlen_zero(ast_channel_peeraccount(src))) {
444 ast_debug(1,
"Setting channel %s accountcode with channel %s peeraccount '%s'.\n",
445 ast_channel_name(dest),
446 ast_channel_name(src), ast_channel_peeraccount(src));
447 ast_channel_accountcode_set(dest, ast_channel_peeraccount(src));
464 channel_fill_empty_peeraccount(c0, c1);
465 channel_fill_empty_peeraccount(c1, c0);
468 channel_fill_empty_accountcode(c0, c1);
469 channel_fill_empty_accountcode(c1, c0);
484 if (strcmp(ast_channel_accountcode(src), ast_channel_peeraccount(dest))) {
485 ast_debug(1,
"Changing channel %s peeraccount '%s' to match channel %s accountcode '%s'.\n",
486 ast_channel_name(dest), ast_channel_peeraccount(dest),
487 ast_channel_name(src), ast_channel_accountcode(src));
488 ast_channel_peeraccount_set(dest, ast_channel_accountcode(src));
504 channel_update_peeraccount(c0, c1);
505 channel_update_peeraccount(c1, c0);
522 unsigned int swap_in_bridge = 0;
523 unsigned int will_be_two_party;
537 will_be_two_party = (1 == bridge->
num_channels - swap_in_bridge);
543 ast_assert(joining != other);
545 channel_set_empty_accountcodes(joining->
chan, other->
chan);
546 if (will_be_two_party) {
547 channel_update_peeraccounts(joining->
chan, other->
chan);
549 ast_channel_unlock(joining->
chan);
550 ast_channel_unlock(other->
chan);
563 static void bridge_channel_update_accountcodes_leaving(
struct ast_bridge_channel *leaving)
575 ast_assert(first && first != second);
577 channel_set_empty_accountcodes(first->
chan, second->
chan);
578 channel_update_peeraccounts(first->
chan, second->
chan);
579 ast_channel_unlock(second->
chan);
580 ast_channel_unlock(first->
chan);
586 bridge_channel_update_accountcodes_joining(joining, leaving);
588 bridge_channel_update_accountcodes_leaving(leaving);
600 channel_set_cause(bridge_channel->
chan, cause);
607 for (; (hook = ao2_iterator_next(&iter));
ao2_ref(hook, -1)) {
610 if (hook->
type != AST_BRIDGE_HOOK_TYPE_HANGUP) {
615 ast_debug(1,
"Hangup hook %p is being removed from %p(%s)\n",
616 hook, bridge_channel, ast_channel_name(bridge_channel->
chan));
640 int unmapped_stream_num;
693 unmapped_stream_num = -1;
731 t38_parameters = frame->
data.ptr;
771 static void bridge_channel_cancel_owed_events(
struct ast_bridge_channel *bridge_channel)
783 .src =
"Bridge channel owed DTMF",
790 ast_log(LOG_DTMF,
"DTMF end '%c' simulated to bridge %s because %s left. Duration %ld ms.\n",
792 ast_channel_name(bridge_channel->
chan), frame.
len);
803 .data.ptr = &t38_parameters,
804 .datalen =
sizeof(t38_parameters),
805 .src =
"Bridge channel owed T.38 terminate",
808 ast_debug(1,
"T.38 terminate simulated to bridge %s because %s left.\n",
809 orig_bridge->
uniqueid, ast_channel_name(bridge_channel->
chan));
820 ast_channel_lock(bridge_channel->
chan);
825 ast_channel_unlock(bridge_channel->
chan);
829 void bridge_channel_internal_suspend_nolock(
struct ast_bridge_channel *bridge_channel)
851 bridge_channel_internal_suspend_nolock(bridge_channel);
855 void bridge_channel_internal_unsuspend_nolock(
struct ast_bridge_channel *bridge_channel)
869 ast_cond_signal(&bridge_channel->
cond);
882 bridge_channel_internal_unsuspend_nolock(bridge_channel);
899 static int bridge_channel_queue_action_data(
struct ast_bridge_channel *bridge_channel,
904 .subclass.integer = action,
906 .data.ptr = (
void *) data,
927 static int bridge_channel_queue_action_data_sync(
struct ast_bridge_channel *bridge_channel,
931 int sync_payload_len =
sizeof(*sync_payload) + datalen;
935 .subclass.integer = action,
939 ast_assert(!pthread_equal(pthread_self(), bridge_channel->
thread));
943 memcpy(sync_payload->
data, data, datalen);
945 frame.
datalen = sync_payload_len;
946 frame.
data.ptr = sync_payload;
971 static int bridge_channel_write_action_data(
struct ast_bridge_channel *bridge_channel,
976 .subclass.integer = action,
978 .data.ptr = (
void *) data,
981 return bridge_channel_write_frame(bridge_channel, &frame);
984 static void bridge_frame_free(
struct ast_frame *frame)
987 struct sync_payload *sync_payload = frame->
data.ptr;
992 if (sync->
id == sync_payload->
id) {
1048 bridge_frame_free(dup);
1056 bridge_frame_free(dup);
1060 if (DEBUG_ATLEAST(1)) {
1062 ast_log(LOG_DEBUG,
"Queuing TEXT frame to '%s': %*.s\n", ast_channel_name(bridge_channel->
chan),
1066 ast_log(LOG_DEBUG,
"Queueing TEXT_DATA frame from '%s' to '%s:%s': %s\n",
1069 ast_channel_name(bridge_channel->
chan),
1076 ast_log(LOG_ERROR,
"We couldn't write alert pipe for %p(%s)... something is VERY wrong\n",
1077 bridge_channel, ast_channel_name(bridge_channel->
chan));
1086 int not_written = -1;
1094 if (cur == bridge_channel) {
1108 .subclass.integer = control,
1110 .data.ptr = (
void *) data,
1120 .subclass.integer = control,
1122 .data.ptr = (
void *) data,
1125 return bridge_channel_write_frame(bridge_channel, &frame);
1134 if (!ast_strlen_zero(moh_class)) {
1135 datalen = strlen(moh_class) + 1;
1138 "musicclass", moh_class);
1148 moh_class, datalen);
1172 static int run_app_helper(
struct ast_channel *chan,
const char *
app_name,
const char *app_args)
1176 if (!strcasecmp(
"Gosub", app_name)) {
1189 if (run_app_helper(bridge_channel->
chan, app_name,
S_OR(app_args,
""))) {
1227 struct ast_bridge_channel *bridge_channel,
const char *app_name,
const char *app_args,
const char *moh_class)
1230 size_t len_name = strlen(app_name) + 1;
1231 size_t len_args = ast_strlen_zero(app_args) ? 0 : strlen(app_args) + 1;
1232 size_t len_moh = !moh_class ? 0 : strlen(moh_class) + 1;
1233 size_t len_data =
sizeof(*app_data) + len_name + len_args + len_moh;
1236 app_data = alloca(len_data);
1238 app_data->
moh_offset = len_moh ? len_name + len_args : 0;
1239 strcpy(app_data->
app_name, app_name);
1252 return payload_helper_app(bridge_channel_write_action_data,
1253 bridge_channel, app_name, app_args, moh_class);
1258 return payload_helper_app(bridge_channel_queue_action_data,
1259 bridge_channel, app_name, app_args, moh_class);
1268 custom_play(bridge_channel, playfile);
1280 if (ast_test_flag(ast_channel_flags(bridge_channel->
chan),
AST_FLAG_MOH)) {
1281 const char *latest_musicclass;
1283 ast_channel_lock(bridge_channel->
chan);
1284 latest_musicclass =
ast_strdupa(ast_channel_latest_musicclass(bridge_channel->
chan));
1285 ast_channel_unlock(bridge_channel->
chan);
1321 size_t len_name = strlen(playfile) + 1;
1322 size_t len_moh = !moh_class ? 0 : strlen(moh_class) + 1;
1323 size_t len_payload =
sizeof(*payload) + len_name + len_moh;
1328 payload->
moh_offset = len_moh ? len_name : 0;
1329 strcpy(payload->
playfile, playfile);
1339 return payload_helper_playfile(bridge_channel_write_action_data,
1340 bridge_channel, custom_play, playfile, moh_class);
1345 return payload_helper_playfile(bridge_channel_queue_action_data,
1346 bridge_channel, custom_play, playfile, moh_class);
1352 return payload_helper_playfile(bridge_channel_queue_action_data_sync,
1353 bridge_channel, custom_play, playfile, moh_class);
1380 bridge_channel_suspend(bridge_channel);
1386 bridge_channel_unsuspend(bridge_channel);
1400 size_t len_data =
sizeof(*cb_data) + (payload ? payload_size : 0);
1409 cb_data = alloca(len_data);
1415 memcpy(cb_data->
payload, payload, payload_size);
1425 return payload_helper_cb(bridge_channel_write_action_data,
1426 bridge_channel, flags, callback, payload, payload_size);
1433 return payload_helper_cb(bridge_channel_queue_action_data,
1434 bridge_channel, flags, callback, payload, payload_size);
1438 int parker_uuid_offset;
1439 int app_data_offset;
1441 char parkee_uuid[0];
1451 ast_log(AST_LOG_WARNING,
"Unable to park %s: No parking provider loaded!\n",
1452 ast_channel_name(bridge_channel->
chan));
1457 &payload->parkee_uuid[payload->parker_uuid_offset],
1458 payload->app_data_offset ? &payload->parkee_uuid[payload->app_data_offset] : NULL)) {
1459 ast_log(AST_LOG_WARNING,
"Error occurred while parking %s\n",
1460 ast_channel_name(bridge_channel->
chan));
1470 const char *parkee_uuid,
1471 const char *parker_uuid,
1472 const char *app_data)
1475 size_t len_parkee_uuid = strlen(parkee_uuid) + 1;
1476 size_t len_parker_uuid = strlen(parker_uuid) + 1;
1477 size_t len_app_data = !app_data ? 0 : strlen(app_data) + 1;
1478 size_t len_payload =
sizeof(*payload) + len_parker_uuid + len_parkee_uuid + len_app_data;
1480 payload = alloca(len_payload);
1481 payload->app_data_offset = len_app_data ? len_parkee_uuid + len_parker_uuid : 0;
1482 payload->parker_uuid_offset = len_parkee_uuid;
1483 strcpy(payload->parkee_uuid, parkee_uuid);
1484 strcpy(&payload->parkee_uuid[payload->parker_uuid_offset], parker_uuid);
1486 strcpy(&payload->parkee_uuid[payload->app_data_offset], app_data);
1494 return payload_helper_park(bridge_channel_write_action_data,
1495 bridge_channel, parkee_uuid, parker_uuid, app_data);
1505 static void bridge_channel_handle_interval(
struct ast_bridge_channel *bridge_channel)
1509 struct timeval start;
1510 int chan_suspended = 0;
1513 ast_heap_wrlock(interval_hooks);
1517 unsigned int execution_time;
1520 ast_debug(1,
"Hook %p on %p(%s) wants to happen in the future, stopping our traversal\n",
1521 hook, bridge_channel, ast_channel_name(bridge_channel->
chan));
1525 ast_heap_unlock(interval_hooks);
1530 bridge_channel_suspend(bridge_channel);
1534 ast_debug(1,
"Executing hook %p on %p(%s)\n",
1535 hook, bridge_channel, ast_channel_name(bridge_channel->
chan));
1538 ast_heap_wrlock(interval_hooks);
1548 ast_debug(1,
"Removed interval hook %p from %p(%s)\n",
1549 hook, bridge_channel, ast_channel_name(bridge_channel->
chan));
1558 ast_debug(1,
"Updating interval hook %p with interval %u on %p(%s)\n",
1560 ast_channel_name(bridge_channel->
chan));
1582 ast_heap_unlock(interval_hooks);
1584 if (chan_suspended) {
1586 bridge_channel_unsuspend(bridge_channel);
1594 static int bridge_channel_write_dtmf_stream(
struct ast_bridge_channel *bridge_channel,
const char *dtmf)
1596 return bridge_channel_write_action_data(bridge_channel,
1610 static void testsuite_notify_feature_success(
struct ast_channel *chan,
const char *dtmf)
1612 #ifdef TEST_FRAMEWORK
1613 char *feature =
"unknown";
1617 ast_channel_lock(chan);
1618 featuremap = ast_get_chan_featuremap_config(chan);
1619 xfer = ast_get_chan_features_xfer_config(chan);
1620 ast_channel_unlock(chan);
1623 if (!strcmp(dtmf, featuremap->
blindxfer)) {
1624 feature =
"blindxfer";
1625 }
else if (!strcmp(dtmf, featuremap->
atxfer)) {
1627 }
else if (!strcmp(dtmf, featuremap->
disconnect)) {
1628 feature =
"disconnect";
1629 }
else if (!strcmp(dtmf, featuremap->
automixmon)) {
1630 feature =
"automixmon";
1631 }
else if (!strcmp(dtmf, featuremap->
parkcall)) {
1632 feature =
"parkcall";
1637 feature =
"atxferthreeway";
1641 ao2_cleanup(featuremap);
1645 "Result: success\r\n"
1646 "Feature: %s", feature);
1650 static int bridge_channel_feature_digit_add(
1658 ast_debug(1,
"DTMF feature string on %p(%s) is now '%s'\n",
1659 bridge_channel, ast_channel_name(bridge_channel->
chan),
1666 static unsigned int bridge_channel_feature_digit_timeout(
struct ast_bridge_channel *bridge_channel)
1668 unsigned int digit_timeout;
1672 ast_channel_lock(bridge_channel->
chan);
1673 gen_cfg = ast_get_chan_features_general_config(bridge_channel->
chan);
1674 ast_channel_unlock(bridge_channel->
chan);
1677 ast_log(LOG_ERROR,
"Unable to retrieve features configuration.\n");
1684 return digit_timeout;
1690 bridge_channel_feature_digit_add(
1701 struct sanity_check_of_dtmf_size {
1706 if (!dtmf_len && !digit) {
1712 dtmf_len = bridge_channel_feature_digit_add(bridge_channel, digit, dtmf_len);
1720 ast_debug(1,
"No DTMF feature hooks on %p(%s) match '%s'\n",
1721 bridge_channel, ast_channel_name(bridge_channel->
chan),
1724 }
else if (dtmf_len != strlen(hook->
dtmf.
code)) {
1725 unsigned int digit_timeout;
1728 digit_timeout = bridge_channel_feature_digit_timeout(bridge_channel);
1734 int already_suspended;
1736 ast_debug(1,
"DTMF feature hook %p matched DTMF string '%s' on %p(%s)\n",
1738 ast_channel_name(bridge_channel->
chan));
1747 already_suspended = bridge_channel->
suspended;
1748 if (!already_suspended) {
1749 bridge_channel_internal_suspend_nolock(bridge_channel);
1757 ast_debug(1,
"DTMF hook %p is being removed from %p(%s)\n",
1758 hook, bridge_channel, ast_channel_name(bridge_channel->
chan));
1761 testsuite_notify_feature_success(bridge_channel->
chan, hook->
dtmf.
code);
1765 if (!already_suspended) {
1766 bridge_channel_unsuspend(bridge_channel);
1775 if (bridge_channel->
chan && ast_check_hangup_locked(bridge_channel->
chan)) {
1792 ast_debug(1,
"DTMF feature string collection on %p(%s) timed out\n",
1793 bridge_channel, ast_channel_name(bridge_channel->
chan));
1799 bridge_channel_write_dtmf_stream(bridge_channel,
1814 static void bridge_channel_handle_feature_timeout(
struct ast_bridge_channel *bridge_channel)
1830 static void bridge_channel_talking(
struct ast_bridge_channel *bridge_channel,
int talking)
1838 for (; (hook = ao2_iterator_next(&iter));
ao2_ref(hook, -1)) {
1842 if (hook->
type != AST_BRIDGE_HOOK_TYPE_TALK) {
1846 remove_me = talk_cb(bridge_channel, hook->
hook_pvt, talking);
1848 ast_debug(1,
"Talk detection hook %p is being removed from %p(%s)\n",
1849 hook, bridge_channel, ast_channel_name(bridge_channel->
chan));
1860 static void bridge_channel_dtmf_stream(
struct ast_bridge_channel *bridge_channel,
const char *dtmf)
1862 ast_debug(1,
"Playing DTMF stream '%s' out to %p(%s)\n",
1863 dtmf, bridge_channel, ast_channel_name(bridge_channel->
chan));
1877 static void after_bridge_move_channel(
struct ast_channel *chan_bridged,
void *data)
1881 unsigned char connected_line_data[1024];
1886 ast_channel_lock(chan_target);
1888 ast_channel_unlock(chan_target);
1903 ast_channel_lock(chan_target);
1906 ast_channel_unlock(chan_target);
1909 sizeof(connected_line_data), &connected_target, NULL)) != -1) {
1913 frame_size = payload_size +
sizeof(*frame_payload);
1915 frame_payload->action = AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO;
1916 frame_payload->payload_size = payload_size;
1917 memcpy(frame_payload->payload, connected_line_data, payload_size);
1925 ast_channel_lock(chan_target);
1928 ast_channel_unlock(chan_target);
1941 ast_log(LOG_WARNING,
"Unable to complete transfer: %s\n",
1961 static void bridge_channel_attended_transfer(
struct ast_bridge_channel *bridge_channel,
1962 const char *target_chan_name)
1975 chan_bridged = bridge_channel->
chan;
1976 ast_assert(chan_bridged != NULL);
2004 bridge_channel_suspend(bridge_channel);
2006 bridge_channel_dtmf_stream(bridge_channel, data);
2008 bridge_channel_unsuspend(bridge_channel);
2012 bridge_channel_talking(bridge_channel,
2016 bridge_channel_suspend(bridge_channel);
2018 bridge_channel_playfile(bridge_channel, data);
2020 bridge_channel_unsuspend(bridge_channel);
2023 bridge_channel_suspend(bridge_channel);
2025 bridge_channel_run_app(bridge_channel, data);
2027 bridge_channel_unsuspend(bridge_channel);
2030 bridge_channel_do_callback(bridge_channel, data);
2033 bridge_channel_suspend(bridge_channel);
2035 bridge_channel_park(bridge_channel, data);
2037 bridge_channel_unsuspend(bridge_channel);
2040 bridge_channel_blind_transfer(bridge_channel, data);
2043 bridge_channel_attended_transfer(bridge_channel, data);
2052 if (bridge_channel->
chan && ast_check_hangup_locked(bridge_channel->
chan)) {
2077 bridge_dissolve(bridge, ast_channel_hangupcause(bridge_channel->
chan));
2081 switch (bridge_channel->
state) {
2088 bridge_dissolve(bridge, ast_channel_hangupcause(bridge_channel->
chan));
2104 ast_channel_hangupcause(bridge_channel->
chan));
2117 ast_debug(1,
"Bridge %s: pulling %p(%s)\n",
2118 bridge->
uniqueid, bridge_channel, ast_channel_name(bridge_channel->
chan));
2120 ast_verb(3,
"Channel %s left '%s' %s-bridge <%s>\n",
2121 ast_channel_name(bridge_channel->
chan),
2128 ast_debug(1,
"Bridge %s: %p(%s) is leaving %s technology\n",
2129 bridge->
uniqueid, bridge_channel, ast_channel_name(bridge_channel->
chan),
2146 bridge_channel_dissolve_check(bridge_channel);
2157 ast_debug(2,
"Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->
chan));
2165 int bridge_channel_internal_push_full(
struct ast_bridge_channel *bridge_channel,
int optimized)
2172 swap = bridge_find_channel(bridge, bridge_channel->
swap);
2173 bridge_channel->
swap = NULL;
2176 ast_debug(1,
"Bridge %s: pushing %p(%s) by swapping with %p(%s)\n",
2177 bridge->
uniqueid, bridge_channel, ast_channel_name(bridge_channel->
chan),
2178 swap, ast_channel_name(swap->
chan));
2180 ast_debug(1,
"Bridge %s: pushing %p(%s)\n",
2181 bridge->
uniqueid, bridge_channel, ast_channel_name(bridge_channel->
chan));
2188 || bridge->
v_table->
push(bridge, bridge_channel, swap)) {
2189 ast_debug(1,
"Bridge %s: pushing %p(%s) into bridge failed\n",
2190 bridge->
uniqueid, bridge_channel, ast_channel_name(bridge_channel->
chan));
2203 bridge_channel_cancel_owed_events(swap);
2206 bridge_channel_internal_pull(swap);
2222 ast_verb(3,
"Channel %s %s%s%s '%s' %s-bridge <%s>\n",
2223 ast_channel_name(bridge_channel->
chan),
2224 swap ?
"swapped with " :
"joined",
2225 swap ? ast_channel_name(swap->
chan) :
"",
2226 swap ?
" into" :
"",
2247 return bridge_channel_internal_push_full(bridge_channel, 0);
2263 chan = bridge_channel->
chan;
2283 if (aoh && aoh->flag == AST_OPTION_FLAG_REQUEST) {
2284 switch (ntohs(aoh->option)) {
2292 fr->
datalen -
sizeof(*aoh), 0);
2304 bridge_reconfigured(bridge_channel->
bridge, 0);
2333 char *text = f->
data.ptr;
2345 if (text != f->
data.ptr) {
2366 struct sync_payload *sync_payload;
2376 ast_log(LOG_WARNING,
"Weird. No frame from bridge for %s to process?\n",
2377 ast_channel_name(bridge_channel->
chan));
2417 sync_payload = fr->
data.ptr;
2421 bridge_channel_handle_control(bridge_channel, fr);
2426 ast_debug(1,
"Sending TEXT frame to '%s': %*.s\n",
2427 ast_channel_name(bridge_channel->
chan), fr->
datalen, (
char *)fr->
data.ptr);
2428 sendtext_safe(bridge_channel->
chan, fr);
2432 ast_debug(1,
"Sending TEXT_DATA frame from '%s' to '%s:%s': %s\n",
2435 ast_channel_name(bridge_channel->
chan),
2463 bridge_frame_free(fr);
2486 bridge_frame_free(frame);
2491 switch (frametype) {
2503 #ifdef TEST_FRAMEWORK
2515 static const char *controls[] = {
2535 if (!ast_strlen_zero(ast_channel_call_forward(bridge_channel->
chan))) {
2543 ast_channel_call_forward(bridge_channel->
chan));
2571 bridge_frame_free(frame);
2583 bridge_channel->
bridge, bridge_channel);
2590 bridge_frame_free(frame);
2602 bridge_channel->
bridge, bridge_channel);
2614 frame = bridge_handle_dtmf(bridge_channel, frame);
2619 bridge_frame_free(frame);
2628 bridge_channel_write_frame(bridge_channel, frame);
2629 bridge_frame_free(frame);
2648 ast_heap_wrlock(interval_hooks);
2660 ast_heap_unlock(interval_hooks);
2709 ms_interval = bridge_channel_next_interval(bridge_channel);
2710 ms = bridge_channel_feature_timeout(bridge_channel);
2711 if (ms < 0 || (0 <= ms_interval && ms_interval < ms)) {
2739 ast_debug(1,
"Bridge %s: %p(%s) is going into a signal wait\n",
2741 ast_channel_name(bridge_channel->
chan));
2746 ms = bridge_channel_next_timeout(bridge_channel);
2748 &bridge_channel->
alert_pipe[0], 1, NULL, &outfd, &ms);
2753 bridge_reconfigured(bridge_channel->
bridge, 0);
2762 bridge_handle_trip(bridge_channel);
2763 }
else if (ms == 0) {
2765 bridge_channel_handle_feature_timeout(bridge_channel);
2766 bridge_channel_handle_interval(bridge_channel);
2767 }
else if (-1 < outfd) {
2773 bridge_channel_handle_write(bridge_channel);
2798 for (; (hook = ao2_iterator_next(&iter));
ao2_ref(hook, -1)) {
2799 if (hook->
type == type) {
2805 bridge_channel_suspend(bridge_channel);
2808 if (hook->
type == type) {
2813 }
while ((hook = ao2_iterator_next(&iter)));
2815 bridge_channel_unsuspend(bridge_channel);
2823 uint8_t indicate_src_change = 0;
2828 ast_debug(1,
"Bridge %s: %p(%s) is joining\n",
2830 bridge_channel, ast_channel_name(bridge_channel->
chan));
2838 ast_channel_lock(bridge_channel->
chan);
2844 ast_channel_unlock(bridge_channel->
chan);
2846 ast_channel_lock(peer);
2847 peer_bridge = ast_channel_internal_bridge(peer);
2848 ast_channel_unlock(peer);
2854 if (peer_bridge == bridge_channel->
bridge) {
2856 ast_debug(1,
"Bridge %s: %p(%s) denying Bridge join to prevent Local channel loop\n",
2859 ast_channel_name(bridge_channel->
chan));
2863 ast_channel_lock(bridge_channel->
chan);
2870 if (ast_channel_internal_bridge(bridge_channel->
chan)
2872 ast_channel_unlock(bridge_channel->
chan);
2874 ast_debug(1,
"Bridge %s: %p(%s) failed to join Bridge\n",
2877 ast_channel_name(bridge_channel->
chan));
2884 if (channel_features) {
2887 ast_channel_unlock(bridge_channel->
chan);
2897 swap = bridge_channel->
swap;
2899 if (bridge_channel_internal_push(bridge_channel)) {
2907 bridge_channel_dissolve_check(bridge_channel);
2920 indicate_src_change = 1;
2923 bridge_channel_impart_signal(bridge_channel->
chan);
2927 ao2_t_cleanup(swap,
"Bridge push with swap successful");
2930 if (indicate_src_change) {
2934 bridge_channel_event_join_leave(bridge_channel, AST_BRIDGE_HOOK_TYPE_JOIN);
2938 bridge_channel_wait(bridge_channel);
2944 bridge_channel_event_join_leave(bridge_channel, AST_BRIDGE_HOOK_TYPE_LEAVE);
2948 bridge_channel_internal_pull(bridge_channel);
2949 bridge_channel_settle_owed_events(bridge_channel->
bridge, bridge_channel);
2950 bridge_reconfigured(bridge_channel->
bridge, 1);
2958 ao2_t_cleanup(swap,
"Bridge push with swap failed or exited immediately");
2962 ast_debug(1,
"Channel %s simulating UNHOLD for bridge end.\n",
2963 ast_channel_name(bridge_channel->
chan));
2968 if (ast_channel_sending_dtmf_digit(bridge_channel->
chan)) {
2970 ast_channel_sending_dtmf_digit(bridge_channel->
chan),
2971 ast_channel_sending_dtmf_tv(bridge_channel->
chan),
"bridge end");
2980 ast_debug(1,
"Channel %s simulating T.38 terminate for bridge end.\n",
2981 ast_channel_name(bridge_channel->
chan));
2983 &t38_parameters,
sizeof(t38_parameters));
2998 ast_channel_lock(bridge_channel->
chan);
3000 ast_channel_unlock(bridge_channel->
chan);
3007 int bridge_channel_internal_queue_blind_transfer(
struct ast_channel *transferee,
3008 const char *exten,
const char *context,
3014 ast_channel_lock(transferee);
3016 ast_channel_unlock(transferee);
3018 if (!transferee_bridge_channel) {
3022 if (new_channel_cb) {
3027 ast_copy_string(blind_data.context, context,
sizeof(blind_data.context));
3029 return bridge_channel_queue_action_data(transferee_bridge_channel,
3033 int bridge_channel_internal_queue_attended_transfer(
struct ast_channel *transferee,
3039 ast_channel_lock(transferee);
3041 ast_channel_unlock(transferee);
3043 if (!transferee_bridge_channel) {
3047 ast_copy_string(unbridged_chan_name, ast_channel_name(unbridged_chan),
3048 sizeof(unbridged_chan_name));
3050 return bridge_channel_queue_action_data(transferee_bridge_channel,
3052 sizeof(unbridged_chan_name));
3055 int bridge_channel_internal_allows_optimization(
struct ast_bridge_channel *bridge_channel)
3062 static void bridge_channel_destroy(
void *obj)
3067 if (bridge_channel->
callid) {
3068 bridge_channel->
callid = 0;
3071 if (bridge_channel->
bridge) {
3073 bridge_channel->
bridge = NULL;
3078 bridge_frame_free(fr);
3087 ast_cond_destroy(&bridge_channel->
cond);
3100 bridge_channel = ao2_alloc(
sizeof(
struct ast_bridge_channel), bridge_channel_destroy);
3101 if (!bridge_channel) {
3104 ast_cond_init(&bridge_channel->
cond, NULL);
3116 return bridge_channel;
3122 ast_channel_lock(bridge_channel->
chan);
3126 ast_channel_unlock(bridge_channel->
chan);
struct stasis_message_type * ast_channel_hold_type(void)
Message type for when a channel is placed on hold.
ast_bridge_custom_play_fn custom_play
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
#define PLAYBACK_TIMEOUT
Failsafe for synchronous bridge action waiting.
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Main Channel structure associated with a channel.
Local proxy channel special access.
enum bridge_channel_thread_state activity
The bridge channel thread activity.
struct ast_bridge_channel::@193 dtmf_hook_state
int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Build the connected line information data frame.
#define ast_frdup(fr)
Copies a frame.
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.
Feature configuration relating to transfers.
void ast_bridge_channel_clear_roles(struct ast_bridge_channel *bridge_channel)
Clear all roles from a bridge_channel's role list.
int ast_sem_destroy(struct ast_sem *sem)
Destroy a semaphore.
Asterisk main include file. File version handling, generic pbx functions.
struct ast_flags feature_flags
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
const ast_string_field uniqueid
struct ast_bridge_features * features
const char * ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
Get a string representation of an after bridge callback reason.
int(* ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
Talking indicator callback.
struct stasis_message_type * ast_channel_unhold_type(void)
Message type for when a channel is removed from hold.
int ast_channel_is_multistream(struct ast_channel *chan)
Determine if a channel is multi-stream capable.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
int(* ast_bridge_channel_post_action_data)(struct ast_bridge_channel *bridge_channel, enum bridge_channel_action_type action, const void *data, size_t datalen)
Used to queue an action frame onto a bridge channel and write an action frame into a bridge...
unsigned int option_dtmfminduration
struct ast_stream_topology * ast_channel_get_stream_topology(const struct ast_channel *chan)
Retrieve the topology of streams on a channel.
bridge_channel_state
State information about a bridged channel.
void ast_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid)
Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
Structure that contains features information.
#define ast_channel_unref(c)
Decrease channel reference count.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
void(* suspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Suspend a channel on a bridging technology instance for a bridge.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
void ast_channel_publish_cached_blob(struct ast_channel *chan, struct stasis_message_type *type, struct ast_json *blob)
Publish a channel blob message using the latest snapshot from the cache.
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
Publish a bridge channel leave event.
const ast_string_field atxferthreeway
void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
Publish a bridge channel enter event.
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
Configuration for the builtin features.
int ast_sem_post(struct ast_sem *sem)
Increments the semaphore, unblocking a waiter if necessary.
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
int(* stream_topology_request_change)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a request has been made to change a stream topology on a channel.
unsigned int reconfigured
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
int ast_sem_timedwait(struct ast_sem *sem, const struct timespec *abs_timeout)
Decrements the semaphore, waiting until abs_timeout.
void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel)
Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_joi...
enum bridge_channel_state state
struct ast_bridge_hook generic
static void bridge_sync_wait(struct bridge_sync *sync_struct)
Wait for a synchronous bridge action to complete.
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
static void bridge_sync_init(struct bridge_sync *sync_struct, unsigned int id)
Initialize a synchronous bridge object.
void ast_alertpipe_close(int alert_pipe[2])
Close an alert pipe.
struct ast_channel * ast_bridge_channel_get_chan(struct ast_bridge_channel *bridge_channel)
Get a ref to the bridge_channel's ast_channel.
enum ast_control_t38 request_response
int ast_bridge_channel_write_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
Write a bridge action run application frame into the bridge.
struct ast_frame * ast_read_stream(struct ast_channel *chan)
Reads a frame, but does not filter to just the default streams.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Structure used to transport a message through the frame core.
ast_channel_state
ast_channel states
int ast_indicate_data(struct ast_channel *chan, int condition, const void *data, size_t datalen)
Indicates condition of channel, with payload.
void(* stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a stream topology changes on the channel.
void(* ast_bridge_custom_callback_fn)(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Custom callback run on a bridge channel.
struct ao2_container * dtmf_hooks
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
void ast_bridge_channel_feature_digit(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits to match against DTMF features.
ast_control_frame_type
Internal control frame subtype field values.
General features configuration items.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr)
Write a frame to the specified bridge_channel.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
unsigned int featuredigittimeout
struct ast_bridge_channel * ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel)
Get the peer bridge channel of a two party bridge.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
int ast_sendtext_data(struct ast_channel *chan, struct ast_msg_data *msg)
Sends text to a channel in an ast_msg_data structure wrapper with ast_sendtext as fallback...
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
int ast_bridge_channel_queue_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
Queue a bridge action run application frame onto the bridge channel.
int ast_channel_move(struct ast_channel *dest, struct ast_channel *source)
Move a channel from its current location to a new location.
Out-of-call text message support.
int ast_bridge_channel_establish_roles(struct ast_bridge_channel *bridge_channel)
Clone the roles from a bridge_channel's attached ast_channel onto the bridge_channel's role list...
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
char collected[MAXIMUM_DTMF_FEATURE_STRING]
int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block)
Sets an option on a channel.
int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Queue a bridge action play file frame onto the bridge channel.
int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
Write a control frame into the bridge with data.
int ast_bridge_channel_write_callback(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
Write a bridge action custom callback frame into the bridge.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
ast_bridge_custom_callback_fn callback
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
Maps a channel's stream topology to and from the bridge.
int ast_write_stream(struct ast_channel *chan, int stream_num, struct ast_frame *frame)
Write a frame to a stream This function writes the given frame to the indicated stream on the channel...
int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
Queue a bridge action custom callback frame onto the bridge channel.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
struct ast_vector_int to_bridge
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_frame_subclass subclass
Frame payload for synchronous bridge actions.
struct ast_channel * ast_local_get_peer(struct ast_channel *ast)
Get the other local channel in the pair.
ast_bridge_after_cb_reason
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
const ast_string_field atxfer
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Data specifying where a blind transfer is going to.
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
struct ast_bridge_technology * technology
struct ast_flags feature_flags
unsigned int text_messaging
void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
remove a channel as a source of video for the bridge.
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
int ast_bridge_channel_notify_talking(struct ast_bridge_channel *bridge_channel, int started_talking)
Lets the bridging indicate when a bridge channel has stopped or started talking.
void(* leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Remove a channel from a bridging technology instance for a bridge.
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
#define ast_heap_push(h, elm)
Push an element on to a heap.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
enum ast_bridge_hook_type type
General Asterisk PBX channel definitions.
struct bridge_sync::@318 list
void ast_jb_enable_for_channel(struct ast_channel *chan)
Sets a jitterbuffer frame hook on the channel based on the channel's stored jitterbuffer configuratio...
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
#define AST_OPTION_RELAXDTMF
void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
int(* write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Write a frame into the bridging technology instance for a bridge.
#define ast_strdupa(s)
duplicate a string in memory from the stack
ast_alert_status_t ast_alertpipe_read(int alert_pipe[2])
Read an event from an alert pipe.
void(* ast_bridge_custom_play_fn)(struct ast_bridge_channel *bridge_channel, const char *playfile)
Custom interpretation of the playfile name.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define AST_MAX_EXTENSION
int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *redirecting_info, int is_frame)
Run a redirecting interception subroutine and update a channel's redirecting information.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Private Bridging Channel API.
struct ast_frame * ast_read_stream_noaudio(struct ast_channel *chan)
Reads a frame, but does not filter to just the default streams, returning AST_FRAME_NULL frame if aud...
struct ast_bridge_hook_dtmf_parms dtmf
void ast_bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class)
Run an application on the bridge channel.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
struct timeval interdigit_timeout
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
int ast_channel_is_t38_active(struct ast_channel *chan)
This function will check if T.38 is active on the channel.
static int sync_ids
Counter used for assigning synchronous bridge action IDs.
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
int ast_channel_is_leaving_bridge(struct ast_channel *chan)
Determine if a channel is leaving a bridge, but not hung up.
struct ast_heap * interval_hooks
struct ast_bridge_channel::@190 wr_queue
void ast_bridge_channel_feature_digit_add(struct ast_bridge_channel *bridge_channel, int digit)
Add a DTMF digit to the collected digits.
struct ast_format * write_format
int ast_alertpipe_init(int alert_pipe[2])
Initialize an alert pipe.
#define ast_test_suite_event_notify(s, f,...)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
ast_frame_type
Frame types.
void ast_bridge_features_merge(struct ast_bridge_features *into, const struct ast_bridge_features *from)
Merge one ast_bridge_features into another.
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
const struct ast_bridge_methods * v_table
unsigned int dtmf_passthrough
struct ast_vector_int to_channel
#define AST_OPTION_DIGIT_DETECT
Structure that contains information about a bridge.
int ast_pbx_exec_application(struct ast_channel *chan, const char *app_name, const char *app_args)
Execute an application.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_unlink(container, obj)
Remove an object from a container.
List holding active synchronous action objects.
int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const void *connected_info, int frame)
Run a connected line interception subroutine and update a channel's connected line information...
ast_bridge_hook_callback callback
const char * ast_msg_data_get_attribute(struct ast_msg_data *msg, enum ast_msg_data_attribute_type attribute_type)
Get attribute from ast_msg_data.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Connected Line/Party information.
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
#define ast_strndup(str, len)
A wrapper for strndup()
struct ast_bridge_channel::@191 deferred_queue
const char * app_name(struct ast_app *app)
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
struct ast_format * read_format
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer, struct ast_channel *forwarded, const char *dialstring, const char *dialstatus, const char *forward)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Write a bridge action play file frame into the bridge.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
struct ast_bridge_features * ast_channel_feature_hooks_get(struct ast_channel *chan)
Gets the channel-attached features a channel has access to upon being bridged.
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
union ast_frame::@224 data
unsigned int inhibit_colp
int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *digits)
stream file until digit If the file name is non-empty, try to play it.
#define AST_OPTION_AUDIO_MODE
struct ast_bridge_hook_timer_parms timer
int ast_sem_init(struct ast_sem *sem, int pshared, unsigned int value)
Initialize a semaphore.
int ast_bridge_channel_write_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
Have a bridge channel park a channel in the bridge.
int ast_parking_park_bridge_channel(struct ast_bridge_channel *parkee, const char *parkee_uuid, const char *parker_uuid, const char *app_data)
Perform a direct park on a channel in a bridge.
void ast_channel_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why)
Simulate a DTMF end on a broken bridge channel.
struct ast_channel * swap
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags flags)
Remove marked bridge channel feature hooks.
struct ast_bridge * ast_bridge_channel_merge_inhibit(struct ast_bridge_channel *bridge_channel, int request)
Adjust the bridge_channel's bridge merge inhibit request count.
struct ast_bridge_hook generic
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define ast_bridge_lock(bridge)
Lock the bridge.
struct ast_frame ast_null_frame
void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_channel *source)
Copy the full linkedid channel id structure from one channel to another.
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
struct ast_bridge_channels_list channels
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
struct ast_channel * chan
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Structure that contains information regarding a channel in a bridge.
void ast_party_connected_line_copy(struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
Copy the source connected line information to the destination connected line.
#define AST_OPTION_FAX_DETECT
const ast_string_field blindxfer
ssize_t ast_alertpipe_write(int alert_pipe[2])
Write an event to an alert pipe.
After Bridge Execution API.
#define ast_channel_ref(c)
Increase channel reference count.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
bridge_channel_action_type
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct ao2_container * other_hooks
int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class)
Write a hold frame into the bridge.
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
int ast_answer(struct ast_channel *chan)
Answer a channel.
int ast_queue_control_data(struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame with payload.
struct ast_vector_int media_types
int ast_is_deferrable_frame(const struct ast_frame *frame)
Should we keep this frame for later?
int ast_bridge_channel_queue_playfile_sync(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Synchronously queue a bridge action play file frame onto the bridge channel.
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Data structure associated with a single frame of data.
int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup)
Run a subroutine on a channel, placing an optional second channel into autoservice.
Internal Asterisk hangup causes.
Abstract JSON element (object, array, string, int, ...).
static void bridge_sync_cleanup(struct bridge_sync *sync_struct)
Clean up a synchronization bridge object.
int ast_channel_unbridged(struct ast_channel *chan)
This function will check if the bridge needs to be re-evaluated due to external changes.
#define AST_OPTION_TONE_VERIFY
Synchronous bridge action object.
void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Play a file on the bridge channel.
void(* transfer_channel_cb)(struct ast_channel *chan, struct transfer_channel_data *user_data, enum ast_transfer_type transfer_type)
Callback function type called during blind transfers.
ast_bridge_pull_channel_fn pull
ast_bridge_push_channel_fn push
unsigned int interval_sequence
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
void ast_stream_topology_map(const struct ast_stream_topology *topology, struct ast_vector_int *types, struct ast_vector_int *v0, struct ast_vector_int *v1)
Map a given topology's streams to the given types.
enum ast_frame_type frametype
static void bridge_sync_signal(struct bridge_sync *sync_struct)
Signal that waiting for a synchronous bridge action is no longer necessary.
int ast_queue_frame_head(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to the head of a channel's frame queue.
void(* unsuspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Unsuspend a channel on a bridging technology instance for a bridge.
int ast_bridge_channel_queue_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame onto the bridge channel with data.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
ast_bridge_channel_custom_callback_option
struct ast_bridge_channel::@192 owed
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
const ast_string_field parkcall
const ast_string_field automixmon
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
char code[MAXIMUM_DTMF_FEATURE_STRING]
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
Structure that is the essence of a feature hook.
unsigned int num_channels
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
const ast_string_field disconnect
Timing source management.
void ast_channel_set_unbridged(struct ast_channel *chan, int value)
Sets the unbridged flag and queues a NULL frame on the channel to trigger a check by bridge_channel_w...
struct ast_channel * ast_channel_internal_oldest_linkedid(struct ast_channel *a, struct ast_channel *b)
Determine which channel has an older linkedid.
int ast_sendtext(struct ast_channel *chan, const char *text)
Sends text to a channel.