Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
udptl.c File Reference

UDPTL support for T.38 faxing. More...

#include "asterisk.h"
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include "asterisk/module.h"
#include "asterisk/udptl.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/acl.h"
#include "asterisk/config_options.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/netsock2.h"
#include "asterisk/cli.h"
#include "asterisk/unaligned.h"
Include dependency graph for udptl.c:

Go to the source code of this file.

Data Structures

struct  ast_udptl
 Structure for an UDPTL session. More...
 
struct  udptl_config
 
struct  udptl_fec_rx_buffer_t
 
struct  udptl_fec_tx_buffer_t
 
struct  udptl_global_options
 

Macros

#define DEFAULT_FAX_MAX_DATAGRAM   400
 
#define DEFAULT_UDPTLEND   4999
 
#define DEFAULT_UDPTLSTART   4000
 
#define FALSE   0
 
#define FAX_MAX_DATAGRAM_LIMIT   1400
 
#define LOCAL_FAX_MAX_DATAGRAM   1400
 
#define LOG_TAG(u)   S_OR(u->tag, "no tag")
 
#define MAX_FEC_ENTRIES   5
 
#define MAX_FEC_SPAN   5
 
#define TRUE   (!FALSE)
 
#define UDPTL_BUF_MASK   15
 
#define UDPTL_MTU   1200
 

Functions

static void __ast_udptl_reload (int reload)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static AO2_GLOBAL_OBJ_STATIC (globals)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
void ast_udptl_destroy (struct ast_udptl *udptl)
 
int ast_udptl_fd (const struct ast_udptl *udptl)
 
enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme (const struct ast_udptl *udptl)
 
unsigned int ast_udptl_get_far_max_datagram (const struct ast_udptl *udptl)
 
unsigned int ast_udptl_get_far_max_ifp (struct ast_udptl *udptl)
 retrieves far max ifp More...
 
unsigned int ast_udptl_get_local_max_datagram (struct ast_udptl *udptl)
 retrieves local_max_datagram. More...
 
void ast_udptl_get_peer (const struct ast_udptl *udptl, struct ast_sockaddr *them)
 
void ast_udptl_get_us (const struct ast_udptl *udptl, struct ast_sockaddr *us)
 
struct ast_udptlast_udptl_new_with_bindaddr (struct ast_sched_context *sched, struct io_context *io, int callbackmode, struct ast_sockaddr *addr)
 
struct ast_frameast_udptl_read (struct ast_udptl *udptl)
 
void ast_udptl_set_callback (struct ast_udptl *udptl, ast_udptl_callback callback)
 
void ast_udptl_set_data (struct ast_udptl *udptl, void *data)
 
void ast_udptl_set_error_correction_scheme (struct ast_udptl *udptl, enum ast_t38_ec_modes ec)
 
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 value. More...
 
void ast_udptl_set_local_max_ifp (struct ast_udptl *udptl, unsigned int max_ifp)
 
void ast_udptl_set_peer (struct ast_udptl *udptl, const struct ast_sockaddr *them)
 
void ast_udptl_set_tag (struct ast_udptl *udptl, const char *format,...)
 Associates a character string 'tag' with a UDPTL session. More...
 
void ast_udptl_setnat (struct ast_udptl *udptl, int nat)
 
int ast_udptl_setqos (struct ast_udptl *udptl, unsigned int tos, unsigned int cos)
 
void ast_udptl_stop (struct ast_udptl *udptl)
 
int ast_udptl_write (struct ast_udptl *s, struct ast_frame *f)
 
static void calculate_far_max_ifp (struct ast_udptl *udptl)
 
static void calculate_local_max_datagram (struct ast_udptl *udptl)
 
 CONFIG_INFO_CORE ("udptl", cfg_info, globals, udptl_snapshot_alloc,.files=ACO_FILES(&udptl_conf),.pre_apply_config=udptl_pre_apply_config,)
 
static int decode_length (uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
 
static int decode_open_type (uint8_t *buf, unsigned int limit, unsigned int *len, const uint8_t **p_object, unsigned int *p_num_octets)
 
static unsigned int encode_length (uint8_t *buf, unsigned int *len, unsigned int value)
 
static int encode_open_type (const struct ast_udptl *udptl, uint8_t *buf, unsigned int buflen, unsigned int *len, const uint8_t *data, unsigned int num_octets)
 
static char * handle_cli_show_config (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_udptl_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int load_module (void)
 
static int reload_module (void)
 
static int removed_options_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static int udptl_build_packet (struct ast_udptl *s, uint8_t *buf, unsigned int buflen, uint8_t *ifp, unsigned int ifp_len)
 
static void udptl_config_destructor (void *obj)
 
static int udptl_debug_test_addr (const struct ast_sockaddr *addr)
 
static int udptl_pre_apply_config (void)
 
static int udptl_rx_packet (struct ast_udptl *s, uint8_t *buf, unsigned int len)
 
static void * udptl_snapshot_alloc (void)
 
static int udptlread (int *id, int fd, short events, void *cbdata)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "UDPTL" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_udptl []
 
static struct aco_type general_option
 
static struct aco_typegeneral_options [] = ACO_TYPES(&general_option)
 
static struct aco_file udptl_conf
 
static int udptldebug
 
static struct ast_sockaddr udptldebugaddr
 

Detailed Description

UDPTL support for T.38 faxing.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Steve Underwood steve.nosp@m.u@co.nosp@m.ppice.nosp@m..org
Kevin P. Fleming kpfle.nosp@m.ming.nosp@m.@digi.nosp@m.um.c.nosp@m.om

Definition in file udptl.c.

Macro Definition Documentation

◆ DEFAULT_FAX_MAX_DATAGRAM

#define DEFAULT_FAX_MAX_DATAGRAM   400

Definition at line 134 of file udptl.c.

Referenced by ast_udptl_set_far_max_datagram(), and ast_udptl_write().

◆ DEFAULT_UDPTLEND

#define DEFAULT_UDPTLEND   4999

Definition at line 128 of file udptl.c.

Referenced by load_module(), and udptl_pre_apply_config().

◆ DEFAULT_UDPTLSTART

#define DEFAULT_UDPTLSTART   4000

Definition at line 127 of file udptl.c.

Referenced by load_module(), and udptl_pre_apply_config().

◆ FALSE

#define FALSE   0

Definition at line 119 of file udptl.c.

◆ FAX_MAX_DATAGRAM_LIMIT

#define FAX_MAX_DATAGRAM_LIMIT   1400

Definition at line 135 of file udptl.c.

Referenced by ast_udptl_set_far_max_datagram().

◆ LOCAL_FAX_MAX_DATAGRAM

#define LOCAL_FAX_MAX_DATAGRAM   1400

Definition at line 133 of file udptl.c.

Referenced by calculate_local_max_datagram(), udptl_build_packet(), and udptl_rx_packet().

◆ LOG_TAG

#define LOG_TAG (   u)    S_OR(u->tag, "no tag")

◆ MAX_FEC_ENTRIES

#define MAX_FEC_ENTRIES   5

Definition at line 136 of file udptl.c.

Referenced by load_module(), and udptl_rx_packet().

◆ MAX_FEC_SPAN

#define MAX_FEC_SPAN   5

Definition at line 137 of file udptl.c.

Referenced by load_module().

◆ TRUE

#define TRUE   (!FALSE)

Definition at line 122 of file udptl.c.

Referenced by udptl_rx_packet().

◆ UDPTL_BUF_MASK

#define UDPTL_BUF_MASK   15

Definition at line 139 of file udptl.c.

Referenced by ast_udptl_new_with_bindaddr(), udptl_build_packet(), and udptl_rx_packet().

◆ UDPTL_MTU

#define UDPTL_MTU   1200

Definition at line 116 of file udptl.c.

Function Documentation

◆ __ast_udptl_reload()

static void __ast_udptl_reload ( int  reload)
static

Definition at line 1327 of file udptl.c.

References aco_process_config(), ACO_PROCESS_ERROR, aco_set_defaults(), ao2_cleanup, ao2_global_obj_replace_unref, ast_log, globals, LOG_ERROR, LOG_NOTICE, RAII_VAR, and udptl_snapshot_alloc().

Referenced by load_module(), and reload_module().

1328 {
1329  if (aco_process_config(&cfg_info, reload) == ACO_PROCESS_ERROR) {
1330  if (!reload) {
1331  RAII_VAR(struct udptl_config *, udptl_cfg, udptl_snapshot_alloc(), ao2_cleanup);
1332 
1333  if (aco_set_defaults(&general_option, "general", udptl_cfg->general)) {
1334  ast_log(LOG_ERROR, "Failed to load udptl.conf and failed to initialize defaults.\n");
1335  return;
1336  }
1337 
1338  ast_log(LOG_NOTICE, "Could not load udptl config; using defaults\n");
1340  }
1341  }
1342 }
static void * udptl_snapshot_alloc(void)
Definition: udptl.c:1302
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 ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct console_pvt globals
Their was an error and no changes were applied.
#define LOG_ERROR
Definition: logger.h:285
#define LOG_NOTICE
Definition: logger.h:263
static int reload(void)
Definition: cdr_mysql.c:741
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
#define ao2_global_obj_replace_unref(holder, obj)
Definition: astobj2.h:908
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct aco_type general_option
Definition: udptl.c:238

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1441 of file udptl.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1441 of file udptl.c.

◆ AO2_GLOBAL_OBJ_STATIC()

static AO2_GLOBAL_OBJ_STATIC ( globals  )
static

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 1441 of file udptl.c.

◆ ast_udptl_destroy()

void ast_udptl_destroy ( struct ast_udptl udptl)

Definition at line 1150 of file udptl.c.

References ast_free, ast_io_remove(), ast_udptl::fd, ast_udptl::io, ast_udptl::ioid, and ast_udptl::tag.

Referenced by ooh323_destroy(), sip_pvt_dtor(), and stream_destroy().

1151 {
1152  if (udptl->ioid)
1153  ast_io_remove(udptl->io, udptl->ioid);
1154  if (udptl->fd > -1)
1155  close(udptl->fd);
1156  if (udptl->tag)
1157  ast_free(udptl->tag);
1158  ast_free(udptl);
1159 }
int fd
Definition: udptl.c:157
int * ioid
Definition: udptl.c:166
char * tag
Definition: udptl.c:170
struct io_context * io
Definition: udptl.c:168
#define ast_free(a)
Definition: astmm.h:182
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:245

◆ ast_udptl_fd()

int ast_udptl_fd ( const struct ast_udptl udptl)

Definition at line 730 of file udptl.c.

References ast_udptl::fd.

Referenced by apply_negotiated_sdp_stream(), configure_local_rtp(), initialize_udptl(), and sip_new().

731 {
732  return udptl->fd;
733 }
int fd
Definition: udptl.c:157

◆ ast_udptl_get_error_correction_scheme()

enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme ( const struct ast_udptl udptl)

Definition at line 940 of file udptl.c.

References ast_udptl::error_correction_scheme.

Referenced by add_sdp(), and create_outgoing_sdp_stream().

941 {
942  return udptl->error_correction_scheme;
943 }
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:176

◆ ast_udptl_get_far_max_datagram()

unsigned int ast_udptl_get_far_max_datagram ( const struct ast_udptl udptl)

Definition at line 1008 of file udptl.c.

References ast_udptl::far_max_datagram.

Referenced by process_sdp().

1009 {
1010  if (udptl->far_max_datagram < 0) {
1011  return 0;
1012  }
1013  return udptl->far_max_datagram;
1014 }
int far_max_datagram
Definition: udptl.c:191

◆ ast_udptl_get_far_max_ifp()

unsigned int ast_udptl_get_far_max_ifp ( struct ast_udptl udptl)

retrieves far max ifp

Return values
positivevalue representing max ifp size
0if no value is present

Definition at line 1016 of file udptl.c.

References calculate_far_max_ifp(), and ast_udptl::far_max_ifp.

Referenced by change_t38_state(), interpret_t38_parameters(), onModeChanged(), ooh323_indicate(), setup_udptl_connection(), t38_change_state(), and t38_interpret_parameters().

1017 {
1018  if (udptl->far_max_ifp == -1) {
1019  calculate_far_max_ifp(udptl);
1020  }
1021 
1022  if (udptl->far_max_ifp < 0) {
1023  return 0;
1024  }
1025  return udptl->far_max_ifp;
1026 }
int far_max_ifp
Definition: udptl.c:205
static void calculate_far_max_ifp(struct ast_udptl *udptl)
Definition: udptl.c:872

◆ ast_udptl_get_local_max_datagram()

unsigned int ast_udptl_get_local_max_datagram ( struct ast_udptl udptl)

retrieves local_max_datagram.

Return values
positivevalue representing max datagram size.
0if no value is present

Definition at line 984 of file udptl.c.

References calculate_local_max_datagram(), and ast_udptl::local_max_datagram.

Referenced by add_sdp(), and create_outgoing_sdp_stream().

985 {
986  if (udptl->local_max_datagram == -1) {
988  }
989 
990  /* this function expects a unsigned value in return. */
991  if (udptl->local_max_datagram < 0) {
992  return 0;
993  }
994  return udptl->local_max_datagram;
995 }
int local_max_datagram
Definition: udptl.c:197
static void calculate_local_max_datagram(struct ast_udptl *udptl)
Definition: udptl.c:831

◆ ast_udptl_get_peer()

void ast_udptl_get_peer ( const struct ast_udptl udptl,
struct ast_sockaddr them 
)

Definition at line 1135 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::them.

1136 {
1137  ast_sockaddr_copy(them, &udptl->them);
1138 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct ast_sockaddr them
Definition: udptl.c:165

◆ ast_udptl_get_us()

void ast_udptl_get_us ( const struct ast_udptl udptl,
struct ast_sockaddr us 
)

Definition at line 1140 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::us.

Referenced by add_sdp(), configure_local_rtp(), and create_outgoing_sdp_stream().

1141 {
1142  ast_sockaddr_copy(us, &udptl->us);
1143 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct ast_sockaddr us
Definition: udptl.c:164

◆ ast_udptl_new_with_bindaddr()

struct ast_udptl* ast_udptl_new_with_bindaddr ( struct ast_sched_context sched,
struct io_context io,
int  callbackmode,
struct ast_sockaddr addr 
)

Definition at line 1028 of file udptl.c.

References ao2_cleanup, ao2_global_obj_ref, ast_bind(), ast_calloc, ast_free, ast_io_add(), AST_IO_IN, ast_log, ast_random(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_set_port, ast_socket_nonblock, udptl_fec_tx_buffer_t::buf_len, udptl_fec_rx_buffer_t::buf_len, errno, ast_udptl::error_correction_entries, ast_udptl::error_correction_span, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, ast_udptl::fd, globals, ast_udptl::io, io, ast_udptl::ioid, ast_udptl::local_max_datagram, ast_udptl::local_max_ifp, LOG_ERROR, LOG_WARNING, NULL, RAII_VAR, ast_udptl::rx, ast_udptl::sched, sched, ast_udptl::tx, UDPTL_BUF_MASK, udptlread(), and ast_udptl::us.

Referenced by configure_local_rtp(), initialize_udptl(), and t38_initialize_session().

1029 {
1030  struct ast_udptl *udptl;
1031  int x;
1032  int startplace;
1033  int i;
1035 
1036  if (!cfg || !cfg->general) {
1037  ast_log(LOG_ERROR, "Could not access global udptl options!\n");
1038  return NULL;
1039  }
1040 
1041  if (!(udptl = ast_calloc(1, sizeof(*udptl)))) {
1042  return NULL;
1043  }
1044 
1045  udptl->error_correction_span = cfg->general->fecspan;
1046  udptl->error_correction_entries = cfg->general->fecentries;
1047 
1048  udptl->far_max_datagram = -1;
1049  udptl->far_max_ifp = -1;
1050  udptl->local_max_ifp = -1;
1051  udptl->local_max_datagram = -1;
1052 
1053  for (i = 0; i <= UDPTL_BUF_MASK; i++) {
1054  udptl->rx[i].buf_len = -1;
1055  udptl->tx[i].buf_len = -1;
1056  }
1057 
1058  if ((udptl->fd = ast_socket_nonblock(ast_sockaddr_is_ipv6(addr) ?
1059  AF_INET6 : AF_INET, SOCK_DGRAM, 0)) < 0) {
1060  ast_free(udptl);
1061  ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
1062  return NULL;
1063  }
1064 
1065 #ifdef SO_NO_CHECK
1066  if (cfg->general->nochecksums)
1067  setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &cfg->general->nochecksums, sizeof(cfg->general->nochecksums));
1068 #endif
1069 
1070  /* Find us a place */
1071  x = (cfg->general->start == cfg->general->end) ? cfg->general->start : (ast_random() % (cfg->general->end - cfg->general->start)) + cfg->general->start;
1072  if (cfg->general->use_even_ports && (x & 1)) {
1073  ++x;
1074  }
1075  startplace = x;
1076  for (;;) {
1077  ast_sockaddr_copy(&udptl->us, addr);
1078  ast_sockaddr_set_port(&udptl->us, x);
1079  if (ast_bind(udptl->fd, &udptl->us) == 0) {
1080  break;
1081  }
1082  if (errno != EADDRINUSE && errno != EACCES) {
1083  ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
1084  close(udptl->fd);
1085  ast_free(udptl);
1086  return NULL;
1087  }
1088  if (cfg->general->use_even_ports) {
1089  x += 2;
1090  } else {
1091  ++x;
1092  }
1093  if (x > cfg->general->end)
1094  x = cfg->general->start;
1095  if (x == startplace) {
1096  ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
1097  close(udptl->fd);
1098  ast_free(udptl);
1099  return NULL;
1100  }
1101  }
1102  if (io && sched && callbackmode) {
1103  /* Operate this one in a callback mode */
1104  udptl->sched = sched;
1105  udptl->io = io;
1106  udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
1107  }
1108 
1109  return udptl;
1110 }
int fd
Definition: udptl.c:157
static struct ast_sched_context * sched
Definition: chan_ooh323.c:400
unsigned int error_correction_span
Definition: udptl.c:186
int local_max_datagram
Definition: udptl.c:197
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define LOG_WARNING
Definition: logger.h:274
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
Definition: utils.h:1043
int * ioid
Definition: udptl.c:166
#define AST_IO_IN
Definition: io.h:34
Structure for an UDPTL session.
Definition: udptl.c:156
int * ast_io_add(struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
Adds an IO context.
Definition: io.c:162
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
unsigned int error_correction_entries
Definition: udptl.c:181
#define NULL
Definition: resample.c:96
struct ast_sockaddr us
Definition: udptl.c:164
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
int far_max_datagram
Definition: udptl.c:191
struct ast_sched_context * sched
Definition: udptl.c:167
static struct io_context * io
Definition: chan_ooh323.c:401
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK+1]
Definition: udptl.c:217
long int ast_random(void)
Definition: main/utils.c:2064
static struct console_pvt globals
static int udptlread(int *id, int fd, short events, void *cbdata)
Definition: udptl.c:750
#define LOG_ERROR
Definition: logger.h:285
struct io_context * io
Definition: udptl.c:168
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int errno
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
int far_max_ifp
Definition: udptl.c:205
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
int local_max_ifp
Definition: udptl.c:211
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK+1]
Definition: udptl.c:216
#define UDPTL_BUF_MASK
Definition: udptl.c:139
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524

◆ ast_udptl_read()

struct ast_frame* ast_udptl_read ( struct ast_udptl udptl)

Definition at line 762 of file udptl.c.

References ast_assert, ast_debug, AST_FRIENDLY_OFFSET, ast_log, ast_null_frame, ast_recvfrom(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verb, buf, errno, ast_udptl::f, ast_udptl::fd, LOG_TAG, LOG_WARNING, ast_udptl::nat, NULL, ast_udptl::rawdata, ast_udptl::tag, ast_udptl::them, udptl_debug_test_addr(), and udptl_rx_packet().

Referenced by media_session_udptl_read_callback(), ooh323_rtp_read(), sip_rtp_read(), skinny_rtp_read(), and udptlread().

763 {
764  int res;
765  struct ast_sockaddr addr;
766  uint8_t *buf;
767 
768  buf = udptl->rawdata + AST_FRIENDLY_OFFSET;
769 
770  /* Cache where the header will go */
771  res = ast_recvfrom(udptl->fd,
772  buf,
773  sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
774  0,
775  &addr);
776  if (res < 0) {
777  if (errno != EAGAIN)
778  ast_log(LOG_WARNING, "UDPTL (%s): read error: %s\n",
779  LOG_TAG(udptl), strerror(errno));
780  ast_assert(errno != EBADF);
781  return &ast_null_frame;
782  }
783 
784  /* Ignore if the other side hasn't been given an address yet. */
785  if (ast_sockaddr_isnull(&udptl->them)) {
786  return &ast_null_frame;
787  }
788 
789  /*
790  * If early media isn't turned on for the channel driver, it's going to
791  * drop this frame. By that time though, udptl has already incremented
792  * the expected sequence number so if the CPE re-sends, the second frame
793  * will be dropped as a dup even though the first frame never went through.
794  * So we drop the frame here if the channel isn't up. 'tag' is set by the
795  * channel drivers on T38_ENABLED or T38_PEER_REINVITE.
796  */
797  if (udptl->tag == NULL) {
798  return &ast_null_frame;
799  }
800 
801  if (udptl->nat) {
802  /* Send to whoever sent to us */
803  if (ast_sockaddr_cmp(&udptl->them, &addr)) {
804  ast_sockaddr_copy(&udptl->them, &addr);
805  ast_debug(1, "UDPTL (%s): NAT, Using address %s\n",
806  LOG_TAG(udptl), ast_sockaddr_stringify(&udptl->them));
807  }
808  }
809 
810  if (udptl_debug_test_addr(&addr)) {
811  int seq_no;
812 
813  /* Decode sequence number just for verbose message. */
814  if (res < 2) {
815  /* Short packet. */
816  seq_no = -1;
817  } else {
818  seq_no = (buf[0] << 8) | buf[1];
819  }
820 
821  ast_verb(1, "UDPTL (%s): packet from %s (seq %d, len %d)\n",
822  LOG_TAG(udptl), ast_sockaddr_stringify(&addr), seq_no, res);
823  }
824  if (udptl_rx_packet(udptl, buf, res) < 1) {
825  return &ast_null_frame;
826  }
827 
828  return &udptl->f[0];
829 }
int fd
Definition: udptl.c:157
int nat
Definition: udptl.c:162
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
char * tag
Definition: udptl.c:170
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
static int udptl_debug_test_addr(const struct ast_sockaddr *addr)
Definition: udptl.c:258
Socket address structure.
Definition: netsock2.h:97
#define ast_verb(level,...)
Definition: logger.h:463
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.
Definition: netsock2.h:127
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
struct ast_sockaddr them
Definition: udptl.c:165
#define LOG_TAG(u)
Definition: udptl.c:125
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
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.
Definition: netsock2.c:606
struct ast_frame f[16]
Definition: udptl.c:159
struct ast_frame ast_null_frame
Definition: main/frame.c:79
unsigned char rawdata[8192+AST_FRIENDLY_OFFSET]
Definition: udptl.c:160
static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
Definition: udptl.c:381

◆ ast_udptl_set_callback()

void ast_udptl_set_callback ( struct ast_udptl udptl,
ast_udptl_callback  callback 
)

Definition at line 740 of file udptl.c.

References ast_udptl::callback.

741 {
742  udptl->callback = callback;
743 }
ast_udptl_callback callback
Definition: udptl.c:171

◆ ast_udptl_set_data()

void ast_udptl_set_data ( struct ast_udptl udptl,
void *  data 
)

Definition at line 735 of file udptl.c.

References ast_udptl::data.

736 {
737  udptl->data = data;
738 }
void * data
Definition: udptl.c:169

◆ ast_udptl_set_error_correction_scheme()

void ast_udptl_set_error_correction_scheme ( struct ast_udptl udptl,
enum ast_t38_ec_modes  ec 
)

Definition at line 945 of file udptl.c.

References ast_udptl::error_correction_entries, ast_udptl::error_correction_scheme, ast_udptl::error_correction_span, ast_udptl::far_max_ifp, ast_udptl::local_max_datagram, UDPTL_ERROR_CORRECTION_FEC, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by process_sdp(), process_sdp_a_image(), set_t38_capabilities(), t38_initialize_session(), and t38_interpret_sdp().

946 {
947  udptl->error_correction_scheme = ec;
948  switch (ec) {
951  if (udptl->error_correction_entries == 0) {
952  udptl->error_correction_entries = 3;
953  }
954  if (udptl->error_correction_span == 0) {
955  udptl->error_correction_span = 3;
956  }
957  break;
960  if (udptl->error_correction_entries == 0) {
961  udptl->error_correction_entries = 3;
962  }
963  break;
964  default:
965  /* nothing to do */
966  break;
967  };
968  /* reset calculated values so they'll be computed again */
969  udptl->local_max_datagram = -1;
970  udptl->far_max_ifp = -1;
971 }
unsigned int error_correction_span
Definition: udptl.c:186
int local_max_datagram
Definition: udptl.c:197
unsigned int error_correction_entries
Definition: udptl.c:181
int far_max_ifp
Definition: udptl.c:205
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:176

◆ ast_udptl_set_far_max_datagram()

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 value.

Definition at line 997 of file udptl.c.

References DEFAULT_FAX_MAX_DATAGRAM, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, and FAX_MAX_DATAGRAM_LIMIT.

Referenced by configure_local_rtp(), onModeChanged(), process_sdp(), process_sdp_a_image(), t38_initialize_session(), and t38_interpret_sdp().

998 {
999  if (!max_datagram || (max_datagram > FAX_MAX_DATAGRAM_LIMIT)) {
1001  } else {
1002  udptl->far_max_datagram = max_datagram;
1003  }
1004  /* reset calculated values so they'll be computed again */
1005  udptl->far_max_ifp = -1;
1006 }
int far_max_datagram
Definition: udptl.c:191
int far_max_ifp
Definition: udptl.c:205
#define FAX_MAX_DATAGRAM_LIMIT
Definition: udptl.c:135
#define DEFAULT_FAX_MAX_DATAGRAM
Definition: udptl.c:134

◆ ast_udptl_set_local_max_ifp()

void ast_udptl_set_local_max_ifp ( struct ast_udptl udptl,
unsigned int  max_ifp 
)

Definition at line 973 of file udptl.c.

References ast_udptl::local_max_datagram, and ast_udptl::local_max_ifp.

Referenced by interpret_t38_parameters(), and t38_interpret_parameters().

974 {
975  /* make sure max_ifp is a positive value since a cast will take place when
976  * when setting local_max_ifp */
977  if ((signed int) max_ifp > 0) {
978  udptl->local_max_ifp = max_ifp;
979  /* reset calculated values so they'll be computed again */
980  udptl->local_max_datagram = -1;
981  }
982 }
int local_max_datagram
Definition: udptl.c:197
int local_max_ifp
Definition: udptl.c:211

◆ ast_udptl_set_peer()

void ast_udptl_set_peer ( struct ast_udptl udptl,
const struct ast_sockaddr them 
)

Definition at line 1130 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::them.

Referenced by apply_negotiated_sdp_stream(), process_sdp(), and setup_udptl_connection().

1131 {
1132  ast_sockaddr_copy(&udptl->them, them);
1133 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
struct ast_sockaddr them
Definition: udptl.c:165

◆ ast_udptl_set_tag()

void ast_udptl_set_tag ( struct ast_udptl udptl,
const char *  format,
  ... 
)

Associates a character string 'tag' with a UDPTL session.

Parameters
udptlThe UDPTL session.
formatprintf-style format string used to construct the tag

This function formats a tag for the specified UDPTL session, so that any log messages generated by the UDPTL stack related to that session will include the tag and the reader of the messages will be able to identify which endpoint caused them to be generated.

Return values
none

Definition at line 1112 of file udptl.c.

References ast_free, ast_vasprintf, NULL, and ast_udptl::tag.

Referenced by change_t38_state(), setup_udptl_connection(), and t38_change_state().

1113 {
1114  va_list ap;
1115 
1116  ast_free(udptl->tag);
1117  udptl->tag = NULL;
1118  va_start(ap, format);
1119  if (ast_vasprintf(&udptl->tag, format, ap) == -1) {
1120  udptl->tag = NULL;
1121  }
1122  va_end(ap);
1123 }
char * tag
Definition: udptl.c:170
#define ast_vasprintf(ret, fmt, ap)
A wrapper for vasprintf()
Definition: astmm.h:280
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182
static snd_pcm_format_t format
Definition: chan_alsa.c:102

◆ ast_udptl_setnat()

void ast_udptl_setnat ( struct ast_udptl udptl,
int  nat 
)

Definition at line 745 of file udptl.c.

References ast_udptl::nat, and nat.

Referenced by do_setnat(), initialize_udptl(), and t38_initialize_session().

746 {
747  udptl->nat = nat;
748 }
int nat
Definition: udptl.c:162
static int nat
Definition: chan_mgcp.c:168

◆ ast_udptl_setqos()

int ast_udptl_setqos ( struct ast_udptl udptl,
unsigned int  tos,
unsigned int  cos 
)

Definition at line 1125 of file udptl.c.

References ast_set_qos(), and ast_udptl::fd.

Referenced by initialize_udptl().

1126 {
1127  return ast_set_qos(udptl->fd, tos, cos, "UDPTL");
1128 }
int fd
Definition: udptl.c:157
unsigned int cos
Definition: chan_iax2.c:352
unsigned int tos
Definition: chan_iax2.c:351
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621

◆ ast_udptl_stop()

void ast_udptl_stop ( struct ast_udptl udptl)

Definition at line 1145 of file udptl.c.

References ast_sockaddr_setnull(), and ast_udptl::them.

Referenced by process_sdp(), and stop_media_flows().

1146 {
1147  ast_sockaddr_setnull(&udptl->them);
1148 }
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:140
struct ast_sockaddr them
Definition: udptl.c:165

◆ ast_udptl_write()

int ast_udptl_write ( struct ast_udptl s,
struct ast_frame f 
)

Definition at line 1161 of file udptl.c.

References AST_FRAME_MODEM, ast_log, AST_MODEM_T38, ast_sendto(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verb, buf, ast_frame::data, ast_frame::datalen, DEFAULT_FAX_MAX_DATAGRAM, errno, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, ast_udptl::fd, ast_frame::frametype, ast_frame_subclass::integer, ast_sockaddr::len, LOG_NOTICE, LOG_TAG, LOG_WARNING, ast_frame::ptr, seq, ast_frame::subclass, ast_udptl::them, ast_udptl::tx_seq_no, udptl_build_packet(), and udptl_debug_test_addr().

Referenced by media_session_udptl_write_callback(), ooh323_write(), and sip_write().

1162 {
1163  unsigned int seq;
1164  unsigned int len = f->datalen;
1165  /* if no max datagram size is provided, use default value */
1166  const int bufsize = (s->far_max_datagram > 0) ? s->far_max_datagram : DEFAULT_FAX_MAX_DATAGRAM;
1167  uint8_t buf[bufsize];
1168 
1169  memset(buf, 0, sizeof(buf));
1170 
1171  /* If we have no peer, return immediately */
1172  if (ast_sockaddr_isnull(&s->them)) {
1173  return 0;
1174  }
1175 
1176  /* If there is no data length, return immediately */
1177  if (f->datalen == 0)
1178  return 0;
1179 
1180  if ((f->frametype != AST_FRAME_MODEM) ||
1181  (f->subclass.integer != AST_MODEM_T38)) {
1182  ast_log(LOG_WARNING, "UDPTL (%s): UDPTL can only send T.38 data.\n",
1183  LOG_TAG(s));
1184  return -1;
1185  }
1186 
1187  if (len > s->far_max_ifp) {
1189  "UDPTL (%s): UDPTL asked to send %u bytes of IFP when far end only prepared to accept %d bytes; data loss will occur."
1190  "You may need to override the T38FaxMaxDatagram value for this endpoint in the channel driver configuration.\n",
1191  LOG_TAG(s), len, s->far_max_ifp);
1192  len = s->far_max_ifp;
1193  }
1194 
1195  /* Save seq_no for debug output because udptl_build_packet increments it */
1196  seq = s->tx_seq_no & 0xFFFF;
1197 
1198  /* Cook up the UDPTL packet, with the relevant EC info. */
1199  len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, len);
1200 
1201  if ((signed int) len > 0 && !ast_sockaddr_isnull(&s->them)) {
1202  if (ast_sendto(s->fd, buf, len, 0, &s->them) < 0) {
1203  ast_log(LOG_NOTICE, "UDPTL (%s): Transmission error to %s: %s\n",
1204  LOG_TAG(s), ast_sockaddr_stringify(&s->them), strerror(errno));
1205  }
1206  if (udptl_debug_test_addr(&s->them)) {
1207  ast_verb(1, "UDPTL (%s): packet to %s (seq %u, len %u)\n",
1208  LOG_TAG(s), ast_sockaddr_stringify(&s->them), seq, len);
1209  }
1210  }
1211 
1212  return 0;
1213 }
int fd
Definition: udptl.c:157
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.
Definition: netsock2.c:614
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define LOG_WARNING
Definition: logger.h:274
static int udptl_debug_test_addr(const struct ast_sockaddr *addr)
Definition: udptl.c:258
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_frame_subclass subclass
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.
Definition: netsock2.h:127
#define ast_log
Definition: astobj2.c:42
int far_max_datagram
Definition: udptl.c:191
struct ast_sockaddr them
Definition: udptl.c:165
unsigned int tx_seq_no
Definition: udptl.c:213
#define LOG_TAG(u)
Definition: udptl.c:125
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int errno
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define LOG_NOTICE
Definition: logger.h:263
int far_max_ifp
Definition: udptl.c:205
static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, unsigned int buflen, uint8_t *ifp, unsigned int ifp_len)
Definition: udptl.c:621
static volatile unsigned int seq
Definition: app_sms.c:120
#define AST_MODEM_T38
union ast_frame::@263 data
enum ast_frame_type frametype
#define DEFAULT_FAX_MAX_DATAGRAM
Definition: udptl.c:134

◆ calculate_far_max_ifp()

static void calculate_far_max_ifp ( struct ast_udptl udptl)
static

Definition at line 872 of file udptl.c.

References ast_log, ast_udptl::error_correction_entries, ast_udptl::error_correction_scheme, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, LOG_TAG, LOG_WARNING, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by ast_udptl_get_far_max_ifp().

873 {
874  unsigned new_max = 0;
875 
876  if (udptl->far_max_datagram == -1) {
877  ast_log(LOG_WARNING, "UDPTL (%s): Cannot calculate far_max_ifp before far_max_datagram has been set.\n",
878  LOG_TAG(udptl));
879  udptl->far_max_ifp = -1;
880  return;
881  }
882 
883  /* the goal here is to supply the local endpoint (application
884  * or bridged channel) a maximum IFP value that will allow it
885  * to effectively and efficiently transfer image data at its
886  * selected bit rate, taking into account the selected error
887  * correction mode, but without overrunning the far endpoint's
888  * datagram buffer. this is complicated by the fact that some
889  * far endpoints send us bogus (small) max datagram values,
890  * which would result in either buffer overrun or no error
891  * correction. we try to accomodate those, but if the supplied
892  * value is too small to do so, we'll emit warning messages and
893  * the user will have to use configuration options to override
894  * the max datagram value supplied by the far endpoint.
895  */
896  switch (udptl->error_correction_scheme) {
898  /* need room for sequence number, length indicator, redundancy
899  * indicator and following length indicator
900  */
901  new_max = udptl->far_max_datagram - 5;
902  break;
904  /* for this case, we'd like to send as many error correction entries
905  * as possible (up to the number we're configured for), but we'll settle
906  * for sending fewer if the configured number would cause the
907  * calculated max IFP to be too small for effective operation
908  *
909  * need room for sequence number, length indicators and the
910  * configured number of redundant packets
911  *
912  * note: we purposely don't allow error_correction_entries to drop to
913  * zero in this loop; we'd rather send smaller IFPs (and thus reduce
914  * the image data transfer rate) than sacrifice redundancy completely
915  */
916  for (;;) {
917  new_max = (udptl->far_max_datagram - 8) / (udptl->error_correction_entries + 1);
918 
919  if ((new_max < 80) && (udptl->error_correction_entries > 1)) {
920  /* the max ifp is not large enough, subtract an
921  * error correction entry and calculate again
922  * */
923  --udptl->error_correction_entries;
924  } else {
925  break;
926  }
927  }
928  break;
930  /* need room for sequence number, length indicators and a
931  * a single IFP of the maximum size expected
932  */
933  new_max = (udptl->far_max_datagram - 10) / 2;
934  break;
935  }
936  /* subtract 5% of space for insurance */
937  udptl->far_max_ifp = new_max * 0.95;
938 }
#define LOG_WARNING
Definition: logger.h:274
unsigned int error_correction_entries
Definition: udptl.c:181
#define ast_log
Definition: astobj2.c:42
int far_max_datagram
Definition: udptl.c:191
#define LOG_TAG(u)
Definition: udptl.c:125
int far_max_ifp
Definition: udptl.c:205
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:176

◆ calculate_local_max_datagram()

static void calculate_local_max_datagram ( struct ast_udptl udptl)
static

Definition at line 831 of file udptl.c.

References ast_log, ast_udptl::error_correction_scheme, LOCAL_FAX_MAX_DATAGRAM, ast_udptl::local_max_datagram, ast_udptl::local_max_ifp, LOG_TAG, LOG_WARNING, MIN, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by ast_udptl_get_local_max_datagram().

832 {
833  unsigned int new_max = 0;
834 
835  if (udptl->local_max_ifp == -1) {
836  ast_log(LOG_WARNING, "UDPTL (%s): Cannot calculate local_max_datagram before local_max_ifp has been set.\n",
837  LOG_TAG(udptl));
838  udptl->local_max_datagram = -1;
839  return;
840  }
841 
842  /* calculate the amount of space required to receive an IFP
843  * of the maximum size supported by the application/endpoint
844  * that we are delivering them to (local endpoint), and add
845  * the amount of space required to support the selected
846  * error correction mode
847  */
848  switch (udptl->error_correction_scheme) {
850  /* need room for sequence number, length indicator, redundancy
851  * indicator and following length indicator
852  */
853  new_max = 5 + udptl->local_max_ifp;
854  break;
856  /* need room for sequence number, length indicators, plus
857  * room for up to 3 redundancy packets
858  */
859  new_max = 5 + udptl->local_max_ifp + 2 + (3 * udptl->local_max_ifp);
860  break;
862  /* need room for sequence number, length indicators and a
863  * a single IFP of the maximum size expected
864  */
865  new_max = 5 + udptl->local_max_ifp + 4 + udptl->local_max_ifp;
866  break;
867  }
868  /* add 5% extra space for insurance, but no larger than LOCAL_FAX_MAX_DATAGRAM */
869  udptl->local_max_datagram = MIN(new_max * 1.05, LOCAL_FAX_MAX_DATAGRAM);
870 }
int local_max_datagram
Definition: udptl.c:197
#define LOG_WARNING
Definition: logger.h:274
#define MIN(a, b)
Definition: utils.h:226
#define ast_log
Definition: astobj2.c:42
#define LOCAL_FAX_MAX_DATAGRAM
Definition: udptl.c:133
#define LOG_TAG(u)
Definition: udptl.c:125
int local_max_ifp
Definition: udptl.c:211
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:176

◆ CONFIG_INFO_CORE()

CONFIG_INFO_CORE ( "udptl"  ,
cfg_info  ,
globals  ,
udptl_snapshot_alloc  ,
files = ACO_FILES(&udptl_conf),
pre_apply_config = udptl_pre_apply_config 
)

◆ decode_length()

static int decode_length ( uint8_t *  buf,
unsigned int  limit,
unsigned int *  len,
unsigned int *  pvalue 
)
static

Definition at line 274 of file udptl.c.

References ast_debug, and ast_sockaddr::len.

Referenced by decode_open_type(), and udptl_rx_packet().

275 {
276  if (*len >= limit)
277  return -1;
278  if ((buf[*len] & 0x80) == 0) {
279  *pvalue = buf[*len];
280  (*len)++;
281  return 0;
282  }
283  if ((buf[*len] & 0x40) == 0) {
284  if (*len == limit - 1)
285  return -1;
286  *pvalue = (buf[*len] & 0x3F) << 8;
287  (*len)++;
288  *pvalue |= buf[*len];
289  (*len)++;
290  return 0;
291  }
292  *pvalue = (buf[*len] & 0x3F) << 14;
293  (*len)++;
294  /* We have a fragment. Currently we don't process fragments. */
295  ast_debug(1, "UDPTL packet with length greater than 16K received, decoding will fail\n");
296  return 1;
297 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ decode_open_type()

static int decode_open_type ( uint8_t *  buf,
unsigned int  limit,
unsigned int *  len,
const uint8_t **  p_object,
unsigned int *  p_num_octets 
)
static

Definition at line 300 of file udptl.c.

References decode_length(), and ast_sockaddr::len.

Referenced by udptl_rx_packet().

301 {
302  unsigned int octet_cnt = 0;
303 
304  if (decode_length(buf, limit, len, &octet_cnt) != 0)
305  return -1;
306 
307  /* Make sure the buffer contains at least the number of bits requested */
308  if ((*len + octet_cnt) > limit) {
309  return -1;
310  }
311 
312  *p_num_octets = octet_cnt;
313  *p_object = &buf[*len];
314  *len += octet_cnt;
315 
316  return 0;
317 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
Definition: udptl.c:274
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ encode_length()

static unsigned int encode_length ( uint8_t *  buf,
unsigned int *  len,
unsigned int  value 
)
static

Definition at line 320 of file udptl.c.

References ast_sockaddr::len, and value.

Referenced by encode_open_type(), and udptl_build_packet().

321 {
322  unsigned int multiplier;
323 
324  if (value < 0x80) {
325  /* 1 octet */
326  buf[*len] = value;
327  (*len)++;
328  return value;
329  }
330  if (value < 0x4000) {
331  /* 2 octets */
332  /* Set the first bit of the first octet */
333  buf[*len] = ((0x8000 | value) >> 8) & 0xFF;
334  (*len)++;
335  buf[*len] = value & 0xFF;
336  (*len)++;
337  return value;
338  }
339  /* Fragmentation */
340  multiplier = (value < 0x10000) ? (value >> 14) : 4;
341  /* Set the first 2 bits of the octet */
342  buf[*len] = 0xC0 | multiplier;
343  (*len)++;
344  return multiplier << 14;
345 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
int value
Definition: syslog.c:37
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ encode_open_type()

static int encode_open_type ( const struct ast_udptl udptl,
uint8_t *  buf,
unsigned int  buflen,
unsigned int *  len,
const uint8_t *  data,
unsigned int  num_octets 
)
static

Definition at line 348 of file udptl.c.

References ast_log, encode_length(), LOG_ERROR, and LOG_TAG.

Referenced by udptl_build_packet().

350 {
351  unsigned int enclen;
352  unsigned int octet_idx;
353  uint8_t zero_byte;
354 
355  /* If open type is of zero length, add a single zero byte (10.1) */
356  if (num_octets == 0) {
357  zero_byte = 0;
358  data = &zero_byte;
359  num_octets = 1;
360  }
361  /* Encode the open type */
362  for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
363  enclen = encode_length(buf, len, num_octets);
364  if (enclen + *len > buflen) {
365  ast_log(LOG_ERROR, "UDPTL (%s): Buffer overflow detected (%u + %u > %u)\n",
366  LOG_TAG(udptl), enclen, *len, buflen);
367  return -1;
368  }
369  if (enclen > 0) {
370  memcpy(&buf[*len], &data[octet_idx], enclen);
371  *len += enclen;
372  }
373  if (enclen >= num_octets)
374  break;
375  }
376 
377  return 0;
378 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
Definition: udptl.c:320
#define ast_log
Definition: astobj2.c:42
#define LOG_TAG(u)
Definition: udptl.c:125
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)

◆ handle_cli_show_config()

static char* handle_cli_show_config ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1260 of file udptl.c.

References ao2_cleanup, ao2_global_obj_ref, ast_cli(), AST_CLI_YESNO, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, globals, NULL, RAII_VAR, and ast_cli_entry::usage.

1261 {
1262  RAII_VAR(struct udptl_config *, cfg, NULL, ao2_cleanup);
1263 
1264  switch (cmd) {
1265  case CLI_INIT:
1266  e->command = "udptl show config";
1267  e->usage =
1268  "Usage: udptl show config\n"
1269  " Display UDPTL configuration options\n";
1270  return NULL;
1271  case CLI_GENERATE:
1272  return NULL;
1273  }
1274 
1275  if (!(cfg = ao2_global_obj_ref(globals))) {
1276  return CLI_FAILURE;
1277  }
1278 
1279  ast_cli(a->fd, "UDPTL Global options\n");
1280  ast_cli(a->fd, "--------------------\n");
1281  ast_cli(a->fd, "udptlstart: %u\n", cfg->general->start);
1282  ast_cli(a->fd, "udptlend: %u\n", cfg->general->end);
1283  ast_cli(a->fd, "udptlfecentries: %u\n", cfg->general->fecentries);
1284  ast_cli(a->fd, "udptlfecspan: %u\n", cfg->general->fecspan);
1285  ast_cli(a->fd, "use_even_ports: %s\n", AST_CLI_YESNO(cfg->general->use_even_ports));
1286  ast_cli(a->fd, "udptlchecksums: %s\n", AST_CLI_YESNO(!cfg->general->nochecksums));
1287 
1288  return CLI_SUCCESS;
1289 }
Definition: cli.h:152
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
const int fd
Definition: cli.h:159
static struct console_pvt globals
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71

◆ handle_cli_udptl_set_debug()

static char* handle_cli_udptl_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1215 of file udptl.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_free, ast_sockaddr_copy(), ast_sockaddr_resolve(), ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, udptldebug, udptldebugaddr, and ast_cli_entry::usage.

1216 {
1217  switch (cmd) {
1218  case CLI_INIT:
1219  e->command = "udptl set debug {on|off|ip}";
1220  e->usage =
1221  "Usage: udptl set debug {on|off|ip host[:port]}\n"
1222  " Enable or disable dumping of UDPTL packets.\n"
1223  " If ip is specified, limit the dumped packets to those to and from\n"
1224  " the specified 'host' with optional port.\n";
1225  return NULL;
1226  case CLI_GENERATE:
1227  return NULL;
1228  }
1229 
1230  if (a->argc < 4 || a->argc > 5)
1231  return CLI_SHOWUSAGE;
1232 
1233  if (a->argc == 4) {
1234  if (!strncasecmp(a->argv[3], "on", 2)) {
1235  udptldebug = 1;
1236  memset(&udptldebugaddr, 0, sizeof(udptldebugaddr));
1237  ast_cli(a->fd, "UDPTL Debugging Enabled\n");
1238  } else if (!strncasecmp(a->argv[3], "off", 3)) {
1239  udptldebug = 0;
1240  ast_cli(a->fd, "UDPTL Debugging Disabled\n");
1241  } else {
1242  return CLI_SHOWUSAGE;
1243  }
1244  } else {
1245  struct ast_sockaddr *addrs;
1246  if (strncasecmp(a->argv[3], "ip", 2))
1247  return CLI_SHOWUSAGE;
1248  if (!ast_sockaddr_resolve(&addrs, a->argv[4], 0, 0)) {
1249  return CLI_SHOWUSAGE;
1250  }
1251  ast_sockaddr_copy(&udptldebugaddr, &addrs[0]);
1252  ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_sockaddr_stringify(&udptldebugaddr));
1253  udptldebug = 1;
1254  ast_free(addrs);
1255  }
1256 
1257  return CLI_SUCCESS;
1258 }
static struct ast_sockaddr udptldebugaddr
Definition: udptl.c:131
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
Socket address structure.
Definition: netsock2.h:97
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
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.
Definition: netsock2.c:280
static int udptldebug
Definition: udptl.c:130

◆ load_module()

static int load_module ( void  )
static

Definition at line 1396 of file udptl.c.

References __ast_udptl_reload(), __stringify, ACO_EXACT, aco_info_init(), aco_option_register, aco_option_register_custom, ARRAY_LEN, ast_cli_register_multiple, AST_MODFLAG_GLOBAL_SYMBOLS, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CORE, AST_MODULE_INFO(), AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, DEFAULT_UDPTLEND, DEFAULT_UDPTLSTART, end, FLDSET, MAX_FEC_ENTRIES, MAX_FEC_SPAN, NULL, OPT_BOOL_T, OPT_UINT_T, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_RANGE_DEFAULTS, reload(), reload_module(), removed_options_handler(), and unload_module().

1397 {
1398  if (aco_info_init(&cfg_info)) {
1399  return AST_MODULE_LOAD_FAILURE;
1400  }
1401 
1404  FLDSET(struct udptl_global_options, start), DEFAULT_UDPTLSTART, 1024, 65535);
1405 
1408  FLDSET(struct udptl_global_options, end), DEFAULT_UDPTLEND, 1024, 65535);
1409 
1410  aco_option_register(&cfg_info, "udptlfecentries", ACO_EXACT, general_options, NULL,
1412  FLDSET(struct udptl_global_options, fecentries), 1, MAX_FEC_ENTRIES);
1413 
1414  aco_option_register(&cfg_info, "udptlfecspan", ACO_EXACT, general_options, NULL,
1416  FLDSET(struct udptl_global_options, fecspan), 1, MAX_FEC_SPAN);
1417 
1418  aco_option_register(&cfg_info, "udptlchecksums", ACO_EXACT, general_options, "yes",
1419  OPT_BOOL_T, 0, FLDSET(struct udptl_global_options, nochecksums));
1420 
1421  aco_option_register(&cfg_info, "use_even_ports", ACO_EXACT, general_options, "no",
1422  OPT_BOOL_T, 1, FLDSET(struct udptl_global_options, use_even_ports));
1423 
1425  aco_option_register_custom(&cfg_info, "t38faxmaxdatagram", ACO_EXACT, general_options, NULL, removed_options_handler, 0);
1426 
1427  __ast_udptl_reload(0);
1428 
1430 
1431  return AST_MODULE_LOAD_SUCCESS;
1432 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
static void __ast_udptl_reload(int reload)
Definition: udptl.c:1327
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define DEFAULT_UDPTLSTART
Definition: udptl.c:127
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
static struct aco_type * general_options[]
Definition: udptl.c:246
static int removed_options_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: udptl.c:1317
#define __stringify(x)
Definition: asterisk.h:214
#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.
Type for default option handler for unsigned integers.
Type for default option handler for bools (ast_true/ast_false)
Module could not be loaded properly.
Definition: module.h:102
#define DEFAULT_UDPTLEND
Definition: udptl.c:128
#define MAX_FEC_SPAN
Definition: udptl.c:137
#define MAX_FEC_ENTRIES
Definition: udptl.c:136
static struct ast_cli_entry cli_udptl[]
Definition: udptl.c:1291

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1376 of file udptl.c.

References __ast_udptl_reload().

Referenced by load_module().

1377 {
1378  __ast_udptl_reload(1);
1379 
1380  return 0;
1381 }
static void __ast_udptl_reload(int reload)
Definition: udptl.c:1327

◆ removed_options_handler()

static int removed_options_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 1317 of file udptl.c.

References ast_log, LOG_WARNING, and ast_variable::name.

Referenced by load_module().

1318 {
1319  if (!strcasecmp(var->name, "t38faxudpec")) {
1320  ast_log(LOG_WARNING, "t38faxudpec in udptl.conf is no longer supported; use the t38pt_udptl configuration option in sip.conf instead.\n");
1321  } else if (!strcasecmp(var->name, "t38faxmaxdatagram")) {
1322  ast_log(LOG_WARNING, "t38faxmaxdatagram in udptl.conf is no longer supported; value is now supplied by T.38 applications.\n");
1323  }
1324  return 0;
1325 }
#define LOG_WARNING
Definition: logger.h:274
#define ast_log
Definition: astobj2.c:42

◆ udptl_build_packet()

static int udptl_build_packet ( struct ast_udptl s,
uint8_t *  buf,
unsigned int  buflen,
uint8_t *  ifp,
unsigned int  ifp_len 
)
static

Definition at line 621 of file udptl.c.

References ast_debug, udptl_fec_tx_buffer_t::buf, udptl_fec_tx_buffer_t::buf_len, encode_length(), encode_open_type(), ast_udptl::error_correction_entries, ast_udptl::error_correction_scheme, ast_udptl::error_correction_span, ast_sockaddr::len, LOCAL_FAX_MAX_DATAGRAM, LOG_TAG, seq, ast_udptl::tx, ast_udptl::tx_seq_no, UDPTL_BUF_MASK, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by ast_udptl_write().

622 {
623  uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2] = { 0, };
624  int i;
625  int j;
626  int seq;
627  int entry;
628  int entries;
629  int span;
630  int m;
631  unsigned int len;
632  int limit;
633  int high_tide;
634 
635  seq = s->tx_seq_no & 0xFFFF;
636 
637  /* Map the sequence number to an entry in the circular buffer */
638  entry = seq & UDPTL_BUF_MASK;
639 
640  /* We save the message in a circular buffer, for generating FEC or
641  redundancy sets later on. */
642  s->tx[entry].buf_len = ifp_len;
643  memcpy(s->tx[entry].buf, ifp, ifp_len);
644 
645  /* Build the UDPTLPacket */
646 
647  len = 0;
648  /* Encode the sequence number */
649  buf[len++] = (seq >> 8) & 0xFF;
650  buf[len++] = seq & 0xFF;
651 
652  /* Encode the primary IFP packet */
653  if (encode_open_type(s, buf, buflen, &len, ifp, ifp_len) < 0)
654  return -1;
655 
656  /* Encode the appropriate type of error recovery information */
657  switch (s->error_correction_scheme)
658  {
660  /* Encode the error recovery type */
661  buf[len++] = 0x00;
662  /* The number of entries will always be zero, so it is pointless allowing
663  for the fragmented case here. */
664  encode_length(buf, &len, 0);
665  break;
667  /* Encode the error recovery type */
668  buf[len++] = 0x00;
670  entries = s->error_correction_entries;
671  else
672  entries = s->tx_seq_no;
673  /* The number of entries will always be small, so it is pointless allowing
674  for the fragmented case here. */
675  encode_length(buf, &len, entries);
676  /* Encode the elements */
677  for (i = 0; i < entries; i++) {
678  j = (entry - i - 1) & UDPTL_BUF_MASK;
679  if (encode_open_type(s, buf, buflen, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) {
680  ast_debug(1, "UDPTL (%s): Encoding failed at i=%d, j=%d\n",
681  LOG_TAG(s), i, j);
682  return -1;
683  }
684  }
685  break;
687  span = s->error_correction_span;
688  entries = s->error_correction_entries;
689  if (seq < s->error_correction_span*s->error_correction_entries) {
690  /* In the initial stages, wind up the FEC smoothly */
691  entries = seq/s->error_correction_span;
692  if (seq < s->error_correction_span)
693  span = 0;
694  }
695  /* Encode the error recovery type */
696  buf[len++] = 0x80;
697  /* Span is defined as an inconstrained integer, which it dumb. It will only
698  ever be a small value. Treat it as such. */
699  buf[len++] = 1;
700  buf[len++] = span;
701  /* The number of entries is defined as a length, but will only ever be a small
702  value. Treat it as such. */
703  buf[len++] = entries;
704  for (m = 0; m < entries; m++) {
705  /* Make an XOR'ed entry the maximum length */
706  limit = (entry + m) & UDPTL_BUF_MASK;
707  high_tide = 0;
708  for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
709  if (high_tide < s->tx[i].buf_len) {
710  for (j = 0; j < high_tide; j++)
711  fec[j] ^= s->tx[i].buf[j];
712  for ( ; j < s->tx[i].buf_len; j++)
713  fec[j] = s->tx[i].buf[j];
714  high_tide = s->tx[i].buf_len;
715  } else {
716  for (j = 0; j < s->tx[i].buf_len; j++)
717  fec[j] ^= s->tx[i].buf[j];
718  }
719  }
720  if (encode_open_type(s, buf, buflen, &len, fec, high_tide) < 0)
721  return -1;
722  }
723  break;
724  }
725 
726  s->tx_seq_no++;
727  return len;
728 }
unsigned int error_correction_span
Definition: udptl.c:186
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
unsigned int error_correction_entries
Definition: udptl.c:181
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:143
static int encode_open_type(const struct ast_udptl *udptl, uint8_t *buf, unsigned int buflen, unsigned int *len, const uint8_t *data, unsigned int num_octets)
Definition: udptl.c:348
static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
Definition: udptl.c:320
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define LOCAL_FAX_MAX_DATAGRAM
Definition: udptl.c:133
unsigned int tx_seq_no
Definition: udptl.c:213
#define LOG_TAG(u)
Definition: udptl.c:125
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static volatile unsigned int seq
Definition: app_sms.c:120
Definition: search.h:40
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK+1]
Definition: udptl.c:216
#define UDPTL_BUF_MASK
Definition: udptl.c:139
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:176

◆ udptl_config_destructor()

static void udptl_config_destructor ( void *  obj)
static

Definition at line 1296 of file udptl.c.

References ao2_cleanup, and udptl_config::general.

Referenced by udptl_snapshot_alloc().

1297 {
1298  struct udptl_config *cfg = obj;
1299  ao2_cleanup(cfg->general);
1300 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct udptl_global_options * general
Definition: udptl.c:232

◆ udptl_debug_test_addr()

static int udptl_debug_test_addr ( const struct ast_sockaddr addr)
inlinestatic

Definition at line 258 of file udptl.c.

References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), ast_sockaddr_port, udptldebug, and udptldebugaddr.

Referenced by ast_udptl_read(), and ast_udptl_write().

259 {
260  if (udptldebug == 0)
261  return 0;
262 
264  return 1;
265  }
266 
268  return !ast_sockaddr_cmp(&udptldebugaddr, addr);
269  } else {
270  return !ast_sockaddr_cmp_addr(&udptldebugaddr, addr);
271  }
272 }
static struct ast_sockaddr udptldebugaddr
Definition: udptl.c:131
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
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.
Definition: netsock2.h:127
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
static int udptldebug
Definition: udptl.c:130

◆ udptl_pre_apply_config()

static int udptl_pre_apply_config ( void  )
static

Definition at line 1344 of file udptl.c.

References __stringify, aco_pending_config(), ast_log, DEFAULT_UDPTLEND, DEFAULT_UDPTLSTART, udptl_global_options::end, udptl_config::general, LOG_NOTICE, LOG_WARNING, udptl_global_options::nochecksums, udptl_global_options::start, and udptl_global_options::use_even_ports.

1344  {
1345  struct udptl_config *cfg = aco_pending_config(&cfg_info);
1346 
1347  if (!cfg->general) {
1348  return -1;
1349  }
1350 
1351 #ifndef SO_NO_CHECK
1352  if (cfg->general->nochecksums) {
1353  ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
1354  cfg->general->nochecksums = 0;
1355  }
1356 #endif
1357 
1358  /* Fix up any global config values that we can handle before replacing the config */
1359  if (cfg->general->use_even_ports && (cfg->general->start & 1)) {
1360  ++cfg->general->start;
1361  ast_log(LOG_NOTICE, "Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %u\n", cfg->general->start);
1362  }
1363  if (cfg->general->start > cfg->general->end) {
1364  ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to %s-%s.\n", __stringify(DEFAULT_UDPTLSTART), __stringify(DEFAULT_UDPTLEND));
1366  cfg->general->end = DEFAULT_UDPTLEND;
1367  }
1368  if (cfg->general->use_even_ports && (cfg->general->end & 1)) {
1369  --cfg->general->end;
1370  ast_log(LOG_NOTICE, "Odd numbered udptlend specified but use_even_ports enabled. udptlend is now %u\n", cfg->general->end);
1371  }
1372 
1373  return 0;
1374 }
#define LOG_WARNING
Definition: logger.h:274
#define DEFAULT_UDPTLSTART
Definition: udptl.c:127
#define ast_log
Definition: astobj2.c:42
#define __stringify(x)
Definition: asterisk.h:214
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
unsigned int end
Definition: udptl.c:222
unsigned int nochecksums
Definition: udptl.c:225
#define LOG_NOTICE
Definition: logger.h:263
unsigned int use_even_ports
Definition: udptl.c:226
#define DEFAULT_UDPTLEND
Definition: udptl.c:128
struct udptl_global_options * general
Definition: udptl.c:232
unsigned int start
Definition: udptl.c:221

◆ udptl_rx_packet()

static int udptl_rx_packet ( struct ast_udptl s,
uint8_t *  buf,
unsigned int  len 
)
static

Definition at line 381 of file udptl.c.

References ARRAY_LEN, ast_debug, AST_FRAME_MODEM, AST_LIST_NEXT, AST_MODEM_T38, udptl_fec_rx_buffer_t::buf, udptl_fec_rx_buffer_t::buf_len, ast_frame::data, ast_frame::datalen, decode_length(), decode_open_type(), ast_udptl::f, udptl_fec_rx_buffer_t::fec, udptl_fec_rx_buffer_t::fec_entries, udptl_fec_rx_buffer_t::fec_len, udptl_fec_rx_buffer_t::fec_span, ast_frame::frametype, ast_frame_subclass::integer, LOCAL_FAX_MAX_DATAGRAM, ast_frame::mallocd, MAX_FEC_ENTRIES, NULL, ast_frame::offset, ast_frame::ptr, ast_udptl::rx, ast_udptl::rx_seq_no, ast_frame::seqno, ast_frame::src, ast_frame::subclass, TRUE, and UDPTL_BUF_MASK.

Referenced by ast_udptl_read().

382 {
383  int stat1;
384  int stat2;
385  int i;
386  unsigned int ptr; /* an index that keeps track of how much of the UDPTL packet has been processed */
387  int seq_no;
388  const uint8_t *ifp = NULL;
389  const uint8_t *data = NULL;
390  unsigned int ifp_len = 0;
391  int repaired[16];
392  const uint8_t *bufs[ARRAY_LEN(s->f) - 1];
393  unsigned int lengths[ARRAY_LEN(s->f) - 1];
394  int span;
395  int entries;
396  int ifp_no;
397 
398  ptr = 0;
399  ifp_no = 0;
400  memset(&s->f[0], 0, sizeof(s->f[0]));
401 
402  /* Decode seq_number */
403  if (ptr + 2 > len)
404  return -1;
405  seq_no = (buf[0] << 8) | buf[1];
406  ptr += 2;
407 
408  /* UDPTL sequence numbers are 16 bit so after 0xFFFF comes
409  0 which breaks all packet recovery logic. To fix this
410  if we see that next expected packet (rx_seq_no) is close
411  to or beyond the wrap around limit & the received packet
412  is still near zero, then we 'unwrap' the received seqno
413  so it has the value it would have had. After a 16
414  packet grace period (there shouldn't be more than
415  that many recovery packets) we wrap the expected
416  sequence number around and things can return back
417  to normal */
418  if (seq_no < 0x000F && s->rx_seq_no > 0xFFF0) {
419  /* received seq_no has wrapped adjust it */
420  seq_no += 0x10000;
421  } else {
422  /* otherwise make sure expected rx_seq_no is properly wrapped */
423  s->rx_seq_no &= 0xFFFF;
424  }
425 
426  /* Break out the primary packet */
427  if ((stat1 = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
428  return -1;
429  /* Decode error_recovery */
430  if (ptr + 1 > len)
431  return -1;
432  if ((buf[ptr++] & 0x80) == 0) {
433  /* Secondary packet mode for error recovery */
434  if (seq_no > s->rx_seq_no) {
435  /* We received a later packet than we expected, so we need to check if we can fill in the gap from the
436  secondary packets. */
437  int total_count = 0;
438  do {
439  unsigned int count;
440  if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
441  return -1;
442  for (i = 0; i < count && total_count + i < ARRAY_LEN(bufs); i++) {
443  if ((stat1 = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0) {
444  return -1;
445  }
446  /* valid secondaries can contain zero-length packets that should be ignored */
447  if (!bufs[total_count + i] || !lengths[total_count + i]) {
448  /* drop the count of items to process and reuse the buffers that were just set */
449  i--;
450  count--;
451  }
452  }
453  total_count += i;
454  }
455  while (stat2 > 0 && total_count < ARRAY_LEN(bufs));
456  /* Step through in reverse order, so we go oldest to newest */
457  for (i = total_count; i > 0; i--) {
458  if (seq_no - i >= s->rx_seq_no) {
459  /* This one wasn't seen before */
460  /* Decode the secondary IFP packet */
461  ast_debug(3, "Recovering lost packet via secondary %d, len %u\n", seq_no - i, lengths[i - 1]);
462  s->f[ifp_no].frametype = AST_FRAME_MODEM;
463  s->f[ifp_no].subclass.integer = AST_MODEM_T38;
464 
465  s->f[ifp_no].mallocd = 0;
466  s->f[ifp_no].seqno = seq_no - i;
467  s->f[ifp_no].datalen = lengths[i - 1];
468  s->f[ifp_no].data.ptr = (uint8_t *) bufs[i - 1];
469  s->f[ifp_no].offset = 0;
470  s->f[ifp_no].src = "UDPTL";
471  if (ifp_no > 0)
472  AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
473  AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
474  ifp_no++;
475  }
476  }
477  }
478  }
479  else
480  {
481  int j;
482  int l;
483  int x;
484  /* FEC mode for error recovery */
485  /* Our buffers cannot tolerate overlength IFP packets in FEC mode */
486  if (ifp_len > LOCAL_FAX_MAX_DATAGRAM)
487  return -1;
488  /* Update any missed slots in the buffer */
489  for ( ; seq_no > s->rx_seq_no; s->rx_seq_no++) {
490  x = s->rx_seq_no & UDPTL_BUF_MASK;
491  s->rx[x].buf_len = -1;
492  s->rx[x].fec_len[0] = 0;
493  s->rx[x].fec_span = 0;
494  s->rx[x].fec_entries = 0;
495  }
496 
497  x = seq_no & UDPTL_BUF_MASK;
498 
499  memset(repaired, 0, sizeof(repaired));
500 
501  /* Save the new IFP packet */
502  memcpy(s->rx[x].buf, ifp, ifp_len);
503  s->rx[x].buf_len = ifp_len;
504  repaired[x] = TRUE;
505 
506  /* Decode the FEC packets */
507  /* The span is defined as an unconstrained integer, but will never be more
508  than a small value. */
509  if (ptr + 2 > len)
510  return -1;
511  if (buf[ptr++] != 1)
512  return -1;
513  span = buf[ptr++];
514  s->rx[x].fec_span = span;
515 
516  /* The number of entries is defined as a length, but will only ever be a small
517  value. Treat it as such. */
518  if (ptr + 1 > len)
519  return -1;
520  entries = buf[ptr++];
521  if (entries > MAX_FEC_ENTRIES) {
522  return -1;
523  }
524  s->rx[x].fec_entries = entries;
525 
526  /* Decode the elements */
527  for (i = 0; i < entries; i++) {
528  if ((stat1 = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
529  return -1;
530  if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
531  return -1;
532 
533  /* Save the new FEC data */
534  memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
535 #if 0
536  fprintf(stderr, "FEC: ");
537  for (j = 0; j < s->rx[x].fec_len[i]; j++)
538  fprintf(stderr, "%02hhX ", data[j]);
539  fprintf(stderr, "\n");
540 #endif
541  }
542 
543  /* See if we can reconstruct anything which is missing */
544  /* TODO: this does not comprehensively hunt back and repair everything that is possible */
545  for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
546  int m;
547  if (s->rx[l].fec_len[0] <= 0)
548  continue;
549  for (m = 0; m < s->rx[l].fec_entries; m++) {
550  int k;
551  int which;
552  int limit = (l + m) & UDPTL_BUF_MASK;
553 
554  /* only repair buffers that actually exist! */
555  if (seq_no <= (s->rx[l].fec_span * s->rx[l].fec_entries) - m) {
556  continue;
557  }
558 
559  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) {
560  if (s->rx[k].buf_len <= 0)
561  which = (which == -1) ? k : -2;
562  }
563  if (which >= 0) {
564  /* Repairable */
565  for (j = 0; j < s->rx[l].fec_len[m]; j++) {
566  s->rx[which].buf[j] = s->rx[l].fec[m][j];
567  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)
568  s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
569  }
570  s->rx[which].buf_len = s->rx[l].fec_len[m];
571  repaired[which] = TRUE;
572  }
573  }
574  }
575  /* Now play any new packets forwards in time */
576  for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
577  if (repaired[l]) {
578  //fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
579  s->f[ifp_no].frametype = AST_FRAME_MODEM;
580  s->f[ifp_no].subclass.integer = AST_MODEM_T38;
581 
582  s->f[ifp_no].mallocd = 0;
583  s->f[ifp_no].seqno = j;
584  s->f[ifp_no].datalen = s->rx[l].buf_len;
585  s->f[ifp_no].data.ptr = s->rx[l].buf;
586  s->f[ifp_no].offset = 0;
587  s->f[ifp_no].src = "UDPTL";
588  if (ifp_no > 0)
589  AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
590  AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
591  ifp_no++;
592  }
593  }
594  }
595 
596  /* If packets are received out of sequence, we may have already processed this packet from the error
597  recovery information in a packet already received. */
598  if (seq_no >= s->rx_seq_no) {
599  /* Decode the primary IFP packet */
600  s->f[ifp_no].frametype = AST_FRAME_MODEM;
601  s->f[ifp_no].subclass.integer = AST_MODEM_T38;
602 
603  s->f[ifp_no].mallocd = 0;
604  s->f[ifp_no].seqno = seq_no;
605  s->f[ifp_no].datalen = ifp_len;
606  s->f[ifp_no].data.ptr = (uint8_t *) ifp;
607  s->f[ifp_no].offset = 0;
608  s->f[ifp_no].src = "UDPTL";
609  if (ifp_no > 0)
610  AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
611  AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
612 
613  ifp_no++;
614  }
615 
616  s->rx_seq_no = seq_no + 1;
617  return ifp_no;
618 }
unsigned int fec_entries
Definition: udptl.c:152
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
#define NULL
Definition: resample.c:96
struct ast_frame_subclass subclass
static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
Definition: udptl.c:274
unsigned int fec_len[MAX_FEC_ENTRIES]
Definition: udptl.c:149
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const char * src
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK+1]
Definition: udptl.c:217
#define LOCAL_FAX_MAX_DATAGRAM
Definition: udptl.c:133
#define TRUE
Definition: udptl.c:122
static int decode_open_type(uint8_t *buf, unsigned int limit, unsigned int *len, const uint8_t **p_object, unsigned int *p_num_octets)
Definition: udptl.c:300
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:148
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
unsigned int rx_seq_no
Definition: udptl.c:214
uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:150
struct ast_frame f[16]
Definition: udptl.c:159
#define AST_MODEM_T38
unsigned int fec_span
Definition: udptl.c:151
union ast_frame::@263 data
enum ast_frame_type frametype
#define MAX_FEC_ENTRIES
Definition: udptl.c:136
#define UDPTL_BUF_MASK
Definition: udptl.c:139

◆ udptl_snapshot_alloc()

static void * udptl_snapshot_alloc ( void  )
static

Definition at line 1302 of file udptl.c.

References ao2_alloc, ao2_ref, udptl_config::general, NULL, and udptl_config_destructor().

Referenced by __ast_udptl_reload().

1303 {
1304  struct udptl_config *cfg;
1305 
1306  if (!(cfg = ao2_alloc(sizeof(*cfg), udptl_config_destructor))) {
1307  return NULL;
1308  }
1309  if (!(cfg->general = ao2_alloc(sizeof(*cfg->general), NULL))) {
1310  ao2_ref(cfg, -1);
1311  return NULL;
1312  }
1313 
1314  return cfg;
1315 }
static void udptl_config_destructor(void *obj)
Definition: udptl.c:1296
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct udptl_global_options * general
Definition: udptl.c:232

◆ udptlread()

static int udptlread ( int *  id,
int  fd,
short  events,
void *  cbdata 
)
static

Definition at line 750 of file udptl.c.

References ast_udptl_read(), ast_udptl::callback, and ast_udptl::data.

Referenced by ast_udptl_new_with_bindaddr().

751 {
752  struct ast_udptl *udptl = cbdata;
753  struct ast_frame *f;
754 
755  if ((f = ast_udptl_read(udptl))) {
756  if (udptl->callback)
757  udptl->callback(udptl, f, udptl->data);
758  }
759  return 1;
760 }
ast_udptl_callback callback
Definition: udptl.c:171
Structure for an UDPTL session.
Definition: udptl.c:156
struct ast_frame * ast_udptl_read(struct ast_udptl *udptl)
Definition: udptl.c:762
Data structure associated with a single frame of data.
void * data
Definition: udptl.c:169

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1387 of file udptl.c.

References aco_info_destroy(), ao2_t_global_obj_release, ARRAY_LEN, ast_cli_unregister_multiple(), and globals.

Referenced by load_module().

1388 {
1390  ao2_t_global_obj_release(globals, "Unref udptl global container in shutdown");
1391  aco_info_destroy(&cfg_info);
1392 
1393  return 0;
1394 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define ao2_t_global_obj_release(holder, tag)
Release the ao2 object held in the global holder.
Definition: astobj2.h:863
static struct console_pvt globals
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.
static struct ast_cli_entry cli_udptl[]
Definition: udptl.c:1291

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "UDPTL" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CORE, .requires = "extconfig", }
static

Definition at line 1441 of file udptl.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1441 of file udptl.c.

◆ cli_udptl

struct ast_cli_entry cli_udptl[]
static
Initial value:
= {
{ .handler = handle_cli_udptl_set_debug , .summary = "Enable/Disable UDPTL debugging" ,},
{ .handler = handle_cli_show_config , .summary = "Show UDPTL config options" ,},
}
static char * handle_cli_udptl_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: udptl.c:1215
static char * handle_cli_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: udptl.c:1260

Definition at line 1291 of file udptl.c.

◆ general_option

struct aco_type general_option
static

Definition at line 238 of file udptl.c.

◆ general_options

struct aco_type* general_options[] = ACO_TYPES(&general_option)
static

Definition at line 246 of file udptl.c.

◆ udptl_conf

struct aco_file udptl_conf
static
Initial value:
= {
.filename = "udptl.conf",
}
#define ACO_TYPES(...)
A helper macro to ensure that aco_info types always have a sentinel.
static struct aco_type general_option
Definition: udptl.c:238

Definition at line 248 of file udptl.c.

◆ udptldebug

int udptldebug
static

Are we debugging?

Definition at line 130 of file udptl.c.

Referenced by handle_cli_udptl_set_debug(), and udptl_debug_test_addr().

◆ udptldebugaddr

struct ast_sockaddr udptldebugaddr
static

Debug packets to/from this host

Definition at line 131 of file udptl.c.

Referenced by handle_cli_udptl_set_debug(), and udptl_debug_test_addr().