Asterisk - The Open Source Telephony Project GIT-master-2de1a68
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 = AST_BUILDOPT_SUM, .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 132 of file udptl.c.

◆ DEFAULT_UDPTLEND

#define DEFAULT_UDPTLEND   4999

Definition at line 126 of file udptl.c.

◆ DEFAULT_UDPTLSTART

#define DEFAULT_UDPTLSTART   4000

Definition at line 125 of file udptl.c.

◆ FALSE

#define FALSE   0

Definition at line 117 of file udptl.c.

◆ FAX_MAX_DATAGRAM_LIMIT

#define FAX_MAX_DATAGRAM_LIMIT   1400

Definition at line 133 of file udptl.c.

◆ LOCAL_FAX_MAX_DATAGRAM

#define LOCAL_FAX_MAX_DATAGRAM   1400

Definition at line 131 of file udptl.c.

◆ LOG_TAG

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

Definition at line 123 of file udptl.c.

◆ MAX_FEC_ENTRIES

#define MAX_FEC_ENTRIES   5

Definition at line 134 of file udptl.c.

◆ MAX_FEC_SPAN

#define MAX_FEC_SPAN   5

Definition at line 135 of file udptl.c.

◆ TRUE

#define TRUE   (!FALSE)

Definition at line 120 of file udptl.c.

◆ UDPTL_BUF_MASK

#define UDPTL_BUF_MASK   15

Definition at line 137 of file udptl.c.

◆ UDPTL_MTU

#define UDPTL_MTU   1200

Definition at line 114 of file udptl.c.

Function Documentation

◆ __ast_udptl_reload()

static void __ast_udptl_reload ( int  reload)
static

Definition at line 1325 of file udptl.c.

1326{
1327 if (aco_process_config(&cfg_info, reload) == ACO_PROCESS_ERROR) {
1328 if (!reload) {
1329 RAII_VAR(struct udptl_config *, udptl_cfg, udptl_snapshot_alloc(), ao2_cleanup);
1330
1331 if (aco_set_defaults(&general_option, "general", udptl_cfg->general)) {
1332 ast_log(LOG_ERROR, "Failed to load udptl.conf and failed to initialize defaults.\n");
1333 return;
1334 }
1335
1336 ast_log(LOG_NOTICE, "Could not load udptl config; using defaults\n");
1338 }
1339 }
1340}
#define ast_log
Definition: astobj2.c:42
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
Definition: astobj2.h:901
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
static struct console_pvt globals
int aco_set_defaults(struct aco_type *type, const char *category, void *obj)
Set all default options of obj.
@ ACO_PROCESS_ERROR
Their was an error and no changes were applied.
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 LOG_ERROR
#define LOG_NOTICE
static int reload(void)
static void * udptl_snapshot_alloc(void)
Definition: udptl.c:1300
static struct aco_type general_option
Definition: udptl.c:236
#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:941

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

Referenced by load_module(), and reload_module().

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1439 of file udptl.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1439 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 1439 of file udptl.c.

◆ ast_udptl_destroy()

void ast_udptl_destroy ( struct ast_udptl udptl)

Definition at line 1148 of file udptl.c.

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

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

Referenced by ooh323_destroy(), and stream_destroy().

◆ ast_udptl_fd()

int ast_udptl_fd ( const struct ast_udptl udptl)

Definition at line 728 of file udptl.c.

729{
730 return udptl->fd;
731}

References ast_udptl::fd.

Referenced by apply_negotiated_sdp_stream(), and configure_local_rtp().

◆ 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 938 of file udptl.c.

939{
940 return udptl->error_correction_scheme;
941}
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:174

References ast_udptl::error_correction_scheme.

Referenced by create_outgoing_sdp_stream().

◆ ast_udptl_get_far_max_datagram()

unsigned int ast_udptl_get_far_max_datagram ( const struct ast_udptl udptl)

Definition at line 1006 of file udptl.c.

1007{
1008 if (udptl->far_max_datagram < 0) {
1009 return 0;
1010 }
1011 return udptl->far_max_datagram;
1012}
int far_max_datagram
Definition: udptl.c:189

References ast_udptl::far_max_datagram.

◆ ast_udptl_get_far_max_ifp()

unsigned int ast_udptl_get_far_max_ifp ( struct ast_udptl udptl)

retrieves far max ifp

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

Definition at line 1014 of file udptl.c.

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

References calculate_far_max_ifp(), and ast_udptl::far_max_ifp.

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

◆ ast_udptl_get_local_max_datagram()

unsigned int ast_udptl_get_local_max_datagram ( struct ast_udptl udptl)

retrieves local_max_datagram.

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

Definition at line 982 of file udptl.c.

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

References calculate_local_max_datagram(), and ast_udptl::local_max_datagram.

Referenced by create_outgoing_sdp_stream().

◆ ast_udptl_get_peer()

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

Definition at line 1133 of file udptl.c.

1134{
1135 ast_sockaddr_copy(them, &udptl->them);
1136}
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:167
struct ast_sockaddr them
Definition: udptl.c:163

References ast_sockaddr_copy(), and ast_udptl::them.

◆ ast_udptl_get_us()

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

Definition at line 1138 of file udptl.c.

1139{
1140 ast_sockaddr_copy(us, &udptl->us);
1141}
struct ast_sockaddr us
Definition: udptl.c:162

References ast_sockaddr_copy(), and ast_udptl::us.

Referenced by configure_local_rtp(), and create_outgoing_sdp_stream().

◆ 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 1026 of file udptl.c.

1027{
1028 struct ast_udptl *udptl;
1029 int x;
1030 int startplace;
1031 int i;
1033
1034 if (!cfg || !cfg->general) {
1035 ast_log(LOG_ERROR, "Could not access global udptl options!\n");
1036 return NULL;
1037 }
1038
1039 if (!(udptl = ast_calloc(1, sizeof(*udptl)))) {
1040 return NULL;
1041 }
1042
1043 udptl->error_correction_span = cfg->general->fecspan;
1044 udptl->error_correction_entries = cfg->general->fecentries;
1045
1046 udptl->far_max_datagram = -1;
1047 udptl->far_max_ifp = -1;
1048 udptl->local_max_ifp = -1;
1049 udptl->local_max_datagram = -1;
1050
1051 for (i = 0; i <= UDPTL_BUF_MASK; i++) {
1052 udptl->rx[i].buf_len = -1;
1053 udptl->tx[i].buf_len = -1;
1054 }
1055
1056 if ((udptl->fd = ast_socket_nonblock(ast_sockaddr_is_ipv6(addr) ?
1057 AF_INET6 : AF_INET, SOCK_DGRAM, 0)) < 0) {
1058 ast_free(udptl);
1059 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
1060 return NULL;
1061 }
1062
1063#ifdef SO_NO_CHECK
1064 if (cfg->general->nochecksums)
1065 setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &cfg->general->nochecksums, sizeof(cfg->general->nochecksums));
1066#endif
1067
1068 /* Find us a place */
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)) {
1071 ++x;
1072 }
1073 startplace = x;
1074 for (;;) {
1075 ast_sockaddr_copy(&udptl->us, addr);
1076 ast_sockaddr_set_port(&udptl->us, x);
1077 if (ast_bind(udptl->fd, &udptl->us) == 0) {
1078 break;
1079 }
1080 if (errno != EADDRINUSE && errno != EACCES) {
1081 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
1082 close(udptl->fd);
1083 ast_free(udptl);
1084 return NULL;
1085 }
1086 if (cfg->general->use_even_ports) {
1087 x += 2;
1088 } else {
1089 ++x;
1090 }
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");
1095 close(udptl->fd);
1096 ast_free(udptl);
1097 return NULL;
1098 }
1099 }
1100 if (io && sched && callbackmode) {
1101 /* Operate this one in a callback mode */
1102 udptl->sched = sched;
1103 udptl->io = io;
1104 udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
1105 }
1106
1107 return udptl;
1108}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
Definition: astobj2.h:918
static struct ast_sched_context * sched
Definition: chan_ooh323.c:400
static struct io_context * io
Definition: chan_ooh323.c:401
#define LOG_WARNING
#define AST_IO_IN
Definition: io.h:34
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
int errno
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
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_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
#define NULL
Definition: resample.c:96
Structure for an UDPTL session.
Definition: udptl.c:154
struct ast_sched_context * sched
Definition: udptl.c:165
unsigned int error_correction_entries
Definition: udptl.c:179
int local_max_ifp
Definition: udptl.c:209
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK+1]
Definition: udptl.c:215
unsigned int error_correction_span
Definition: udptl.c:184
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK+1]
Definition: udptl.c:214
Definition: sched.c:76
#define UDPTL_BUF_MASK
Definition: udptl.c:137
static int udptlread(int *id, int fd, short events, void *cbdata)
Definition: udptl.c:748
#define ast_socket_nonblock(domain, type, protocol)
Create a non-blocking socket.
Definition: utils.h:1073
long int ast_random(void)
Definition: utils.c:2312

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, io, ast_udptl::io, ast_udptl::ioid, ast_udptl::local_max_datagram, ast_udptl::local_max_ifp, LOG_ERROR, LOG_WARNING, NULL, RAII_VAR, ast_udptl::rx, sched, ast_udptl::sched, ast_udptl::tx, UDPTL_BUF_MASK, udptlread(), and ast_udptl::us.

Referenced by configure_local_rtp(), and t38_initialize_session().

◆ ast_udptl_read()

struct ast_frame * ast_udptl_read ( struct ast_udptl udptl)

Definition at line 760 of file udptl.c.

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

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(), and udptlread().

◆ ast_udptl_set_callback()

void ast_udptl_set_callback ( struct ast_udptl udptl,
ast_udptl_callback  callback 
)

Definition at line 738 of file udptl.c.

739{
740 udptl->callback = callback;
741}
ast_udptl_callback callback
Definition: udptl.c:169

References ast_udptl::callback.

◆ ast_udptl_set_data()

void ast_udptl_set_data ( struct ast_udptl udptl,
void *  data 
)

Definition at line 733 of file udptl.c.

734{
735 udptl->data = data;
736}
void * data
Definition: udptl.c:167

References ast_udptl::data.

◆ 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 943 of file udptl.c.

944{
945 udptl->error_correction_scheme = ec;
946 switch (ec) {
949 if (udptl->error_correction_entries == 0) {
950 udptl->error_correction_entries = 3;
951 }
952 if (udptl->error_correction_span == 0) {
953 udptl->error_correction_span = 3;
954 }
955 break;
958 if (udptl->error_correction_entries == 0) {
959 udptl->error_correction_entries = 3;
960 }
961 break;
962 default:
963 /* nothing to do */
964 break;
965 };
966 /* reset calculated values so they'll be computed again */
967 udptl->local_max_datagram = -1;
968 udptl->far_max_ifp = -1;
969}
@ UDPTL_ERROR_CORRECTION_FEC
Definition: udptl.h:39
@ UDPTL_ERROR_CORRECTION_REDUNDANCY
Definition: udptl.h:40

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 t38_initialize_session(), and t38_interpret_sdp().

◆ 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 995 of file udptl.c.

996{
997 if (!max_datagram || (max_datagram > FAX_MAX_DATAGRAM_LIMIT)) {
999 } else {
1000 udptl->far_max_datagram = max_datagram;
1001 }
1002 /* reset calculated values so they'll be computed again */
1003 udptl->far_max_ifp = -1;
1004}
#define DEFAULT_FAX_MAX_DATAGRAM
Definition: udptl.c:132
#define FAX_MAX_DATAGRAM_LIMIT
Definition: udptl.c:133

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(), t38_initialize_session(), and t38_interpret_sdp().

◆ ast_udptl_set_local_max_ifp()

void ast_udptl_set_local_max_ifp ( struct ast_udptl udptl,
unsigned int  max_ifp 
)

Definition at line 971 of file udptl.c.

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

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

Referenced by t38_interpret_parameters().

◆ ast_udptl_set_peer()

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

Definition at line 1128 of file udptl.c.

1129{
1130 ast_sockaddr_copy(&udptl->them, them);
1131}

References ast_sockaddr_copy(), and ast_udptl::them.

Referenced by apply_negotiated_sdp_stream(), and setup_udptl_connection().

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

Definition at line 1110 of file udptl.c.

1111{
1112 va_list ap;
1113
1114 ast_free(udptl->tag);
1115 udptl->tag = NULL;
1116 va_start(ap, format);
1117 if (ast_vasprintf(&udptl->tag, format, ap) == -1) {
1118 udptl->tag = NULL;
1119 }
1120 va_end(ap);
1121}
#define ast_vasprintf(ret, fmt, ap)
A wrapper for vasprintf()
Definition: astmm.h:278

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

Referenced by setup_udptl_connection(), and t38_change_state().

◆ ast_udptl_setnat()

void ast_udptl_setnat ( struct ast_udptl udptl,
int  nat 
)

Definition at line 743 of file udptl.c.

744{
745 udptl->nat = nat;
746}

References ast_udptl::nat.

Referenced by t38_initialize_session().

◆ ast_udptl_setqos()

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

Definition at line 1123 of file udptl.c.

1124{
1125 return ast_set_qos(udptl->fd, tos, cos, "UDPTL");
1126}
unsigned int tos
Definition: chan_iax2.c:358
unsigned int cos
Definition: chan_iax2.c:359
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621

References ast_set_qos(), cos, ast_udptl::fd, and tos.

◆ ast_udptl_stop()

void ast_udptl_stop ( struct ast_udptl udptl)

Definition at line 1143 of file udptl.c.

1144{
1145 ast_sockaddr_setnull(&udptl->them);
1146}
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:138

References ast_sockaddr_setnull(), and ast_udptl::them.

◆ ast_udptl_write()

int ast_udptl_write ( struct ast_udptl s,
struct ast_frame f 
)

Definition at line 1159 of file udptl.c.

1160{
1161 unsigned int seq;
1162 unsigned int len = f->datalen;
1163 /* if no max datagram size is provided, use default value */
1164 const int bufsize = (s->far_max_datagram > 0) ? s->far_max_datagram : DEFAULT_FAX_MAX_DATAGRAM;
1165 uint8_t buf[bufsize];
1166
1167 memset(buf, 0, sizeof(buf));
1168
1169 /* If we have no peer, return immediately */
1170 if (ast_sockaddr_isnull(&s->them)) {
1171 return 0;
1172 }
1173
1174 /* If there is no data length, return immediately */
1175 if (f->datalen == 0)
1176 return 0;
1177
1178 if ((f->frametype != AST_FRAME_MODEM) ||
1179 (f->subclass.integer != AST_MODEM_T38)) {
1180 ast_log(LOG_WARNING, "UDPTL (%s): UDPTL can only send T.38 data.\n",
1181 LOG_TAG(s));
1182 return -1;
1183 }
1184
1185 if (len > s->far_max_ifp) {
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",
1189 LOG_TAG(s), len, s->far_max_ifp);
1190 len = s->far_max_ifp;
1191 }
1192
1193 /* Save seq_no for debug output because udptl_build_packet increments it */
1194 seq = s->tx_seq_no & 0xFFFF;
1195
1196 /* Cook up the UDPTL packet, with the relevant EC info. */
1197 len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, len);
1198
1199 if ((signed int) len > 0 && !ast_sockaddr_isnull(&s->them)) {
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",
1202 LOG_TAG(s), ast_sockaddr_stringify(&s->them), strerror(errno));
1203 }
1204 if (udptl_debug_test_addr(&s->them)) {
1205 ast_verb(1, "UDPTL (%s): packet to %s (seq %u, len %u)\n",
1207 }
1208 }
1209
1210 return 0;
1211}
static volatile unsigned int seq
Definition: app_sms.c:120
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_MODEM_T38
@ AST_FRAME_MODEM
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
struct ast_frame_subclass subclass
union ast_frame::@226 data
enum ast_frame_type frametype
unsigned int tx_seq_no
Definition: udptl.c:211
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:619

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::f, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, ast_udptl::fd, ast_frame::frametype, ast_frame_subclass::integer, 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(), and ooh323_write().

◆ calculate_far_max_ifp()

static void calculate_far_max_ifp ( struct ast_udptl udptl)
static

Definition at line 870 of file udptl.c.

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

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().

◆ calculate_local_max_datagram()

static void calculate_local_max_datagram ( struct ast_udptl udptl)
static

Definition at line 829 of file udptl.c.

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

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().

◆ 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 272 of file udptl.c.

273{
274 if (*len >= limit)
275 return -1;
276 if ((buf[*len] & 0x80) == 0) {
277 *pvalue = buf[*len];
278 (*len)++;
279 return 0;
280 }
281 if ((buf[*len] & 0x40) == 0) {
282 if (*len == limit - 1)
283 return -1;
284 *pvalue = (buf[*len] & 0x3F) << 8;
285 (*len)++;
286 *pvalue |= buf[*len];
287 (*len)++;
288 return 0;
289 }
290 *pvalue = (buf[*len] & 0x3F) << 14;
291 (*len)++;
292 /* We have a fragment. Currently we don't process fragments. */
293 ast_debug(1, "UDPTL packet with length greater than 16K received, decoding will fail\n");
294 return 1;
295}

References ast_debug, buf, and len().

Referenced by decode_open_type(), and udptl_rx_packet().

◆ 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 298 of file udptl.c.

299{
300 unsigned int octet_cnt = 0;
301
302 if (decode_length(buf, limit, len, &octet_cnt) != 0)
303 return -1;
304
305 /* Make sure the buffer contains at least the number of bits requested */
306 if ((*len + octet_cnt) > limit) {
307 return -1;
308 }
309
310 *p_num_octets = octet_cnt;
311 *p_object = &buf[*len];
312 *len += octet_cnt;
313
314 return 0;
315}
static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
Definition: udptl.c:272

References buf, decode_length(), and len().

Referenced by udptl_rx_packet().

◆ encode_length()

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

Definition at line 318 of file udptl.c.

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

References buf, len(), and value.

Referenced by encode_open_type(), and udptl_build_packet().

◆ 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 346 of file udptl.c.

348{
349 unsigned int enclen;
350 unsigned int octet_idx;
351 uint8_t zero_byte;
352
353 /* If open type is of zero length, add a single zero byte (10.1) */
354 if (num_octets == 0) {
355 zero_byte = 0;
356 data = &zero_byte;
357 num_octets = 1;
358 }
359 /* Encode the open type */
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);
365 return -1;
366 }
367 if (enclen > 0) {
368 memcpy(&buf[*len], &data[octet_idx], enclen);
369 *len += enclen;
370 }
371 if (enclen >= num_octets)
372 break;
373 }
374
375 return 0;
376}
static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
Definition: udptl.c:318

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

Referenced by udptl_build_packet().

◆ 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 1258 of file udptl.c.

1259{
1260 RAII_VAR(struct udptl_config *, cfg, NULL, ao2_cleanup);
1261
1262 switch (cmd) {
1263 case CLI_INIT:
1264 e->command = "udptl show config";
1265 e->usage =
1266 "Usage: udptl show config\n"
1267 " Display UDPTL configuration options\n";
1268 return NULL;
1269 case CLI_GENERATE:
1270 return NULL;
1271 }
1272
1273 if (!(cfg = ao2_global_obj_ref(globals))) {
1274 return CLI_FAILURE;
1275 }
1276
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));
1285
1286 return CLI_SUCCESS;
1287}
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
#define CLI_SUCCESS
Definition: cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define CLI_FAILURE
Definition: cli.h:46
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
static struct test_val a

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

◆ 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 1213 of file udptl.c.

1214{
1215 switch (cmd) {
1216 case CLI_INIT:
1217 e->command = "udptl set debug {on|off|ip}";
1218 e->usage =
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";
1223 return NULL;
1224 case CLI_GENERATE:
1225 return NULL;
1226 }
1227
1228 if (a->argc < 4 || a->argc > 5)
1229 return CLI_SHOWUSAGE;
1230
1231 if (a->argc == 4) {
1232 if (!strncasecmp(a->argv[3], "on", 2)) {
1233 udptldebug = 1;
1234 memset(&udptldebugaddr, 0, sizeof(udptldebugaddr));
1235 ast_cli(a->fd, "UDPTL Debugging Enabled\n");
1236 } else if (!strncasecmp(a->argv[3], "off", 3)) {
1237 udptldebug = 0;
1238 ast_cli(a->fd, "UDPTL Debugging Disabled\n");
1239 } else {
1240 return CLI_SHOWUSAGE;
1241 }
1242 } else {
1243 struct ast_sockaddr *addrs;
1244 if (strncasecmp(a->argv[3], "ip", 2))
1245 return CLI_SHOWUSAGE;
1246 if (!ast_sockaddr_resolve(&addrs, a->argv[4], 0, 0)) {
1247 return CLI_SHOWUSAGE;
1248 }
1249 ast_sockaddr_copy(&udptldebugaddr, &addrs[0]);
1250 ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_sockaddr_stringify(&udptldebugaddr));
1251 udptldebug = 1;
1252 ast_free(addrs);
1253 }
1254
1255 return CLI_SUCCESS;
1256}
#define CLI_SHOWUSAGE
Definition: cli.h:45
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 struct ast_sockaddr udptldebugaddr
Definition: udptl.c:129
static int udptldebug
Definition: udptl.c:128

References a, 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, NULL, udptldebug, udptldebugaddr, and ast_cli_entry::usage.

◆ load_module()

static int load_module ( void  )
static

Definition at line 1394 of file udptl.c.

1395{
1396 if (aco_info_init(&cfg_info)) {
1398 }
1399
1402 FLDSET(struct udptl_global_options, start), DEFAULT_UDPTLSTART, 1024, 65535);
1403
1406 FLDSET(struct udptl_global_options, end), DEFAULT_UDPTLEND, 1024, 65535);
1407
1408 aco_option_register(&cfg_info, "udptlfecentries", ACO_EXACT, general_options, NULL,
1410 FLDSET(struct udptl_global_options, fecentries), 1, MAX_FEC_ENTRIES);
1411
1412 aco_option_register(&cfg_info, "udptlfecspan", ACO_EXACT, general_options, NULL,
1414 FLDSET(struct udptl_global_options, fecspan), 1, MAX_FEC_SPAN);
1415
1416 aco_option_register(&cfg_info, "udptlchecksums", ACO_EXACT, general_options, "yes",
1417 OPT_BOOL_T, 0, FLDSET(struct udptl_global_options, nochecksums));
1418
1419 aco_option_register(&cfg_info, "use_even_ports", ACO_EXACT, general_options, "no",
1420 OPT_BOOL_T, 1, FLDSET(struct udptl_global_options, use_even_ports));
1421
1424
1426
1428
1430}
#define __stringify(x)
Definition: asterisk.h:216
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ ACO_EXACT
int aco_info_init(struct aco_info *info)
Initialize an aco_info structure.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
#define aco_option_register(info, name, matchtype, types, default_val, opt_type, flags,...)
Register a config option.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
#define aco_option_register_custom(info, name, matchtype, types, default_val, handler, flags)
Register a config option.
char * end
Definition: eagi_proxy.c:73
@ PARSE_RANGE_DEFAULTS
@ AST_MODULE_LOAD_FAILURE
Module could not be loaded properly.
Definition: module.h:102
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define MAX_FEC_ENTRIES
Definition: udptl.c:134
#define DEFAULT_UDPTLEND
Definition: udptl.c:126
static int removed_options_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Definition: udptl.c:1315
#define DEFAULT_UDPTLSTART
Definition: udptl.c:125
static struct ast_cli_entry cli_udptl[]
Definition: udptl.c:1289
#define MAX_FEC_SPAN
Definition: udptl.c:135
static struct aco_type * general_options[]
Definition: udptl.c:244
static void __ast_udptl_reload(int reload)
Definition: udptl.c:1325
#define ARRAY_LEN(a)
Definition: utils.h:666

References __ast_udptl_reload(), __stringify, ACO_EXACT, aco_info_init(), aco_option_register, aco_option_register_custom, ARRAY_LEN, ast_cli_register_multiple, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, cli_udptl, DEFAULT_UDPTLEND, DEFAULT_UDPTLSTART, end, FLDSET, general_options, MAX_FEC_ENTRIES, MAX_FEC_SPAN, NULL, OPT_BOOL_T, OPT_UINT_T, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_RANGE_DEFAULTS, and removed_options_handler().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1374 of file udptl.c.

1375{
1377
1378 return 0;
1379}

References __ast_udptl_reload().

◆ removed_options_handler()

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

Definition at line 1315 of file udptl.c.

1316{
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");
1321 }
1322 return 0;
1323}
#define var
Definition: ast_expr2f.c:605

References ast_log, LOG_WARNING, and var.

Referenced by load_module().

◆ 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 619 of file udptl.c.

620{
621 uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2] = { 0, };
622 int i;
623 int j;
624 int seq;
625 int entry;
626 int entries;
627 int span;
628 int m;
629 unsigned int len;
630 int limit;
631 int high_tide;
632
633 seq = s->tx_seq_no & 0xFFFF;
634
635 /* Map the sequence number to an entry in the circular buffer */
637
638 /* We save the message in a circular buffer, for generating FEC or
639 redundancy sets later on. */
640 s->tx[entry].buf_len = ifp_len;
641 memcpy(s->tx[entry].buf, ifp, ifp_len);
642
643 /* Build the UDPTLPacket */
644
645 len = 0;
646 /* Encode the sequence number */
647 buf[len++] = (seq >> 8) & 0xFF;
648 buf[len++] = seq & 0xFF;
649
650 /* Encode the primary IFP packet */
651 if (encode_open_type(s, buf, buflen, &len, ifp, ifp_len) < 0)
652 return -1;
653
654 /* Encode the appropriate type of error recovery information */
655 switch (s->error_correction_scheme)
656 {
658 /* Encode the error recovery type */
659 buf[len++] = 0x00;
660 /* The number of entries will always be zero, so it is pointless allowing
661 for the fragmented case here. */
662 encode_length(buf, &len, 0);
663 break;
665 /* Encode the error recovery type */
666 buf[len++] = 0x00;
668 entries = s->error_correction_entries;
669 else
670 entries = s->tx_seq_no;
671 /* The number of entries will always be small, so it is pointless allowing
672 for the fragmented case here. */
673 encode_length(buf, &len, entries);
674 /* Encode the elements */
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",
679 LOG_TAG(s), i, j);
680 return -1;
681 }
682 }
683 break;
685 span = s->error_correction_span;
686 entries = s->error_correction_entries;
687 if (seq < s->error_correction_span*s->error_correction_entries) {
688 /* In the initial stages, wind up the FEC smoothly */
689 entries = seq/s->error_correction_span;
690 if (seq < s->error_correction_span)
691 span = 0;
692 }
693 /* Encode the error recovery type */
694 buf[len++] = 0x80;
695 /* Span is defined as an unconstrained integer, which it dumb. It will only
696 ever be a small value. Treat it as such. */
697 buf[len++] = 1;
698 buf[len++] = span;
699 /* The number of entries is defined as a length, but will only ever be a small
700 value. Treat it as such. */
701 buf[len++] = entries;
702 for (m = 0; m < entries; m++) {
703 /* Make an XOR'ed entry the maximum length */
704 limit = (entry + m) & UDPTL_BUF_MASK;
705 high_tide = 0;
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;
713 } else {
714 for (j = 0; j < s->tx[i].buf_len; j++)
715 fec[j] ^= s->tx[i].buf[j];
716 }
717 }
718 if (encode_open_type(s, buf, buflen, &len, fec, high_tide) < 0)
719 return -1;
720 }
721 break;
722 }
723
724 s->tx_seq_no++;
725 return len;
726}
Definition: search.h:40
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:141
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:346

References ast_debug, buf, 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, 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().

◆ udptl_config_destructor()

static void udptl_config_destructor ( void *  obj)
static

Definition at line 1294 of file udptl.c.

1295{
1296 struct udptl_config *cfg = obj;
1297 ao2_cleanup(cfg->general);
1298}
struct udptl_global_options * general
Definition: udptl.c:230

References ao2_cleanup, and udptl_config::general.

Referenced by udptl_snapshot_alloc().

◆ udptl_debug_test_addr()

static int udptl_debug_test_addr ( const struct ast_sockaddr addr)
inlinestatic

Definition at line 256 of file udptl.c.

257{
258 if (udptldebug == 0)
259 return 0;
260
262 return 1;
263 }
264
266 return !ast_sockaddr_cmp(&udptldebugaddr, addr);
267 } else {
269 }
270}
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
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

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().

◆ udptl_pre_apply_config()

static int udptl_pre_apply_config ( void  )
static

Definition at line 1342 of file udptl.c.

1342 {
1343 struct udptl_config *cfg = aco_pending_config(&cfg_info);
1344
1345 if (!cfg->general) {
1346 return -1;
1347 }
1348
1349#ifndef SO_NO_CHECK
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;
1353 }
1354#endif
1355
1356 /* Fix up any global config values that we can handle before replacing the config */
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);
1360 }
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));
1365 }
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);
1369 }
1370
1371 return 0;
1372}
void * aco_pending_config(struct aco_info *info)
Get pending config changes.
unsigned int use_even_ports
Definition: udptl.c:224
unsigned int nochecksums
Definition: udptl.c:223
unsigned int start
Definition: udptl.c:219
unsigned int end
Definition: udptl.c:220

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.

◆ udptl_rx_packet()

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

Definition at line 379 of file udptl.c.

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

References ARRAY_LEN, ast_debug, AST_FRAME_MODEM, AST_LIST_NEXT, AST_MODEM_T38, buf, 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, len(), 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().

◆ udptl_snapshot_alloc()

static void * udptl_snapshot_alloc ( void  )
static

Definition at line 1300 of file udptl.c.

1301{
1302 struct udptl_config *cfg;
1303
1304 if (!(cfg = ao2_alloc(sizeof(*cfg), udptl_config_destructor))) {
1305 return NULL;
1306 }
1307 if (!(cfg->general = ao2_alloc(sizeof(*cfg->general), NULL))) {
1308 ao2_ref(cfg, -1);
1309 return NULL;
1310 }
1311
1312 return cfg;
1313}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void udptl_config_destructor(void *obj)
Definition: udptl.c:1294

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

Referenced by __ast_udptl_reload().

◆ udptlread()

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

Definition at line 748 of file udptl.c.

749{
750 struct ast_udptl *udptl = cbdata;
751 struct ast_frame *f;
752
753 if ((f = ast_udptl_read(udptl))) {
754 if (udptl->callback)
755 udptl->callback(udptl, f, udptl->data);
756 }
757 return 1;
758}
Data structure associated with a single frame of data.
struct ast_frame * ast_udptl_read(struct ast_udptl *udptl)
Definition: udptl.c:760

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

Referenced by ast_udptl_new_with_bindaddr().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1385 of file udptl.c.

1386{
1388 ao2_t_global_obj_release(globals, "Unref udptl global container in shutdown");
1389 aco_info_destroy(&cfg_info);
1390
1391 return 0;
1392}
#define ao2_t_global_obj_release(holder, tag)
Definition: astobj2.h:861
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
void aco_info_destroy(struct aco_info *info)
Destroy an initialized aco_info struct.

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

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 = AST_BUILDOPT_SUM, .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 1439 of file udptl.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1439 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:1213
static char * handle_cli_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: udptl.c:1258

Definition at line 1289 of file udptl.c.

Referenced by load_module(), and unload_module().

◆ general_option

struct aco_type general_option
static

Definition at line 236 of file udptl.c.

Referenced by __ast_udptl_reload().

◆ general_options

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

Definition at line 244 of file udptl.c.

Referenced by load_module().

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

Definition at line 246 of file udptl.c.

◆ udptldebug

int udptldebug
static

Are we debugging?

Definition at line 128 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 129 of file udptl.c.

Referenced by handle_cli_udptl_set_debug(), and udptl_debug_test_addr().