Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


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/udptl.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/acl.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/netsock.h"
#include "asterisk/cli.h"
#include "asterisk/unaligned.h"

Go to the source code of this file.

Data Structures

struct  ast_udptl
 Structure for an UDPTL session. More...
 
struct  protos
 
struct  udptl_fec_rx_buffer_t
 
struct  udptl_fec_tx_buffer_t
 

Macros

#define DEFAULT_FAX_MAX_DATAGRAM   400
 
#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)
 
int ast_udptl_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
 
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)
 
void ast_udptl_init (void)
 
struct ast_udptlast_udptl_new_with_bindaddr (struct sched_context *sched, struct io_context *io, int callbackmode, struct ast_sockaddr *addr)
 
int ast_udptl_proto_register (struct ast_udptl_protocol *proto)
 
void ast_udptl_proto_unregister (struct ast_udptl_protocol *proto)
 
struct ast_frameast_udptl_read (struct ast_udptl *udptl)
 
int ast_udptl_reload (void)
 
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)
 
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 struct ast_udptl_protocolget_proto (struct ast_channel *chan)
 
static char * handle_cli_udptl_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int udptl_build_packet (struct ast_udptl *s, uint8_t *buf, unsigned int buflen, uint8_t *ifp, unsigned int ifp_len)
 
static int udptl_debug_test_addr (const struct ast_sockaddr *addr)
 
static int udptl_rx_packet (struct ast_udptl *s, uint8_t *buf, unsigned int len)
 
static void udptl_shutdown (void)
 
static int udptlread (int *id, int fd, short events, void *cbdata)
 

Variables

static struct ast_cli_entry cli_udptl []
 
static struct protos protos = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
 
static int udptldebug
 
static struct ast_sockaddr udptldebugaddr
 
static int udptlend = 4599
 
static int udptlfecentries
 
static int udptlfecspan
 
static int udptlstart = 4500
 
static int use_even_ports
 

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

#define DEFAULT_FAX_MAX_DATAGRAM   400

Definition at line 97 of file udptl.c.

Referenced by ast_udptl_set_far_max_datagram(), and ast_udptl_write().

#define FALSE   0

Definition at line 77 of file udptl.c.

#define FAX_MAX_DATAGRAM_LIMIT   1400

Definition at line 98 of file udptl.c.

Referenced by ast_udptl_set_far_max_datagram().

#define LOCAL_FAX_MAX_DATAGRAM   1400

Definition at line 96 of file udptl.c.

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

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

Definition at line 99 of file udptl.c.

Referenced by __ast_udptl_reload(), and udptl_rx_packet().

#define MAX_FEC_SPAN   5

Definition at line 100 of file udptl.c.

Referenced by __ast_udptl_reload().

#define TRUE   (!FALSE)

Definition at line 80 of file udptl.c.

Referenced by udptl_rx_packet().

#define UDPTL_BUF_MASK   15

Definition at line 102 of file udptl.c.

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

#define UDPTL_MTU   1200

Definition at line 74 of file udptl.c.

Function Documentation

static void __ast_udptl_reload ( int  reload)
static

Definition at line 1321 of file udptl.c.

References ast_config_destroy(), ast_config_load2(), ast_false(), ast_log(), ast_true(), ast_variable_retrieve(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, LOG_NOTICE, LOG_WARNING, MAX_FEC_ENTRIES, MAX_FEC_SPAN, udptlend, and udptlstart.

Referenced by ast_udptl_init(), and ast_udptl_reload().

1322 {
1323  struct ast_config *cfg;
1324  const char *s;
1325  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1326 
1327  cfg = ast_config_load2("udptl.conf", "udptl", config_flags);
1329  return;
1330  }
1331 
1332  udptlstart = 4500;
1333  udptlend = 4999;
1334  udptlfecentries = 0;
1335  udptlfecspan = 0;
1336  use_even_ports = 0;
1337 
1338  if (cfg) {
1339  if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
1340  udptlstart = atoi(s);
1341  if (udptlstart < 1024) {
1342  ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
1343  udptlstart = 1024;
1344  }
1345  if (udptlstart > 65535) {
1346  ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
1347  udptlstart = 65535;
1348  }
1349  }
1350  if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
1351  udptlend = atoi(s);
1352  if (udptlend < 1024) {
1353  ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
1354  udptlend = 1024;
1355  }
1356  if (udptlend > 65535) {
1357  ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
1358  udptlend = 65535;
1359  }
1360  }
1361  if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
1362 #ifdef SO_NO_CHECK
1363  if (ast_false(s))
1364  nochecksums = 1;
1365  else
1366  nochecksums = 0;
1367 #else
1368  if (ast_false(s))
1369  ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n");
1370 #endif
1371  }
1372  if (ast_variable_retrieve(cfg, "general", "T38FaxUdpEC")) {
1373  ast_log(LOG_WARNING, "T38FaxUdpEC in udptl.conf is no longer supported; use the t38pt_udptl configuration option in sip.conf instead.\n");
1374  }
1375  if (ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram")) {
1376  ast_log(LOG_WARNING, "T38FaxMaxDatagram in udptl.conf is no longer supported; value is now supplied by T.38 applications.\n");
1377  }
1378  if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECEntries"))) {
1379  udptlfecentries = atoi(s);
1380  if (udptlfecentries < 1) {
1381  ast_log(LOG_WARNING, "Too small UDPTLFECEntries value. Defaulting to 1.\n");
1382  udptlfecentries = 1;
1383  }
1385  ast_log(LOG_WARNING, "Too large UDPTLFECEntries value. Defaulting to %d.\n", MAX_FEC_ENTRIES);
1387  }
1388  }
1389  if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECSpan"))) {
1390  udptlfecspan = atoi(s);
1391  if (udptlfecspan < 1) {
1392  ast_log(LOG_WARNING, "Too small UDPTLFECSpan value. Defaulting to 1.\n");
1393  udptlfecspan = 1;
1394  }
1395  if (udptlfecspan > MAX_FEC_SPAN) {
1396  ast_log(LOG_WARNING, "Too large UDPTLFECSpan value. Defaulting to %d.\n", MAX_FEC_SPAN);
1398  }
1399  }
1400  if ((s = ast_variable_retrieve(cfg, "general", "use_even_ports"))) {
1401  use_even_ports = ast_true(s);
1402  }
1403  ast_config_destroy(cfg);
1404  }
1405  if (udptlstart >= udptlend) {
1406  ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end ports; defaulting to 4500-4999.\n");
1407  udptlstart = 4500;
1408  udptlend = 4999;
1409  }
1410  if (use_even_ports && (udptlstart & 1)) {
1411  ++udptlstart;
1412  ast_log(LOG_NOTICE, "Odd numbered udptlstart specified but use_even_ports enabled. udptlstart is now %d\n", udptlstart);
1413  }
1414  if (use_even_ports && (udptlend & 1)) {
1415  --udptlend;
1416  ast_log(LOG_NOTICE, "Odd numbered udptlend specified but use_event_ports enabled. udptlend is now %d\n", udptlend);
1417  }
1418  ast_verb(2, "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend);
1419 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define LOG_WARNING
Definition: logger.h:144
static int udptlstart
Definition: udptl.c:85
static int use_even_ports
Definition: udptl.c:94
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
static int udptlfecspan
Definition: udptl.c:93
static int reload(void)
Definition: app_amd.c:497
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int udptlend
Definition: udptl.c:86
Structure used to handle boolean flags.
Definition: utils.h:200
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
#define MAX_FEC_SPAN
Definition: udptl.c:100
#define MAX_FEC_ENTRIES
Definition: udptl.c:99
static int udptlfecentries
Definition: udptl.c:92
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
int ast_udptl_bridge ( struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc 
)

Definition at line 1146 of file udptl.c.

References ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_debug, AST_FRAME_MODEM, ast_frfree, ast_log(), ast_read(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_udptl_get_peer(), ast_waitfor_n(), ast_write(), f, ast_frame::frametype, get_proto(), ast_udptl_protocol::get_udptl_info, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_udptl_protocol::set_udptl_peer, and ast_channel::tech_pvt.

1147 {
1148  struct ast_frame *f;
1149  struct ast_channel *who;
1150  struct ast_channel *cs[3];
1151  struct ast_udptl *p0;
1152  struct ast_udptl *p1;
1153  struct ast_udptl_protocol *pr0;
1154  struct ast_udptl_protocol *pr1;
1155  struct ast_sockaddr ac0;
1156  struct ast_sockaddr ac1;
1157  struct ast_sockaddr t0;
1158  struct ast_sockaddr t1;
1159  void *pvt0;
1160  void *pvt1;
1161  int to;
1162 
1163  ast_channel_lock(c0);
1164  while (ast_channel_trylock(c1)) {
1165  ast_channel_unlock(c0);
1166  usleep(1);
1167  ast_channel_lock(c0);
1168  }
1169  pr0 = get_proto(c0);
1170  pr1 = get_proto(c1);
1171  if (!pr0) {
1172  ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
1173  ast_channel_unlock(c0);
1174  ast_channel_unlock(c1);
1175  return -1;
1176  }
1177  if (!pr1) {
1178  ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
1179  ast_channel_unlock(c0);
1180  ast_channel_unlock(c1);
1181  return -1;
1182  }
1183  pvt0 = c0->tech_pvt;
1184  pvt1 = c1->tech_pvt;
1185  p0 = pr0->get_udptl_info(c0);
1186  p1 = pr1->get_udptl_info(c1);
1187  if (!p0 || !p1) {
1188  /* Somebody doesn't want to play... */
1189  ast_channel_unlock(c0);
1190  ast_channel_unlock(c1);
1191  return -2;
1192  }
1193  if (pr0->set_udptl_peer(c0, p1)) {
1194  ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
1195  memset(&ac1, 0, sizeof(ac1));
1196  } else {
1197  /* Store UDPTL peer */
1198  ast_udptl_get_peer(p1, &ac1);
1199  }
1200  if (pr1->set_udptl_peer(c1, p0)) {
1201  ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
1202  memset(&ac0, 0, sizeof(ac0));
1203  } else {
1204  /* Store UDPTL peer */
1205  ast_udptl_get_peer(p0, &ac0);
1206  }
1207  ast_channel_unlock(c0);
1208  ast_channel_unlock(c1);
1209  cs[0] = c0;
1210  cs[1] = c1;
1211  cs[2] = NULL;
1212  for (;;) {
1213  if ((c0->tech_pvt != pvt0) ||
1214  (c1->tech_pvt != pvt1) ||
1215  (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
1216  ast_debug(1, "Oooh, something is weird, backing out\n");
1217  /* Tell it to try again later */
1218  return -3;
1219  }
1220  to = -1;
1221  ast_udptl_get_peer(p1, &t1);
1222  ast_udptl_get_peer(p0, &t0);
1223  if (ast_sockaddr_cmp(&t1, &ac1)) {
1224  ast_debug(1, "Oooh, '%s' changed end address to %s\n",
1225  c1->name, ast_sockaddr_stringify(&t1));
1226  ast_debug(1, "Oooh, '%s' was %s\n",
1227  c1->name, ast_sockaddr_stringify(&ac1));
1228  ast_sockaddr_copy(&ac1, &t1);
1229  }
1230  if (ast_sockaddr_cmp(&t0, &ac0)) {
1231  ast_debug(1, "Oooh, '%s' changed end address to %s\n",
1232  c0->name, ast_sockaddr_stringify(&t0));
1233  ast_debug(1, "Oooh, '%s' was %s\n",
1234  c0->name, ast_sockaddr_stringify(&ac0));
1235  ast_sockaddr_copy(&ac0, &t0);
1236  }
1237  who = ast_waitfor_n(cs, 2, &to);
1238  if (!who) {
1239  ast_debug(1, "Ooh, empty read...\n");
1240  /* check for hangup / whentohangup */
1241  if (ast_check_hangup(c0) || ast_check_hangup(c1))
1242  break;
1243  continue;
1244  }
1245  f = ast_read(who);
1246  if (!f) {
1247  *fo = f;
1248  *rc = who;
1249  ast_debug(1, "Oooh, got a %s\n", f ? "digit" : "hangup");
1250  /* That's all we needed */
1251  return 0;
1252  } else {
1253  if (f->frametype == AST_FRAME_MODEM) {
1254  /* Forward T.38 frames if they happen upon us */
1255  if (who == c0) {
1256  ast_write(c1, f);
1257  } else if (who == c1) {
1258  ast_write(c0, f);
1259  }
1260  }
1261  ast_frfree(f);
1262  }
1263  /* Swap priority. Not that it's a big deal at this point */
1264  cs[2] = cs[0];
1265  cs[0] = cs[1];
1266  cs[1] = cs[2];
1267  }
1268  return -1;
1269 }
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
Definition: channel.c:3534
struct ast_channel * masqr
Definition: channel.h:752
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
struct ast_channel * masq
Definition: channel.h:751
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:121
void * tech_pvt
Definition: channel.h:744
#define LOG_WARNING
Definition: logger.h:144
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4383
int(*const set_udptl_peer)(struct ast_channel *chan, struct ast_udptl *peer)
Set UDPTL peer.
Definition: udptl.h:51
Structure for an UDPTL session.
Definition: udptl.c:119
void ast_udptl_get_peer(const struct ast_udptl *udptl, struct ast_sockaddr *them)
Definition: udptl.c:1029
struct ast_udptl *(* get_udptl_info)(struct ast_channel *chan)
Get UDPTL struct, or NULL if unwilling to transfer.
Definition: udptl.h:49
static struct ast_udptl_protocol * get_proto(struct ast_channel *chan)
Definition: udptl.c:1132
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
Socket address structure.
Definition: netsock2.h:63
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:806
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static struct ast_format f[]
Definition: format_g726.c:181
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition: channel.c:4916
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_channel_trylock(chan)
Definition: channel.h:2468
#define ast_frfree(fr)
Definition: frame.h:583
static uint16_t t1
Definition: res_pktccops.c:159
void ast_udptl_destroy ( struct ast_udptl udptl)

Definition at line 1044 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 __sip_destroy().

1045 {
1046  if (udptl->ioid)
1047  ast_io_remove(udptl->io, udptl->ioid);
1048  if (udptl->fd > -1)
1049  close(udptl->fd);
1050  if (udptl->tag)
1051  ast_free(udptl->tag);
1052  ast_free(udptl);
1053 }
int fd
Definition: udptl.c:120
int * ioid
Definition: udptl.c:129
char * tag
Definition: udptl.c:133
struct io_context * io
Definition: udptl.c:131
#define ast_free(a)
Definition: astmm.h:97
int ast_io_remove(struct io_context *ioc, int *id)
Removes an IO context.
Definition: io.c:240
int ast_udptl_fd ( const struct ast_udptl udptl)

Definition at line 643 of file udptl.c.

References ast_udptl::fd.

Referenced by __oh323_new(), initialize_udptl(), and sip_new().

644 {
645  return udptl->fd;
646 }
int fd
Definition: udptl.c:120
enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme ( const struct ast_udptl udptl)

Definition at line 841 of file udptl.c.

References ast_udptl::error_correction_scheme.

Referenced by add_sdp().

842 {
843  return udptl->error_correction_scheme;
844 }
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:139
unsigned int ast_udptl_get_far_max_datagram ( const struct ast_udptl udptl)

Definition at line 909 of file udptl.c.

References ast_udptl::far_max_datagram.

Referenced by process_sdp().

910 {
911  if (udptl->far_max_datagram < 0) {
912  return 0;
913  }
914  return udptl->far_max_datagram;
915 }
int far_max_datagram
Definition: udptl.c:154
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 917 of file udptl.c.

References calculate_far_max_ifp(), and ast_udptl::far_max_ifp.

Referenced by change_t38_state(), and interpret_t38_parameters().

918 {
919  if (udptl->far_max_ifp == -1) {
920  calculate_far_max_ifp(udptl);
921  }
922 
923  if (udptl->far_max_ifp < 0) {
924  return 0;
925  }
926  return udptl->far_max_ifp;
927 }
int far_max_ifp
Definition: udptl.c:168
static void calculate_far_max_ifp(struct ast_udptl *udptl)
Definition: udptl.c:773
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 885 of file udptl.c.

References calculate_local_max_datagram(), and ast_udptl::local_max_datagram.

Referenced by add_sdp().

886 {
887  if (udptl->local_max_datagram == -1) {
889  }
890 
891  /* this function expects a unsigned value in return. */
892  if (udptl->local_max_datagram < 0) {
893  return 0;
894  }
895  return udptl->local_max_datagram;
896 }
int local_max_datagram
Definition: udptl.c:160
static void calculate_local_max_datagram(struct ast_udptl *udptl)
Definition: udptl.c:732
void ast_udptl_get_peer ( const struct ast_udptl udptl,
struct ast_sockaddr them 
)

Definition at line 1029 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::them.

Referenced by ast_udptl_bridge(), and sip_set_udptl_peer().

1030 {
1031  ast_sockaddr_copy(them, &udptl->them);
1032 }
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:121
struct ast_sockaddr them
Definition: udptl.c:128
void ast_udptl_get_us ( const struct ast_udptl udptl,
struct ast_sockaddr us 
)

Definition at line 1034 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::us.

Referenced by add_sdp().

1035 {
1036  ast_sockaddr_copy(us, &udptl->us);
1037 }
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:121
struct ast_sockaddr us
Definition: udptl.c:127
void ast_udptl_init ( void  )

Definition at line 1436 of file udptl.c.

References __ast_udptl_reload(), ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), and udptl_shutdown().

Referenced by main().

1437 {
1438  __ast_udptl_reload(0);
1439 
1441 
1443 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void __ast_udptl_reload(int reload)
Definition: udptl.c:1321
static void udptl_shutdown(void)
Definition: udptl.c:1431
int ast_register_atexit(void(*func)(void))
Register a function to be executed before Asterisk exits.
Definition: asterisk.c:998
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static struct ast_cli_entry cli_udptl[]
Definition: udptl.c:1317
struct ast_udptl* ast_udptl_new_with_bindaddr ( struct sched_context sched,
struct io_context io,
int  callbackmode,
struct ast_sockaddr addr 
)

Definition at line 929 of file udptl.c.

References 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, 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, ast_udptl::flags, ast_udptl::io, io, ast_udptl::ioid, ast_udptl::local_max_datagram, ast_udptl::local_max_ifp, LOG_WARNING, ast_udptl::rx, ast_udptl::sched, sched, ast_udptl::tx, UDPTL_BUF_MASK, udptlend, udptlfecentries, udptlfecspan, udptlread(), udptlstart, and ast_udptl::us.

Referenced by initialize_udptl().

930 {
931  struct ast_udptl *udptl;
932  int x;
933  int startplace;
934  int i;
935  long int flags;
936 
937  if (!(udptl = ast_calloc(1, sizeof(*udptl))))
938  return NULL;
939 
942 
943  udptl->far_max_datagram = -1;
944  udptl->far_max_ifp = -1;
945  udptl->local_max_ifp = -1;
946  udptl->local_max_datagram = -1;
947 
948  for (i = 0; i <= UDPTL_BUF_MASK; i++) {
949  udptl->rx[i].buf_len = -1;
950  udptl->tx[i].buf_len = -1;
951  }
952 
953  if ((udptl->fd = socket(ast_sockaddr_is_ipv6(addr) ?
954  AF_INET6 : AF_INET, SOCK_DGRAM, 0)) < 0) {
955  ast_free(udptl);
956  ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
957  return NULL;
958  }
959  flags = fcntl(udptl->fd, F_GETFL);
960  fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
961 #ifdef SO_NO_CHECK
962  if (nochecksums)
963  setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
964 #endif
965  /* Find us a place */
967  if (use_even_ports && (x & 1)) {
968  ++x;
969  }
970  startplace = x;
971  for (;;) {
972  ast_sockaddr_copy(&udptl->us, addr);
973  ast_sockaddr_set_port(&udptl->us, x);
974  if (ast_bind(udptl->fd, &udptl->us) == 0) {
975  break;
976  }
977  if (errno != EADDRINUSE && errno != EACCES) {
978  ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
979  close(udptl->fd);
980  ast_free(udptl);
981  return NULL;
982  }
983  if (use_even_ports) {
984  x += 2;
985  } else {
986  ++x;
987  }
988  if (x > udptlend)
989  x = udptlstart;
990  if (x == startplace) {
991  ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
992  close(udptl->fd);
993  ast_free(udptl);
994  return NULL;
995  }
996  }
997  if (io && sched && callbackmode) {
998  /* Operate this one in a callback mode */
999  udptl->sched = sched;
1000  udptl->io = io;
1001  udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
1002  }
1003  return udptl;
1004 }
int fd
Definition: udptl.c:120
unsigned int error_correction_span
Definition: udptl.c:149
static struct io_context * io
Definition: chan_gtalk.c:228
int local_max_datagram
Definition: udptl.c:160
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:121
#define LOG_WARNING
Definition: logger.h:144
static int udptlstart
Definition: udptl.c:85
int * ioid
Definition: udptl.c:129
#define AST_IO_IN
Definition: io.h:33
Structure for an UDPTL session.
Definition: udptl.c:119
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:157
unsigned int error_correction_entries
Definition: udptl.c:144
struct ast_sockaddr us
Definition: udptl.c:127
static int use_even_ports
Definition: udptl.c:94
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:462
struct sched_context * sched
Definition: chan_sip.c:782
int far_max_datagram
Definition: udptl.c:154
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK+1]
Definition: udptl.c:180
long int ast_random(void)
Definition: utils.c:1640
static int udptlfecspan
Definition: udptl.c:93
static int udptlread(int *id, int fd, short events, void *cbdata)
Definition: udptl.c:663
struct io_context * io
Definition: udptl.c:131
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define ast_free(a)
Definition: astmm.h:97
static int udptlend
Definition: udptl.c:86
int far_max_ifp
Definition: udptl.c:168
int flags
Definition: udptl.c:126
struct sched_context * sched
Definition: udptl.c:130
#define ast_calloc(a, b)
Definition: astmm.h:82
int local_max_ifp
Definition: udptl.c:174
static int udptlfecentries
Definition: udptl.c:92
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK+1]
Definition: udptl.c:179
#define UDPTL_BUF_MASK
Definition: udptl.c:102
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
int ast_udptl_proto_register ( struct ast_udptl_protocol proto)

Definition at line 1115 of file udptl.c.

References ast_log(), AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, LOG_WARNING, and ast_udptl_protocol::type.

Referenced by load_module().

1116 {
1117  struct ast_udptl_protocol *cur;
1118 
1120  AST_RWLIST_TRAVERSE(&protos, cur, list) {
1121  if (cur->type == proto->type) {
1122  ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
1124  return -1;
1125  }
1126  }
1127  AST_RWLIST_INSERT_TAIL(&protos, proto, list);
1129  return 0;
1130 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:144
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: udptl.c:183
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:726
const char *const type
Definition: udptl.h:52
void ast_udptl_proto_unregister ( struct ast_udptl_protocol proto)

Definition at line 1108 of file udptl.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by unload_module().

1109 {
1111  AST_RWLIST_REMOVE(&protos, proto, list);
1113 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: udptl.c:183
#define AST_RWLIST_REMOVE
Definition: linkedlists.h:870
struct ast_frame* ast_udptl_read ( struct ast_udptl udptl)

Definition at line 675 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, errno, ast_udptl::f, ast_udptl::fd, LOG_TAG, LOG_WARNING, ast_udptl::nat, ast_udptl::rawdata, ast_udptl::them, udptl_debug_test_addr(), and udptl_rx_packet().

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

676 {
677  int res;
678  struct ast_sockaddr addr;
679  uint8_t *buf;
680 
681  buf = udptl->rawdata + AST_FRIENDLY_OFFSET;
682 
683  /* Cache where the header will go */
684  res = ast_recvfrom(udptl->fd,
685  buf,
686  sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
687  0,
688  &addr);
689  if (res < 0) {
690  if (errno != EAGAIN)
691  ast_log(LOG_WARNING, "UDPTL (%s): read error: %s\n",
692  LOG_TAG(udptl), strerror(errno));
693  ast_assert(errno != EBADF);
694  return &ast_null_frame;
695  }
696 
697  /* Ignore if the other side hasn't been given an address yet. */
698  if (ast_sockaddr_isnull(&udptl->them)) {
699  return &ast_null_frame;
700  }
701 
702  if (udptl->nat) {
703  /* Send to whoever sent to us */
704  if (ast_sockaddr_cmp(&udptl->them, &addr)) {
705  ast_sockaddr_copy(&udptl->them, &addr);
706  ast_debug(1, "UDPTL (%s): NAT, Using address %s\n",
707  LOG_TAG(udptl), ast_sockaddr_stringify(&udptl->them));
708  }
709  }
710 
711  if (udptl_debug_test_addr(&addr)) {
712  int seq_no;
713 
714  /* Decode sequence number just for verbose message. */
715  if (res < 2) {
716  /* Short packet. */
717  seq_no = -1;
718  } else {
719  seq_no = (buf[0] << 8) | buf[1];
720  }
721 
722  ast_verb(1, "UDPTL (%s): packet from %s (seq %d, len %d)\n",
723  LOG_TAG(udptl), ast_sockaddr_stringify(&addr), seq_no, res);
724  }
725  if (udptl_rx_packet(udptl, buf, res) < 1) {
726  return &ast_null_frame;
727  }
728 
729  return &udptl->f[0];
730 }
int fd
Definition: udptl.c:120
int nat
Definition: udptl.c:125
struct ast_frame ast_null_frame
Definition: frame.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:121
#define LOG_WARNING
Definition: logger.h:144
#define ast_assert(a)
Definition: utils.h:738
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
static int udptl_debug_test_addr(const struct ast_sockaddr *addr)
Definition: udptl.c:185
Socket address structure.
Definition: netsock2.h:63
#define ast_verb(level,...)
Definition: logger.h:243
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
struct ast_sockaddr them
Definition: udptl.c:128
#define LOG_TAG(u)
Definition: udptl.c:83
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
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:478
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
struct ast_frame f[16]
Definition: udptl.c:122
unsigned char rawdata[8192+AST_FRIENDLY_OFFSET]
Definition: udptl.c:123
static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
Definition: udptl.c:310
int ast_udptl_reload ( void  )
Version
1.6.1 return changed to int

Definition at line 1421 of file udptl.c.

References __ast_udptl_reload().

1422 {
1423  __ast_udptl_reload(1);
1424  return 0;
1425 }
static void __ast_udptl_reload(int reload)
Definition: udptl.c:1321
void ast_udptl_set_callback ( struct ast_udptl udptl,
ast_udptl_callback  callback 
)

Definition at line 653 of file udptl.c.

References ast_udptl::callback.

654 {
655  udptl->callback = callback;
656 }
ast_udptl_callback callback
Definition: udptl.c:134
void ast_udptl_set_data ( struct ast_udptl udptl,
void *  data 
)

Definition at line 648 of file udptl.c.

References ast_udptl::data.

649 {
650  udptl->data = data;
651 }
void * data
Definition: udptl.c:132
void ast_udptl_set_error_correction_scheme ( struct ast_udptl udptl,
enum ast_t38_ec_modes  ec 
)

Definition at line 846 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(), and set_t38_capabilities().

847 {
848  udptl->error_correction_scheme = ec;
849  switch (ec) {
852  if (udptl->error_correction_entries == 0) {
853  udptl->error_correction_entries = 3;
854  }
855  if (udptl->error_correction_span == 0) {
856  udptl->error_correction_span = 3;
857  }
858  break;
861  if (udptl->error_correction_entries == 0) {
862  udptl->error_correction_entries = 3;
863  }
864  break;
865  default:
866  /* nothing to do */
867  break;
868  };
869  /* reset calculated values so they'll be computed again */
870  udptl->local_max_datagram = -1;
871  udptl->far_max_ifp = -1;
872 }
unsigned int error_correction_span
Definition: udptl.c:149
int local_max_datagram
Definition: udptl.c:160
unsigned int error_correction_entries
Definition: udptl.c:144
int far_max_ifp
Definition: udptl.c:168
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:139
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 898 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 process_sdp(), and process_sdp_a_image().

899 {
900  if (!max_datagram || (max_datagram > FAX_MAX_DATAGRAM_LIMIT)) {
902  } else {
903  udptl->far_max_datagram = max_datagram;
904  }
905  /* reset calculated values so they'll be computed again */
906  udptl->far_max_ifp = -1;
907 }
int far_max_datagram
Definition: udptl.c:154
int far_max_ifp
Definition: udptl.c:168
#define FAX_MAX_DATAGRAM_LIMIT
Definition: udptl.c:98
#define DEFAULT_FAX_MAX_DATAGRAM
Definition: udptl.c:97
void ast_udptl_set_local_max_ifp ( struct ast_udptl udptl,
unsigned int  max_ifp 
)

Definition at line 874 of file udptl.c.

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

Referenced by interpret_t38_parameters().

875 {
876  /* make sure max_ifp is a positive value since a cast will take place when
877  * when setting local_max_ifp */
878  if ((signed int) max_ifp > 0) {
879  udptl->local_max_ifp = max_ifp;
880  /* reset calculated values so they'll be computed again */
881  udptl->local_max_datagram = -1;
882  }
883 }
int local_max_datagram
Definition: udptl.c:160
int local_max_ifp
Definition: udptl.c:174
void ast_udptl_set_peer ( struct ast_udptl udptl,
const struct ast_sockaddr them 
)

Definition at line 1024 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::them.

Referenced by process_sdp().

1025 {
1026  ast_sockaddr_copy(&udptl->them, them);
1027 }
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:121
struct ast_sockaddr them
Definition: udptl.c:128
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 1006 of file udptl.c.

References ast_free, ast_vasprintf, and ast_udptl::tag.

Referenced by change_t38_state().

1007 {
1008  va_list ap;
1009 
1010  ast_free(udptl->tag);
1011  udptl->tag = NULL;
1012  va_start(ap, format);
1013  if (ast_vasprintf(&udptl->tag, format, ap) == -1) {
1014  udptl->tag = NULL;
1015  }
1016  va_end(ap);
1017 }
#define ast_vasprintf(a, b, c)
Definition: astmm.h:127
char * tag
Definition: udptl.c:133
#define ast_free(a)
Definition: astmm.h:97
static snd_pcm_format_t format
Definition: chan_alsa.c:93
void ast_udptl_setnat ( struct ast_udptl udptl,
int  nat 
)

Definition at line 658 of file udptl.c.

References ast_udptl::nat, and nat.

Referenced by do_setnat(), and initialize_udptl().

659 {
660  udptl->nat = nat;
661 }
int nat
Definition: udptl.c:125
static int nat
Definition: chan_mgcp.c:161
int ast_udptl_setqos ( struct ast_udptl udptl,
unsigned int  tos,
unsigned int  cos 
)

Definition at line 1019 of file udptl.c.

References ast_netsock_set_qos(), and ast_udptl::fd.

Referenced by initialize_udptl().

1020 {
1021  return ast_netsock_set_qos(udptl->fd, tos, cos, "UDPTL");
1022 }
int fd
Definition: udptl.c:120
static unsigned int tos
Definition: chan_h323.c:146
int ast_netsock_set_qos(int netsocket, int tos, int cos, const char *desc)
Definition: netsock.c:158
static unsigned int cos
Definition: chan_h323.c:147
void ast_udptl_stop ( struct ast_udptl udptl)

Definition at line 1039 of file udptl.c.

References ast_sockaddr_setnull(), and ast_udptl::them.

Referenced by process_sdp(), and stop_media_flows().

1040 {
1041  ast_sockaddr_setnull(&udptl->them);
1042 }
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
struct ast_sockaddr them
Definition: udptl.c:128
int ast_udptl_write ( struct ast_udptl s,
struct ast_frame f 
)

Definition at line 1055 of file udptl.c.

References AST_FRAME_MODEM, ast_log(), AST_MODEM_T38, ast_sendto(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verb, ast_frame_subclass::codec, 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, 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 sip_write().

1056 {
1057  unsigned int seq;
1058  unsigned int len = f->datalen;
1059  int res;
1060  /* if no max datagram size is provided, use default value */
1061  const int bufsize = (s->far_max_datagram > 0) ? s->far_max_datagram : DEFAULT_FAX_MAX_DATAGRAM;
1062  uint8_t buf[bufsize];
1063 
1064  memset(buf, 0, sizeof(buf));
1065 
1066  /* If we have no peer, return immediately */
1067  if (ast_sockaddr_isnull(&s->them)) {
1068  return 0;
1069  }
1070 
1071  /* If there is no data length, return immediately */
1072  if (f->datalen == 0)
1073  return 0;
1074 
1075  if ((f->frametype != AST_FRAME_MODEM) ||
1076  (f->subclass.codec != AST_MODEM_T38)) {
1077  ast_log(LOG_WARNING, "UDPTL (%s): UDPTL can only send T.38 data.\n",
1078  LOG_TAG(s));
1079  return -1;
1080  }
1081 
1082  if (len > s->far_max_ifp) {
1084  "UDPTL (%s): UDPTL asked to send %u bytes of IFP when far end only prepared to accept %d bytes; data loss will occur."
1085  "You may need to override the T38FaxMaxDatagram value for this endpoint in the channel driver configuration.\n",
1086  LOG_TAG(s), len, s->far_max_ifp);
1087  len = s->far_max_ifp;
1088  }
1089 
1090  /* Save seq_no for debug output because udptl_build_packet increments it */
1091  seq = s->tx_seq_no & 0xFFFF;
1092 
1093  /* Cook up the UDPTL packet, with the relevant EC info. */
1094  len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, len);
1095 
1096  if ((signed int) len > 0 && !ast_sockaddr_isnull(&s->them)) {
1097  if ((res = ast_sendto(s->fd, buf, len, 0, &s->them)) < 0)
1098  ast_log(LOG_NOTICE, "UDPTL (%s): Transmission error to %s: %s\n",
1099  LOG_TAG(s), ast_sockaddr_stringify(&s->them), strerror(errno));
1100  if (udptl_debug_test_addr(&s->them))
1101  ast_verb(1, "UDPTL (%s): packet to %s (seq %u, len %u)\n",
1102  LOG_TAG(s), ast_sockaddr_stringify(&s->them), seq, len);
1103  }
1104 
1105  return 0;
1106 }
int fd
Definition: udptl.c:120
union ast_frame_subclass subclass
Definition: frame.h:146
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:486
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
#define AST_MODEM_T38
Definition: frame.h:216
format_t codec
Definition: frame.h:137
static int udptl_debug_test_addr(const struct ast_sockaddr *addr)
Definition: udptl.c:185
#define ast_verb(level,...)
Definition: logger.h:243
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
int far_max_datagram
Definition: udptl.c:154
int datalen
Definition: frame.h:148
struct ast_sockaddr them
Definition: udptl.c:128
unsigned int tx_seq_no
Definition: udptl.c:176
#define LOG_TAG(u)
Definition: udptl.c:83
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int errno
int far_max_ifp
Definition: udptl.c:168
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:532
static volatile unsigned int seq
Definition: app_sms.c:118
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
#define DEFAULT_FAX_MAX_DATAGRAM
Definition: udptl.c:97
static void calculate_far_max_ifp ( struct ast_udptl udptl)
static

Definition at line 773 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().

774 {
775  unsigned new_max = 0;
776 
777  if (udptl->far_max_datagram == -1) {
778  ast_log(LOG_WARNING, "UDPTL (%s): Cannot calculate far_max_ifp before far_max_datagram has been set.\n",
779  LOG_TAG(udptl));
780  udptl->far_max_ifp = -1;
781  return;
782  }
783 
784  /* the goal here is to supply the local endpoint (application
785  * or bridged channel) a maximum IFP value that will allow it
786  * to effectively and efficiently transfer image data at its
787  * selected bit rate, taking into account the selected error
788  * correction mode, but without overrunning the far endpoint's
789  * datagram buffer. this is complicated by the fact that some
790  * far endpoints send us bogus (small) max datagram values,
791  * which would result in either buffer overrun or no error
792  * correction. we try to accomodate those, but if the supplied
793  * value is too small to do so, we'll emit warning messages and
794  * the user will have to use configuration options to override
795  * the max datagram value supplied by the far endpoint.
796  */
797  switch (udptl->error_correction_scheme) {
799  /* need room for sequence number, length indicator, redundancy
800  * indicator and following length indicator
801  */
802  new_max = udptl->far_max_datagram - 5;
803  break;
805  /* for this case, we'd like to send as many error correction entries
806  * as possible (up to the number we're configured for), but we'll settle
807  * for sending fewer if the configured number would cause the
808  * calculated max IFP to be too small for effective operation
809  *
810  * need room for sequence number, length indicators and the
811  * configured number of redundant packets
812  *
813  * note: we purposely don't allow error_correction_entries to drop to
814  * zero in this loop; we'd rather send smaller IFPs (and thus reduce
815  * the image data transfer rate) than sacrifice redundancy completely
816  */
817  for (;;) {
818  new_max = (udptl->far_max_datagram - 8) / (udptl->error_correction_entries + 1);
819 
820  if ((new_max < 80) && (udptl->error_correction_entries > 1)) {
821  /* the max ifp is not large enough, subtract an
822  * error correction entry and calculate again
823  * */
824  --udptl->error_correction_entries;
825  } else {
826  break;
827  }
828  }
829  break;
831  /* need room for sequence number, length indicators and a
832  * a single IFP of the maximum size expected
833  */
834  new_max = (udptl->far_max_datagram - 10) / 2;
835  break;
836  }
837  /* subtract 5% of space for insurance */
838  udptl->far_max_ifp = new_max * 0.95;
839 }
#define LOG_WARNING
Definition: logger.h:144
unsigned int error_correction_entries
Definition: udptl.c:144
int far_max_datagram
Definition: udptl.c:154
#define LOG_TAG(u)
Definition: udptl.c:83
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int far_max_ifp
Definition: udptl.c:168
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:139
static void calculate_local_max_datagram ( struct ast_udptl udptl)
static

Definition at line 732 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().

733 {
734  unsigned int new_max = 0;
735 
736  if (udptl->local_max_ifp == -1) {
737  ast_log(LOG_WARNING, "UDPTL (%s): Cannot calculate local_max_datagram before local_max_ifp has been set.\n",
738  LOG_TAG(udptl));
739  udptl->local_max_datagram = -1;
740  return;
741  }
742 
743  /* calculate the amount of space required to receive an IFP
744  * of the maximum size supported by the application/endpoint
745  * that we are delivering them to (local endpoint), and add
746  * the amount of space required to support the selected
747  * error correction mode
748  */
749  switch (udptl->error_correction_scheme) {
751  /* need room for sequence number, length indicator, redundancy
752  * indicator and following length indicator
753  */
754  new_max = 5 + udptl->local_max_ifp;
755  break;
757  /* need room for sequence number, length indicators, plus
758  * room for up to 3 redundancy packets
759  */
760  new_max = 5 + udptl->local_max_ifp + 2 + (3 * udptl->local_max_ifp);
761  break;
763  /* need room for sequence number, length indicators and a
764  * a single IFP of the maximum size expected
765  */
766  new_max = 5 + udptl->local_max_ifp + 4 + udptl->local_max_ifp;
767  break;
768  }
769  /* add 5% extra space for insurance, but no larger than LOCAL_FAX_MAX_DATAGRAM */
770  udptl->local_max_datagram = MIN(new_max * 1.05, LOCAL_FAX_MAX_DATAGRAM);
771 }
int local_max_datagram
Definition: udptl.c:160
#define LOG_WARNING
Definition: logger.h:144
#define MIN(a, b)
Definition: utils.h:226
#define LOCAL_FAX_MAX_DATAGRAM
Definition: udptl.c:96
#define LOG_TAG(u)
Definition: udptl.c:83
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int local_max_ifp
Definition: udptl.c:174
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:139
static int decode_length ( uint8_t *  buf,
unsigned int  limit,
unsigned int *  len,
unsigned int *  pvalue 
)
static

Definition at line 201 of file udptl.c.

References ast_debug, and len().

Referenced by decode_open_type(), and udptl_rx_packet().

202 {
203  if (*len >= limit)
204  return -1;
205  if ((buf[*len] & 0x80) == 0) {
206  *pvalue = buf[*len];
207  (*len)++;
208  return 0;
209  }
210  if ((buf[*len] & 0x40) == 0) {
211  if (*len == limit - 1)
212  return -1;
213  *pvalue = (buf[*len] & 0x3F) << 8;
214  (*len)++;
215  *pvalue |= buf[*len];
216  (*len)++;
217  return 0;
218  }
219  *pvalue = (buf[*len] & 0x3F) << 14;
220  (*len)++;
221  /* We have a fragment. Currently we don't process fragments. */
222  ast_debug(1, "UDPTL packet with length greater than 16K received, decoding will fail\n");
223  return 1;
224 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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 227 of file udptl.c.

References decode_length(), and len().

Referenced by udptl_rx_packet().

228 {
229  unsigned int octet_cnt = 0;
230 
231  if (decode_length(buf, limit, len, &octet_cnt) != 0)
232  return -1;
233 
234  if (octet_cnt > 0) {
235  /* Make sure the buffer contains at least the number of bits requested */
236  if ((*len + octet_cnt) > limit)
237  return -1;
238 
239  *p_num_octets = octet_cnt;
240  *p_object = &buf[*len];
241  *len += octet_cnt;
242  }
243 
244  return 0;
245 }
static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
Definition: udptl.c:201
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static unsigned int encode_length ( uint8_t *  buf,
unsigned int *  len,
unsigned int  value 
)
static

Definition at line 248 of file udptl.c.

References len(), and value.

Referenced by encode_open_type(), and udptl_build_packet().

249 {
250  unsigned int multiplier;
251 
252  if (value < 0x80) {
253  /* 1 octet */
254  buf[*len] = value;
255  (*len)++;
256  return value;
257  }
258  if (value < 0x4000) {
259  /* 2 octets */
260  /* Set the first bit of the first octet */
261  buf[*len] = ((0x8000 | value) >> 8) & 0xFF;
262  (*len)++;
263  buf[*len] = value & 0xFF;
264  (*len)++;
265  return value;
266  }
267  /* Fragmentation */
268  multiplier = (value < 0x10000) ? (value >> 14) : 4;
269  /* Set the first 2 bits of the octet */
270  buf[*len] = 0xC0 | multiplier;
271  (*len)++;
272  return multiplier << 14;
273 }
int value
Definition: syslog.c:39
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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 276 of file udptl.c.

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

Referenced by udptl_build_packet().

278 {
279  unsigned int enclen;
280  unsigned int octet_idx;
281  uint8_t zero_byte;
282 
283  /* If open type is of zero length, add a single zero byte (10.1) */
284  if (num_octets == 0) {
285  zero_byte = 0;
286  data = &zero_byte;
287  num_octets = 1;
288  }
289  /* Encode the open type */
290  for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
291  if ((enclen = encode_length(buf, len, num_octets)) < 0)
292  return -1;
293  if (enclen + *len > buflen) {
294  ast_log(LOG_ERROR, "UDPTL (%s): Buffer overflow detected (%u + %u > %u)\n",
295  LOG_TAG(udptl), enclen, *len, buflen);
296  return -1;
297  }
298  if (enclen > 0) {
299  memcpy(&buf[*len], &data[octet_idx], enclen);
300  *len += enclen;
301  }
302  if (enclen >= num_octets)
303  break;
304  }
305 
306  return 0;
307 }
static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
Definition: udptl.c:248
#define LOG_TAG(u)
Definition: udptl.c:83
#define LOG_ERROR
Definition: logger.h:155
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_udptl_protocol* get_proto ( struct ast_channel chan)
static

Definition at line 1132 of file udptl.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_channel::tech, ast_udptl_protocol::type, and ast_channel_tech::type.

Referenced by ast_udptl_bridge().

1133 {
1134  struct ast_udptl_protocol *cur = NULL;
1135 
1137  AST_RWLIST_TRAVERSE(&protos, cur, list) {
1138  if (cur->type == chan->tech->type)
1139  break;
1140  }
1142 
1143  return cur;
1144 }
const char *const type
Definition: channel.h:508
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Definition: udptl.c:183
const char *const type
Definition: udptl.h:52
struct ast_channel_tech * tech
Definition: channel.h:743
static char* handle_cli_udptl_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1271 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, udptldebugaddr, and ast_cli_entry::usage.

1272 {
1273  switch (cmd) {
1274  case CLI_INIT:
1275  e->command = "udptl set debug {on|off|ip}";
1276  e->usage =
1277  "Usage: udptl set debug {on|off|ip host[:port]}\n"
1278  " Enable or disable dumping of UDPTL packets.\n"
1279  " If ip is specified, limit the dumped packets to those to and from\n"
1280  " the specified 'host' with optional port.\n";
1281  return NULL;
1282  case CLI_GENERATE:
1283  return NULL;
1284  }
1285 
1286  if (a->argc < 4 || a->argc > 5)
1287  return CLI_SHOWUSAGE;
1288 
1289  if (a->argc == 4) {
1290  if (!strncasecmp(a->argv[3], "on", 2)) {
1291  udptldebug = 1;
1292  memset(&udptldebugaddr, 0, sizeof(udptldebugaddr));
1293  ast_cli(a->fd, "UDPTL Debugging Enabled\n");
1294  } else if (!strncasecmp(a->argv[3], "off", 3)) {
1295  udptldebug = 0;
1296  ast_cli(a->fd, "UDPTL Debugging Disabled\n");
1297  } else {
1298  return CLI_SHOWUSAGE;
1299  }
1300  } else {
1301  struct ast_sockaddr *addrs;
1302  if (strncasecmp(a->argv[3], "ip", 2))
1303  return CLI_SHOWUSAGE;
1304  if (!ast_sockaddr_resolve(&addrs, a->argv[4], 0, 0)) {
1305  return CLI_SHOWUSAGE;
1306  }
1307  ast_sockaddr_copy(&udptldebugaddr, &addrs[0]);
1308  ast_cli(a->fd, "UDPTL Debugging Enabled for IP: %s\n", ast_sockaddr_stringify(&udptldebugaddr));
1309  udptldebug = 1;
1310  ast_free(addrs);
1311  }
1312 
1313  return CLI_SUCCESS;
1314 }
static struct ast_sockaddr udptldebugaddr
Definition: udptl.c:88
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:121
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
Socket address structure.
Definition: netsock2.h:63
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
#define ast_free(a)
Definition: astmm.h:97
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
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:248
static int udptldebug
Definition: udptl.c:87
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 532 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, for(), 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().

533 {
534  uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2] = { 0, };
535  int i;
536  int j;
537  int seq;
538  int entry;
539  int entries;
540  int span;
541  int m;
542  unsigned int len;
543  int limit;
544  int high_tide;
545 
546  seq = s->tx_seq_no & 0xFFFF;
547 
548  /* Map the sequence number to an entry in the circular buffer */
549  entry = seq & UDPTL_BUF_MASK;
550 
551  /* We save the message in a circular buffer, for generating FEC or
552  redundancy sets later on. */
553  s->tx[entry].buf_len = ifp_len;
554  memcpy(s->tx[entry].buf, ifp, ifp_len);
555 
556  /* Build the UDPTLPacket */
557 
558  len = 0;
559  /* Encode the sequence number */
560  buf[len++] = (seq >> 8) & 0xFF;
561  buf[len++] = seq & 0xFF;
562 
563  /* Encode the primary IFP packet */
564  if (encode_open_type(s, buf, buflen, &len, ifp, ifp_len) < 0)
565  return -1;
566 
567  /* Encode the appropriate type of error recovery information */
568  switch (s->error_correction_scheme)
569  {
571  /* Encode the error recovery type */
572  buf[len++] = 0x00;
573  /* The number of entries will always be zero, so it is pointless allowing
574  for the fragmented case here. */
575  if (encode_length(buf, &len, 0) < 0)
576  return -1;
577  break;
579  /* Encode the error recovery type */
580  buf[len++] = 0x00;
582  entries = s->error_correction_entries;
583  else
584  entries = s->tx_seq_no;
585  /* The number of entries will always be small, so it is pointless allowing
586  for the fragmented case here. */
587  if (encode_length(buf, &len, entries) < 0)
588  return -1;
589  /* Encode the elements */
590  for (i = 0; i < entries; i++) {
591  j = (entry - i - 1) & UDPTL_BUF_MASK;
592  if (encode_open_type(s, buf, buflen, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) {
593  ast_debug(1, "UDPTL (%s): Encoding failed at i=%d, j=%d\n",
594  LOG_TAG(s), i, j);
595  return -1;
596  }
597  }
598  break;
600  span = s->error_correction_span;
601  entries = s->error_correction_entries;
602  if (seq < s->error_correction_span*s->error_correction_entries) {
603  /* In the initial stages, wind up the FEC smoothly */
604  entries = seq/s->error_correction_span;
605  if (seq < s->error_correction_span)
606  span = 0;
607  }
608  /* Encode the error recovery type */
609  buf[len++] = 0x80;
610  /* Span is defined as an inconstrained integer, which it dumb. It will only
611  ever be a small value. Treat it as such. */
612  buf[len++] = 1;
613  buf[len++] = span;
614  /* The number of entries is defined as a length, but will only ever be a small
615  value. Treat it as such. */
616  buf[len++] = entries;
617  for (m = 0; m < entries; m++) {
618  /* Make an XOR'ed entry the maximum length */
619  limit = (entry + m) & UDPTL_BUF_MASK;
620  high_tide = 0;
621  for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
622  if (high_tide < s->tx[i].buf_len) {
623  for (j = 0; j < high_tide; j++)
624  fec[j] ^= s->tx[i].buf[j];
625  for ( ; j < s->tx[i].buf_len; j++)
626  fec[j] = s->tx[i].buf[j];
627  high_tide = s->tx[i].buf_len;
628  } else {
629  for (j = 0; j < s->tx[i].buf_len; j++)
630  fec[j] ^= s->tx[i].buf[j];
631  }
632  }
633  if (encode_open_type(s, buf, buflen, &len, fec, high_tide) < 0)
634  return -1;
635  }
636  break;
637  }
638 
639  s->tx_seq_no++;
640  return len;
641 }
unsigned int error_correction_span
Definition: udptl.c:149
for(;;)
Definition: ast_expr2.c:2460
unsigned int error_correction_entries
Definition: udptl.c:144
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:106
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:276
static unsigned int encode_length(uint8_t *buf, unsigned int *len, unsigned int value)
Definition: udptl.c:248
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define LOCAL_FAX_MAX_DATAGRAM
Definition: udptl.c:96
unsigned int tx_seq_no
Definition: udptl.c:176
#define LOG_TAG(u)
Definition: udptl.c:83
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:118
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK+1]
Definition: udptl.c:179
#define UDPTL_BUF_MASK
Definition: udptl.c:102
enum ast_t38_ec_modes error_correction_scheme
Definition: udptl.c:139
static int udptl_debug_test_addr ( const struct ast_sockaddr addr)
inlinestatic

Definition at line 185 of file udptl.c.

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

Referenced by ast_udptl_read(), and ast_udptl_write().

186 {
187  if (udptldebug == 0)
188  return 0;
189 
191  return 1;
192  }
193 
195  return !ast_sockaddr_cmp(&udptldebugaddr, addr);
196  } else {
197  return !ast_sockaddr_cmp_addr(&udptldebugaddr, addr);
198  }
199 }
static struct ast_sockaddr udptldebugaddr
Definition: udptl.c:88
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
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:325
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
static int udptldebug
Definition: udptl.c:87
static int udptl_rx_packet ( struct ast_udptl s,
uint8_t *  buf,
unsigned int  len 
)
static

Definition at line 310 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_subclass::codec, 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, LOCAL_FAX_MAX_DATAGRAM, ast_frame::mallocd, MAX_FEC_ENTRIES, 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().

311 {
312  int stat1;
313  int stat2;
314  int i;
315  unsigned int ptr; /* an index that keeps track of how much of the UDPTL packet has been processed */
316  int seq_no;
317  const uint8_t *ifp = NULL;
318  const uint8_t *data = NULL;
319  unsigned int ifp_len = 0;
320  int repaired[16];
321  const uint8_t *bufs[ARRAY_LEN(s->f) - 1];
322  unsigned int lengths[ARRAY_LEN(s->f) - 1];
323  int span;
324  int entries;
325  int ifp_no;
326 
327  ptr = 0;
328  ifp_no = 0;
329  memset(&s->f[0], 0, sizeof(s->f[0]));
330 
331  /* Decode seq_number */
332  if (ptr + 2 > len)
333  return -1;
334  seq_no = (buf[0] << 8) | buf[1];
335  ptr += 2;
336 
337  /* Break out the primary packet */
338  if ((stat1 = decode_open_type(buf, len, &ptr, &ifp, &ifp_len)) != 0)
339  return -1;
340  /* Decode error_recovery */
341  if (ptr + 1 > len)
342  return -1;
343  if ((buf[ptr++] & 0x80) == 0) {
344  /* Secondary packet mode for error recovery */
345  if (seq_no > s->rx_seq_no) {
346  /* We received a later packet than we expected, so we need to check if we can fill in the gap from the
347  secondary packets. */
348  int total_count = 0;
349  do {
350  unsigned int count;
351  if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
352  return -1;
353  for (i = 0; i < count && total_count + i < ARRAY_LEN(bufs); i++) {
354  if ((stat1 = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0) {
355  return -1;
356  }
357  /* valid secondaries can contain zero-length packets that should be ignored */
358  if (!bufs[total_count + i] || !lengths[total_count + i]) {
359  /* drop the count of items to process and reuse the buffers that were just set */
360  i--;
361  count--;
362  }
363  }
364  total_count += i;
365  }
366  while (stat2 > 0 && total_count < ARRAY_LEN(bufs));
367  /* Step through in reverse order, so we go oldest to newest */
368  for (i = total_count; i > 0; i--) {
369  if (seq_no - i >= s->rx_seq_no) {
370  /* This one wasn't seen before */
371  /* Decode the secondary IFP packet */
372  ast_debug(3, "Recovering lost packet via secondary %d, len %u\n", seq_no - i, lengths[i - 1]);
373  s->f[ifp_no].frametype = AST_FRAME_MODEM;
374  s->f[ifp_no].subclass.codec = AST_MODEM_T38;
375 
376  s->f[ifp_no].mallocd = 0;
377  s->f[ifp_no].seqno = seq_no - i;
378  s->f[ifp_no].datalen = lengths[i - 1];
379  s->f[ifp_no].data.ptr = (uint8_t *) bufs[i - 1];
380  s->f[ifp_no].offset = 0;
381  s->f[ifp_no].src = "UDPTL";
382  if (ifp_no > 0)
383  AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
384  AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
385  ifp_no++;
386  }
387  }
388  }
389  }
390  else
391  {
392  int j;
393  int l;
394  int x;
395  /* FEC mode for error recovery */
396  /* Our buffers cannot tolerate overlength IFP packets in FEC mode */
397  if (ifp_len > LOCAL_FAX_MAX_DATAGRAM)
398  return -1;
399  /* Update any missed slots in the buffer */
400  for ( ; seq_no > s->rx_seq_no; s->rx_seq_no++) {
401  x = s->rx_seq_no & UDPTL_BUF_MASK;
402  s->rx[x].buf_len = -1;
403  s->rx[x].fec_len[0] = 0;
404  s->rx[x].fec_span = 0;
405  s->rx[x].fec_entries = 0;
406  }
407 
408  x = seq_no & UDPTL_BUF_MASK;
409 
410  memset(repaired, 0, sizeof(repaired));
411 
412  /* Save the new IFP packet */
413  memcpy(s->rx[x].buf, ifp, ifp_len);
414  s->rx[x].buf_len = ifp_len;
415  repaired[x] = TRUE;
416 
417  /* Decode the FEC packets */
418  /* The span is defined as an unconstrained integer, but will never be more
419  than a small value. */
420  if (ptr + 2 > len)
421  return -1;
422  if (buf[ptr++] != 1)
423  return -1;
424  span = buf[ptr++];
425  s->rx[x].fec_span = span;
426 
427  /* The number of entries is defined as a length, but will only ever be a small
428  value. Treat it as such. */
429  if (ptr + 1 > len)
430  return -1;
431  entries = buf[ptr++];
432  if (entries > MAX_FEC_ENTRIES) {
433  return -1;
434  }
435  s->rx[x].fec_entries = entries;
436 
437  /* Decode the elements */
438  for (i = 0; i < entries; i++) {
439  if ((stat1 = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
440  return -1;
441  if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
442  return -1;
443 
444  /* Save the new FEC data */
445  memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
446 #if 0
447  fprintf(stderr, "FEC: ");
448  for (j = 0; j < s->rx[x].fec_len[i]; j++)
449  fprintf(stderr, "%02X ", data[j]);
450  fprintf(stderr, "\n");
451 #endif
452  }
453 
454  /* See if we can reconstruct anything which is missing */
455  /* TODO: this does not comprehensively hunt back and repair everything that is possible */
456  for (l = x; l != ((x - (16 - span*entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
457  int m;
458  if (s->rx[l].fec_len[0] <= 0)
459  continue;
460  for (m = 0; m < s->rx[l].fec_entries; m++) {
461  int k;
462  int which;
463  int limit = (l + m) & UDPTL_BUF_MASK;
464 
465  /* only repair buffers that actually exist! */
466  if (seq_no <= (s->rx[l].fec_span * s->rx[l].fec_entries) - m) {
467  continue;
468  }
469 
470  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) {
471  if (s->rx[k].buf_len <= 0)
472  which = (which == -1) ? k : -2;
473  }
474  if (which >= 0) {
475  /* Repairable */
476  for (j = 0; j < s->rx[l].fec_len[m]; j++) {
477  s->rx[which].buf[j] = s->rx[l].fec[m][j];
478  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)
479  s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
480  }
481  s->rx[which].buf_len = s->rx[l].fec_len[m];
482  repaired[which] = TRUE;
483  }
484  }
485  }
486  /* Now play any new packets forwards in time */
487  for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
488  if (repaired[l]) {
489  //fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
490  s->f[ifp_no].frametype = AST_FRAME_MODEM;
491  s->f[ifp_no].subclass.codec = AST_MODEM_T38;
492 
493  s->f[ifp_no].mallocd = 0;
494  s->f[ifp_no].seqno = j;
495  s->f[ifp_no].datalen = s->rx[l].buf_len;
496  s->f[ifp_no].data.ptr = s->rx[l].buf;
497  s->f[ifp_no].offset = 0;
498  s->f[ifp_no].src = "UDPTL";
499  if (ifp_no > 0)
500  AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
501  AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
502  ifp_no++;
503  }
504  }
505  }
506 
507  /* If packets are received out of sequence, we may have already processed this packet from the error
508  recovery information in a packet already received. */
509  if (seq_no >= s->rx_seq_no) {
510  /* Decode the primary IFP packet */
511  s->f[ifp_no].frametype = AST_FRAME_MODEM;
512  s->f[ifp_no].subclass.codec = AST_MODEM_T38;
513 
514  s->f[ifp_no].mallocd = 0;
515  s->f[ifp_no].seqno = seq_no;
516  s->f[ifp_no].datalen = ifp_len;
517  s->f[ifp_no].data.ptr = (uint8_t *) ifp;
518  s->f[ifp_no].offset = 0;
519  s->f[ifp_no].src = "UDPTL";
520  if (ifp_no > 0)
521  AST_LIST_NEXT(&s->f[ifp_no - 1], frame_list) = &s->f[ifp_no];
522  AST_LIST_NEXT(&s->f[ifp_no], frame_list) = NULL;
523 
524  ifp_no++;
525  }
526 
527  s->rx_seq_no = seq_no + 1;
528  return ifp_no;
529 }
union ast_frame_subclass subclass
Definition: frame.h:146
unsigned int fec_entries
Definition: udptl.c:115
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int offset
Definition: frame.h:156
int seqno
Definition: frame.h:172
void * ptr
Definition: frame.h:160
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
#define AST_MODEM_T38
Definition: frame.h:216
format_t codec
Definition: frame.h:137
static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, unsigned int *pvalue)
Definition: udptl.c:201
unsigned int fec_len[MAX_FEC_ENTRIES]
Definition: udptl.c:112
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * src
Definition: frame.h:158
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK+1]
Definition: udptl.c:180
#define LOCAL_FAX_MAX_DATAGRAM
Definition: udptl.c:96
int datalen
Definition: frame.h:148
#define TRUE
Definition: udptl.c:80
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:227
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:111
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:177
uint8_t fec[MAX_FEC_ENTRIES][LOCAL_FAX_MAX_DATAGRAM]
Definition: udptl.c:113
struct ast_frame f[16]
Definition: udptl.c:122
int mallocd
Definition: frame.h:152
unsigned int fec_span
Definition: udptl.c:114
enum ast_frame_type frametype
Definition: frame.h:144
#define MAX_FEC_ENTRIES
Definition: udptl.c:99
union ast_frame::@172 data
#define UDPTL_BUF_MASK
Definition: udptl.c:102
static void udptl_shutdown ( void  )
static

Definition at line 1431 of file udptl.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_udptl_init().

1432 {
1434 }
#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: cli.c:2177
static struct ast_cli_entry cli_udptl[]
Definition: udptl.c:1317
static int udptlread ( int *  id,
int  fd,
short  events,
void *  cbdata 
)
static

Definition at line 663 of file udptl.c.

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

Referenced by ast_udptl_new_with_bindaddr().

664 {
665  struct ast_udptl *udptl = cbdata;
666  struct ast_frame *f;
667 
668  if ((f = ast_udptl_read(udptl))) {
669  if (udptl->callback)
670  udptl->callback(udptl, f, udptl->data);
671  }
672  return 1;
673 }
ast_udptl_callback callback
Definition: udptl.c:134
Structure for an UDPTL session.
Definition: udptl.c:119
static struct ast_format f[]
Definition: format_g726.c:181
struct ast_frame * ast_udptl_read(struct ast_udptl *udptl)
Definition: udptl.c:675
Data structure associated with a single frame of data.
Definition: frame.h:142
void * data
Definition: udptl.c:132

Variable Documentation

struct ast_cli_entry cli_udptl[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_cli_udptl_set_debug, "Enable/Disable UDPTL debugging")
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_cli_udptl_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: udptl.c:1271

Definition at line 1317 of file udptl.c.

struct protos protos = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, 1 } , }
static
int udptldebug
static

Are we debugging?

Definition at line 87 of file udptl.c.

struct ast_sockaddr udptldebugaddr
static

Debug packets to/from this host

Definition at line 88 of file udptl.c.

Referenced by handle_cli_udptl_set_debug(), and udptl_debug_test_addr().

int udptlend = 4599
static

Definition at line 86 of file udptl.c.

Referenced by __ast_udptl_reload(), and ast_udptl_new_with_bindaddr().

int udptlfecentries
static

Definition at line 92 of file udptl.c.

Referenced by ast_udptl_new_with_bindaddr().

int udptlfecspan
static

Definition at line 93 of file udptl.c.

Referenced by ast_udptl_new_with_bindaddr().

int udptlstart = 4500
static

Definition at line 85 of file udptl.c.

Referenced by __ast_udptl_reload(), and ast_udptl_new_with_bindaddr().

int use_even_ports
static

Definition at line 94 of file udptl.c.