114 #define UDPTL_MTU 1200
120 #define TRUE (!FALSE)
123 #define LOG_TAG(u) S_OR(u->tag, "no tag")
125 #define DEFAULT_UDPTLSTART 4000
126 #define DEFAULT_UDPTLEND 4999
131 #define LOCAL_FAX_MAX_DATAGRAM 1400
132 #define DEFAULT_FAX_MAX_DATAGRAM 400
133 #define FAX_MAX_DATAGRAM_LIMIT 1400
134 #define MAX_FEC_ENTRIES 5
135 #define MAX_FEC_SPAN 5
137 #define UDPTL_BUF_MASK 15
141 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
146 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
147 unsigned int fec_len[MAX_FEC_ENTRIES];
148 uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM];
149 unsigned int fec_span;
150 unsigned int fec_entries;
159 unsigned int lasteventseqn;
169 ast_udptl_callback callback;
211 unsigned int tx_seq_no;
212 unsigned int rx_seq_no;
221 unsigned int fecentries;
222 unsigned int fecspan;
223 unsigned int nochecksums;
224 unsigned int use_even_ports;
233 static void *udptl_snapshot_alloc(
void);
234 static int udptl_pre_apply_config(
void);
236 static struct aco_type general_option = {
241 .category =
"general",
246 static struct aco_file udptl_conf = {
252 .files = ACO_FILES(&udptl_conf),
253 .pre_apply_config = udptl_pre_apply_config,
256 static inline int udptl_debug_test_addr(
const struct ast_sockaddr *addr)
272 static int decode_length(uint8_t *buf,
unsigned int limit,
unsigned int *len,
unsigned int *pvalue)
276 if ((buf[*len] & 0x80) == 0) {
281 if ((buf[*len] & 0x40) == 0) {
282 if (*len == limit - 1)
284 *pvalue = (buf[*len] & 0x3F) << 8;
286 *pvalue |= buf[*len];
290 *pvalue = (buf[*len] & 0x3F) << 14;
293 ast_debug(1,
"UDPTL packet with length greater than 16K received, decoding will fail\n");
298 static int decode_open_type(uint8_t *buf,
unsigned int limit,
unsigned int *len,
const uint8_t **p_object,
unsigned int *p_num_octets)
300 unsigned int octet_cnt = 0;
302 if (decode_length(buf, limit, len, &octet_cnt) != 0)
306 if ((*len + octet_cnt) > limit) {
310 *p_num_octets = octet_cnt;
311 *p_object = &buf[*len];
318 static unsigned int encode_length(uint8_t *buf,
unsigned int *len,
unsigned int value)
320 unsigned int multiplier;
328 if (value < 0x4000) {
331 buf[*len] = ((0x8000 | value) >> 8) & 0xFF;
333 buf[*len] = value & 0xFF;
338 multiplier = (value < 0x10000) ? (value >> 14) : 4;
340 buf[*len] = 0xC0 | multiplier;
342 return multiplier << 14;
346 static int encode_open_type(
const struct ast_udptl *udptl, uint8_t *buf,
unsigned int buflen,
347 unsigned int *len,
const uint8_t *data,
unsigned int num_octets)
350 unsigned int octet_idx;
354 if (num_octets == 0) {
360 for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
361 enclen = encode_length(buf, len, num_octets);
362 if (enclen + *len > buflen) {
363 ast_log(LOG_ERROR,
"UDPTL (%s): Buffer overflow detected (%u + %u > %u)\n",
364 LOG_TAG(udptl), enclen, *len, buflen);
368 memcpy(&buf[*len], &data[octet_idx], enclen);
371 if (enclen >= num_octets)
379 static int udptl_rx_packet(
struct ast_udptl *s, uint8_t *buf,
unsigned int len)
386 const uint8_t *ifp = NULL;
387 const uint8_t *data = NULL;
388 unsigned int ifp_len = 0;
390 const uint8_t *bufs[ARRAY_LEN(s->f) - 1];
391 unsigned int lengths[ARRAY_LEN(s->f) - 1];
398 memset(&s->f[0], 0,
sizeof(s->f[0]));
403 seq_no = (buf[0] << 8) | buf[1];
416 if (seq_no < 0x000F && s->rx_seq_no > 0xFFF0) {
421 s->rx_seq_no &= 0xFFFF;
425 if ((stat1 = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
430 if ((buf[ptr++] & 0x80) == 0) {
432 if (seq_no > s->rx_seq_no) {
438 if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
440 for (i = 0; i < count && total_count + i < ARRAY_LEN(bufs); i++) {
441 if ((stat1 = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0) {
445 if (!bufs[total_count + i] || !lengths[total_count + i]) {
453 while (stat2 > 0 && total_count < ARRAY_LEN(bufs));
455 for (i = total_count; i > 0; i--) {
456 if (seq_no - i >= s->rx_seq_no) {
459 ast_debug(3,
"Recovering lost packet via secondary %d, len %u\n", seq_no - i, lengths[i - 1]);
464 s->f[ifp_no].
seqno = seq_no - i;
465 s->f[ifp_no].
datalen = lengths[i - 1];
466 s->f[ifp_no].
data.ptr = (uint8_t *) bufs[i - 1];
468 s->f[ifp_no].
src =
"UDPTL";
484 if (ifp_len > LOCAL_FAX_MAX_DATAGRAM)
487 for ( ; seq_no > s->rx_seq_no; s->rx_seq_no++) {
488 x = s->rx_seq_no & UDPTL_BUF_MASK;
489 s->rx[x].buf_len = -1;
490 s->rx[x].fec_len[0] = 0;
491 s->rx[x].fec_span = 0;
492 s->rx[x].fec_entries = 0;
495 x = seq_no & UDPTL_BUF_MASK;
497 memset(repaired, 0,
sizeof(repaired));
500 memcpy(s->rx[x].buf, ifp, ifp_len);
501 s->rx[x].buf_len = ifp_len;
512 s->rx[x].fec_span = span;
518 entries = buf[ptr++];
519 if (entries > MAX_FEC_ENTRIES) {
522 s->rx[x].fec_entries = entries;
525 for (i = 0; i < entries; i++) {
526 if ((stat1 = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
528 if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
532 memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
534 fprintf(stderr,
"FEC: ");
535 for (j = 0; j < s->rx[x].fec_len[i]; j++)
536 fprintf(stderr,
"%02hhX ", data[j]);
537 fprintf(stderr,
"\n");
543 for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
545 if (s->rx[l].fec_len[0] <= 0)
547 for (m = 0; m < s->rx[l].fec_entries; m++) {
550 int limit = (l + m) & UDPTL_BUF_MASK;
553 if (seq_no <= (s->rx[l].fec_span * s->rx[l].fec_entries) - m) {
557 for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
558 if (s->rx[k].buf_len <= 0)
559 which = (which == -1) ? k : -2;
563 for (j = 0; j < s->rx[l].fec_len[m]; j++) {
564 s->rx[which].buf[j] = s->rx[l].fec[m][j];
565 for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit; k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
566 s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
568 s->rx[which].buf_len = s->rx[l].fec_len[m];
569 repaired[which] = TRUE;
574 for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
581 s->f[ifp_no].
seqno = j;
582 s->f[ifp_no].
datalen = s->rx[l].buf_len;
583 s->f[ifp_no].
data.ptr = s->rx[l].buf;
585 s->f[ifp_no].
src =
"UDPTL";
596 if (seq_no >= s->rx_seq_no) {
602 s->f[ifp_no].
seqno = seq_no;
603 s->f[ifp_no].
datalen = ifp_len;
604 s->f[ifp_no].
data.ptr = (uint8_t *) ifp;
606 s->f[ifp_no].
src =
"UDPTL";
614 s->rx_seq_no = seq_no + 1;
619 static int udptl_build_packet(
struct ast_udptl *s, uint8_t *buf,
unsigned int buflen, uint8_t *ifp,
unsigned int ifp_len)
621 uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2] = { 0, };
633 seq = s->tx_seq_no & 0xFFFF;
636 entry = seq & UDPTL_BUF_MASK;
640 s->tx[entry].buf_len = ifp_len;
641 memcpy(s->tx[entry].buf, ifp, ifp_len);
647 buf[len++] = (seq >> 8) & 0xFF;
648 buf[len++] = seq & 0xFF;
651 if (encode_open_type(s, buf, buflen, &len, ifp, ifp_len) < 0)
657 case UDPTL_ERROR_CORRECTION_NONE:
662 encode_length(buf, &len, 0);
664 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
670 entries = s->tx_seq_no;
673 encode_length(buf, &len, entries);
675 for (i = 0; i < entries; i++) {
676 j = (entry - i - 1) & UDPTL_BUF_MASK;
677 if (encode_open_type(s, buf, buflen, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) {
678 ast_debug(1,
"UDPTL (%s): Encoding failed at i=%d, j=%d\n",
684 case UDPTL_ERROR_CORRECTION_FEC:
690 if (seq < s->error_correction_span)
701 buf[len++] = entries;
702 for (m = 0; m < entries; m++) {
704 limit = (entry + m) & UDPTL_BUF_MASK;
706 for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
707 if (high_tide < s->tx[i].buf_len) {
708 for (j = 0; j < high_tide; j++)
709 fec[j] ^= s->tx[i].buf[j];
710 for ( ; j < s->tx[i].buf_len; j++)
711 fec[j] = s->tx[i].buf[j];
712 high_tide = s->tx[i].buf_len;
714 for (j = 0; j < s->tx[i].buf_len; j++)
715 fec[j] ^= s->tx[i].buf[j];
718 if (encode_open_type(s, buf, buflen, &len, fec, high_tide) < 0)
728 int ast_udptl_fd(
const struct ast_udptl *udptl)
733 void ast_udptl_set_data(
struct ast_udptl *udptl,
void *data)
738 void ast_udptl_set_callback(
struct ast_udptl *udptl, ast_udptl_callback callback)
740 udptl->callback = callback;
743 void ast_udptl_setnat(
struct ast_udptl *udptl,
int nat)
748 static int udptlread(
int *
id,
int fd,
short events,
void *cbdata)
753 if ((f = ast_udptl_read(udptl))) {
755 udptl->callback(udptl, f, udptl->data);
776 ast_log(LOG_WARNING,
"UDPTL (%s): read error: %s\n",
777 LOG_TAG(udptl), strerror(errno));
778 ast_assert(errno != EBADF);
795 if (udptl->tag == NULL) {
803 ast_debug(1,
"UDPTL (%s): NAT, Using address %s\n",
808 if (udptl_debug_test_addr(&addr)) {
816 seq_no = (buf[0] << 8) | buf[1];
819 ast_verb(1,
"UDPTL (%s): packet from %s (seq %d, len %d)\n",
822 if (udptl_rx_packet(udptl, buf, res) < 1) {
829 static void calculate_local_max_datagram(
struct ast_udptl *udptl)
831 unsigned int new_max = 0;
834 ast_log(LOG_WARNING,
"UDPTL (%s): Cannot calculate local_max_datagram before local_max_ifp has been set.\n",
847 case UDPTL_ERROR_CORRECTION_NONE:
853 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
859 case UDPTL_ERROR_CORRECTION_FEC:
870 static void calculate_far_max_ifp(
struct ast_udptl *udptl)
872 unsigned new_max = 0;
875 ast_log(LOG_WARNING,
"UDPTL (%s): Cannot calculate far_max_ifp before far_max_datagram has been set.\n",
895 case UDPTL_ERROR_CORRECTION_NONE:
901 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
927 case UDPTL_ERROR_CORRECTION_FEC:
938 enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme(
const struct ast_udptl *udptl)
943 void ast_udptl_set_error_correction_scheme(
struct ast_udptl *udptl,
enum ast_t38_ec_modes ec)
947 case UDPTL_ERROR_CORRECTION_FEC:
956 case UDPTL_ERROR_CORRECTION_REDUNDANCY:
971 void ast_udptl_set_local_max_ifp(
struct ast_udptl *udptl,
unsigned int max_ifp)
975 if ((
signed int) max_ifp > 0) {
985 calculate_local_max_datagram(udptl);
997 if (!max_datagram || (max_datagram > FAX_MAX_DATAGRAM_LIMIT)) {
1006 unsigned int ast_udptl_get_far_max_datagram(
const struct ast_udptl *udptl)
1017 calculate_far_max_ifp(udptl);
1034 if (!cfg || !cfg->general) {
1035 ast_log(LOG_ERROR,
"Could not access global udptl options!\n");
1039 if (!(udptl =
ast_calloc(1,
sizeof(*udptl)))) {
1051 for (i = 0; i <= UDPTL_BUF_MASK; i++) {
1052 udptl->rx[i].buf_len = -1;
1053 udptl->tx[i].buf_len = -1;
1057 AF_INET6 : AF_INET, SOCK_DGRAM, 0)) < 0) {
1059 ast_log(LOG_WARNING,
"Unable to allocate socket: %s\n", strerror(errno));
1064 if (cfg->general->nochecksums)
1065 setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &cfg->general->nochecksums,
sizeof(cfg->general->nochecksums));
1069 x = (cfg->general->start == cfg->general->end) ? cfg->general->start : (ast_random() % (cfg->general->end - cfg->general->start)) + cfg->general->start;
1070 if (cfg->general->use_even_ports && (x & 1)) {
1077 if (
ast_bind(udptl->fd, &udptl->us) == 0) {
1080 if (errno != EADDRINUSE && errno != EACCES) {
1081 ast_log(LOG_WARNING,
"Unexpected bind error: %s\n", strerror(errno));
1086 if (cfg->general->use_even_ports) {
1091 if (x > cfg->general->end)
1092 x = cfg->general->start;
1093 if (x == startplace) {
1094 ast_log(LOG_WARNING,
"No UDPTL ports remaining\n");
1100 if (io && sched && callbackmode) {
1102 udptl->sched = sched;
1114 ast_free(udptl->tag);
1116 va_start(ap, format);
1123 int ast_udptl_setqos(
struct ast_udptl *udptl,
unsigned int tos,
unsigned int cos)
1143 void ast_udptl_stop(
struct ast_udptl *udptl)
1148 void ast_udptl_destroy(
struct ast_udptl *udptl)
1155 ast_free(udptl->tag);
1162 unsigned int len = f->
datalen;
1165 uint8_t buf[bufsize];
1167 memset(buf, 0,
sizeof(buf));
1180 ast_log(LOG_WARNING,
"UDPTL (%s): UDPTL can only send T.38 data.\n",
1186 ast_log(LOG_WARNING,
1187 "UDPTL (%s): UDPTL asked to send %u bytes of IFP when far end only prepared to accept %d bytes; data loss will occur."
1188 "You may need to override the T38FaxMaxDatagram value for this endpoint in the channel driver configuration.\n",
1194 seq = s->tx_seq_no & 0xFFFF;
1197 len = udptl_build_packet(s, buf,
sizeof(buf), f->
data.ptr, len);
1200 if (
ast_sendto(s->fd, buf, len, 0, &s->them) < 0) {
1201 ast_log(LOG_NOTICE,
"UDPTL (%s): Transmission error to %s: %s\n",
1204 if (udptl_debug_test_addr(&s->them)) {
1205 ast_verb(1,
"UDPTL (%s): packet to %s (seq %u, len %u)\n",
1217 e->
command =
"udptl set debug {on|off|ip}";
1219 "Usage: udptl set debug {on|off|ip host[:port]}\n"
1220 " Enable or disable dumping of UDPTL packets.\n"
1221 " If ip is specified, limit the dumped packets to those to and from\n"
1222 " the specified 'host' with optional port.\n";
1228 if (a->argc < 4 || a->argc > 5)
1229 return CLI_SHOWUSAGE;
1232 if (!strncasecmp(a->argv[3],
"on", 2)) {
1235 ast_cli(a->fd,
"UDPTL Debugging Enabled\n");
1236 }
else if (!strncasecmp(a->argv[3],
"off", 3)) {
1238 ast_cli(a->fd,
"UDPTL Debugging Disabled\n");
1240 return CLI_SHOWUSAGE;
1244 if (strncasecmp(a->argv[3],
"ip", 2))
1245 return CLI_SHOWUSAGE;
1247 return CLI_SHOWUSAGE;
1264 e->
command =
"udptl show config";
1266 "Usage: udptl show config\n"
1267 " Display UDPTL configuration options\n";
1277 ast_cli(a->fd,
"UDPTL Global options\n");
1278 ast_cli(a->fd,
"--------------------\n");
1279 ast_cli(a->fd,
"udptlstart: %u\n", cfg->general->start);
1280 ast_cli(a->fd,
"udptlend: %u\n", cfg->general->end);
1281 ast_cli(a->fd,
"udptlfecentries: %u\n", cfg->general->fecentries);
1282 ast_cli(a->fd,
"udptlfecspan: %u\n", cfg->general->fecspan);
1283 ast_cli(a->fd,
"use_even_ports: %s\n",
AST_CLI_YESNO(cfg->general->use_even_ports));
1284 ast_cli(a->fd,
"udptlchecksums: %s\n",
AST_CLI_YESNO(!cfg->general->nochecksums));
1290 AST_CLI_DEFINE(handle_cli_udptl_set_debug,
"Enable/Disable UDPTL debugging"),
1291 AST_CLI_DEFINE(handle_cli_show_config,
"Show UDPTL config options"),
1294 static void udptl_config_destructor(
void *obj)
1297 ao2_cleanup(cfg->general);
1300 static void *udptl_snapshot_alloc(
void)
1304 if (!(cfg = ao2_alloc(
sizeof(*cfg), udptl_config_destructor))) {
1307 if (!(cfg->general = ao2_alloc(
sizeof(*cfg->general), NULL))) {
1317 if (!strcasecmp(var->
name,
"t38faxudpec")) {
1318 ast_log(LOG_WARNING,
"t38faxudpec in udptl.conf is no longer supported.\n");
1319 }
else if (!strcasecmp(var->
name,
"t38faxmaxdatagram")) {
1320 ast_log(LOG_WARNING,
"t38faxmaxdatagram in udptl.conf is no longer supported; value is now supplied by T.38 applications.\n");
1325 static void __ast_udptl_reload(
int reload)
1332 ast_log(LOG_ERROR,
"Failed to load udptl.conf and failed to initialize defaults.\n");
1336 ast_log(LOG_NOTICE,
"Could not load udptl config; using defaults\n");
1342 static int udptl_pre_apply_config(
void) {
1345 if (!cfg->general) {
1350 if (cfg->general->nochecksums) {
1351 ast_log(LOG_WARNING,
"Disabling UDPTL checksums is not supported on this operating system!\n");
1352 cfg->general->nochecksums = 0;
1357 if (cfg->general->use_even_ports && (cfg->general->start & 1)) {
1358 ++cfg->general->start;
1359 ast_log(LOG_NOTICE,
"Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %u\n", cfg->general->start);
1361 if (cfg->general->start > cfg->general->end) {
1362 ast_log(LOG_WARNING,
"Unreasonable values for UDPTL start/end ports; defaulting to %s-%s.\n", __stringify(DEFAULT_UDPTLSTART), __stringify(DEFAULT_UDPTLEND));
1363 cfg->general->start = DEFAULT_UDPTLSTART;
1364 cfg->general->end = DEFAULT_UDPTLEND;
1366 if (cfg->general->use_even_ports && (cfg->general->end & 1)) {
1367 --cfg->general->end;
1368 ast_log(LOG_NOTICE,
"Odd numbered udptlend specified but use_even_ports enabled. udptlend is now %u\n", cfg->general->end);
1374 static int reload_module(
void)
1376 __ast_udptl_reload(1);
1385 static int unload_module(
void)
1388 ao2_t_global_obj_release(globals,
"Unref udptl global container in shutdown");
1394 static int load_module(
void)
1400 aco_option_register(&cfg_info,
"udptlstart", ACO_EXACT, general_options, __stringify(DEFAULT_UDPTLSTART),
1404 aco_option_register(&cfg_info,
"udptlend", ACO_EXACT, general_options, __stringify(DEFAULT_UDPTLEND),
1409 OPT_UINT_T, PARSE_IN_RANGE | PARSE_RANGE_DEFAULTS,
1413 OPT_UINT_T, PARSE_IN_RANGE | PARSE_RANGE_DEFAULTS,
1425 __ast_udptl_reload(0);
1432 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,
"UDPTL",
1433 .support_level = AST_MODULE_SUPPORT_CORE,
1434 .load = load_module,
1435 .unload = unload_module,
1436 .reload = reload_module,
1438 .requires =
"extconfig",
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
unsigned int error_correction_span
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
static struct ast_sockaddr udptldebugaddr
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
descriptor for a cli entry.
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
Structure for variables, used for configurations and for channel variables.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Structure for an UDPTL session.
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
enum aco_process_status aco_process_config(struct aco_info *info, int reload)
Process a config info via the options registered with an aco_info.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
CONFIG_INFO_CORE("stasis", cfg_info, globals, stasis_config_alloc,.files=ACO_FILES(&stasis_conf),)
Register information about the configs being processed by this module.
#define ast_vasprintf(ret, fmt, ap)
A wrapper for vasprintf()
unsigned int error_correction_entries
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
The representation of a single configuration file to be processed.
Socket address structure.
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
struct ast_frame_subclass subclass
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized, or having a 0 length.
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Handle unaligned data access.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
General Asterisk PBX channel definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
Type for default option handler for unsigned integers.
Access Control of various sorts.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Global IO variables are now in a struct in order to be made threadsafe.
Asterisk internal frame definitions.
static struct stasis_rest_handlers events
REST handler for /api-docs/events.json.
#define ast_debug(level,...)
Log a DEBUG message.
Their was an error and no changes were applied.
Configuration option-handling.
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
void ast_udptl_set_tag(struct ast_udptl *udptl, const char *format,...)
Associates a character string 'tag' with a UDPTL session.
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
Type for default option handler for bools (ast_true/ast_false)
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
unsigned int ast_udptl_get_local_max_datagram(struct ast_udptl *udptl)
retrieves local_max_datagram.
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
union ast_frame::@224 data
#define ast_calloc(num, len)
A wrapper for calloc()
void ast_udptl_set_far_max_datagram(struct ast_udptl *udptl, unsigned int max_datagram)
sets far max datagram size. If max_datagram is = 0, the far max datagram size is set to a default val...
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
Module could not be loaded properly.
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
struct ast_frame ast_null_frame
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Standard Command Line Interface.
Type information about a category-level configurable object.
Data structure associated with a single frame of data.
enum ast_frame_type frametype
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
#define AO2_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
enum ast_t38_ec_modes error_correction_scheme
unsigned int ast_udptl_get_far_max_ifp(struct ast_udptl *udptl)
retrieves far max ifp
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.