Sat Apr 26 2014 22:03:20

Asterisk developer's documentation


udptl.h File Reference

UDPTL support for T.38. More...

#include "asterisk/network.h"
#include "asterisk/frame.h"
#include "asterisk/io.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/netsock2.h"
Include dependency graph for udptl.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_udptl_protocol

Typedefs

typedef int(* ast_udptl_callback )(struct ast_udptl *udptl, struct ast_frame *f, void *data)

Enumerations

enum  ast_t38_ec_modes { UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_REDUNDANCY }

Functions

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
unsigned int ast_udptl_get_local_max_datagram (struct ast_udptl *udptl)
 retrieves local_max_datagram.
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 ast_sched_context *sched, struct io_context *io, int callbackmode, struct ast_sockaddr *in)
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_reset (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.
void ast_udptl_set_local_max_ifp (struct ast_udptl *udptl, unsigned int max_ifp)
void ast_udptl_set_m_type (struct ast_udptl *udptl, unsigned int pt)
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.
void ast_udptl_set_udptlmap_type (struct ast_udptl *udptl, unsigned int pt, char *mimeType, char *mimeSubtype)
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 *udptl, struct ast_frame *f)

Detailed Description

UDPTL support for T.38.

Author:
Steve Underwood <steveu@coppice.org> udptl.c
Todo:
add doxygen documentation to this file!

Definition in file udptl.h.


Typedef Documentation

typedef int(* ast_udptl_callback)(struct ast_udptl *udptl, struct ast_frame *f, void *data)

Definition at line 58 of file udptl.h.


Enumeration Type Documentation

Enumerator:
UDPTL_ERROR_CORRECTION_NONE 
UDPTL_ERROR_CORRECTION_FEC 
UDPTL_ERROR_CORRECTION_REDUNDANCY 

Definition at line 37 of file udptl.h.


Function Documentation

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

References ast_channel_lock, ast_channel_masq(), ast_channel_masqr(), ast_channel_name(), ast_channel_tech_pvt(), 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, and ast_udptl_protocol::set_udptl_peer.

{
   struct ast_frame *f;
   struct ast_channel *who;
   struct ast_channel *cs[3];
   struct ast_udptl *p0;
   struct ast_udptl *p1;
   struct ast_udptl_protocol *pr0;
   struct ast_udptl_protocol *pr1;
   struct ast_sockaddr ac0;
   struct ast_sockaddr ac1;
   struct ast_sockaddr t0;
   struct ast_sockaddr t1;
   void *pvt0;
   void *pvt1;
   int to;

   ast_channel_lock(c0);
   while (ast_channel_trylock(c1)) {
      ast_channel_unlock(c0);
      usleep(1);
      ast_channel_lock(c0);
   }
   pr0 = get_proto(c0);
   pr1 = get_proto(c1);
   if (!pr0) {
      ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", ast_channel_name(c0));
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      return -1;
   }
   if (!pr1) {
      ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", ast_channel_name(c1));
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      return -1;
   }
   pvt0 = ast_channel_tech_pvt(c0);
   pvt1 = ast_channel_tech_pvt(c1);
   p0 = pr0->get_udptl_info(c0);
   p1 = pr1->get_udptl_info(c1);
   if (!p0 || !p1) {
      /* Somebody doesn't want to play... */
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      return -2;
   }
   if (pr0->set_udptl_peer(c0, p1)) {
      ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", ast_channel_name(c0), ast_channel_name(c1));
      memset(&ac1, 0, sizeof(ac1));
   } else {
      /* Store UDPTL peer */
      ast_udptl_get_peer(p1, &ac1);
   }
   if (pr1->set_udptl_peer(c1, p0)) {
      ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", ast_channel_name(c1), ast_channel_name(c0));
      memset(&ac0, 0, sizeof(ac0));
   } else {
      /* Store UDPTL peer */
      ast_udptl_get_peer(p0, &ac0);
   }
   ast_channel_unlock(c0);
   ast_channel_unlock(c1);
   cs[0] = c0;
   cs[1] = c1;
   cs[2] = NULL;
   for (;;) {
      if ((ast_channel_tech_pvt(c0) != pvt0) ||
         (ast_channel_tech_pvt(c1) != pvt1) ||
         (ast_channel_masq(c0) || ast_channel_masqr(c0) || ast_channel_masq(c1) || ast_channel_masqr(c1))) {
            ast_debug(1, "Oooh, something is weird, backing out\n");
            /* Tell it to try again later */
            return -3;
      }
      to = -1;
      ast_udptl_get_peer(p1, &t1);
      ast_udptl_get_peer(p0, &t0);
      if (ast_sockaddr_cmp(&t1, &ac1)) {
         ast_debug(1, "Oooh, '%s' changed end address to %s\n",
            ast_channel_name(c1), ast_sockaddr_stringify(&t1));
         ast_debug(1, "Oooh, '%s' was %s\n",
            ast_channel_name(c1), ast_sockaddr_stringify(&ac1));
         ast_sockaddr_copy(&ac1, &t1);
      }
      if (ast_sockaddr_cmp(&t0, &ac0)) {
         ast_debug(1, "Oooh, '%s' changed end address to %s\n",
            ast_channel_name(c0), ast_sockaddr_stringify(&t0));
         ast_debug(1, "Oooh, '%s' was %s\n",
            ast_channel_name(c0), ast_sockaddr_stringify(&ac0));
         ast_sockaddr_copy(&ac0, &t0);
      }
      who = ast_waitfor_n(cs, 2, &to);
      if (!who) {
         ast_debug(1, "Ooh, empty read...\n");
         /* check for hangup / whentohangup */
         if (ast_check_hangup(c0) || ast_check_hangup(c1))
            break;
         continue;
      }
      f = ast_read(who);
      if (!f) {
         *fo = f;
         *rc = who;
         ast_debug(1, "Oooh, got a %s\n", f ? "digit" : "hangup");
         /* That's all we needed */
         return 0;
      } else {
         if (f->frametype == AST_FRAME_MODEM) {
            /* Forward T.38 frames if they happen upon us */
            if (who == c0) {
               ast_write(c1, f);
            } else if (who == c1) {
               ast_write(c0, f);
            }
         }
         ast_frfree(f);
      }
      /* Swap priority. Not that it's a big deal at this point */
      cs[2] = cs[0];
      cs[0] = cs[1];
      cs[1] = cs[2];
   }
   return -1;
}
void ast_udptl_destroy ( struct ast_udptl udptl)

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

{
   if (udptl->ioid)
      ast_io_remove(udptl->io, udptl->ioid);
   if (udptl->fd > -1)
      close(udptl->fd);
   if (udptl->tag)
      ast_free(udptl->tag);
   ast_free(udptl);
}
int ast_udptl_fd ( const struct ast_udptl udptl)

Definition at line 669 of file udptl.c.

References ast_udptl::fd.

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

{
   return udptl->fd;
}

Definition at line 867 of file udptl.c.

References ast_udptl::error_correction_scheme.

Referenced by add_sdp().

{
   return udptl->error_correction_scheme;
}
unsigned int ast_udptl_get_far_max_datagram ( const struct ast_udptl udptl)

Definition at line 935 of file udptl.c.

References ast_udptl::far_max_datagram.

Referenced by process_sdp().

{
   if (udptl->far_max_datagram < 0) {
      return 0;
   }
   return udptl->far_max_datagram;
}
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 943 of file udptl.c.

References calculate_far_max_ifp(), and ast_udptl::far_max_ifp.

Referenced by change_t38_state(), and interpret_t38_parameters().

{
   if (udptl->far_max_ifp == -1) {
      calculate_far_max_ifp(udptl);
   }

   if (udptl->far_max_ifp < 0) {
      return 0;
   }
   return udptl->far_max_ifp;
}
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 911 of file udptl.c.

References calculate_local_max_datagram(), and ast_udptl::local_max_datagram.

Referenced by add_sdp().

{
   if (udptl->local_max_datagram == -1) {
      calculate_local_max_datagram(udptl);
   }

   /* this function expects a unsigned value in return. */
   if (udptl->local_max_datagram < 0) {
      return 0;
   }
   return udptl->local_max_datagram;
}
void ast_udptl_get_peer ( const struct ast_udptl udptl,
struct ast_sockaddr them 
)

Definition at line 1065 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::them.

Referenced by ast_udptl_bridge(), and sip_set_udptl_peer().

{
   ast_sockaddr_copy(them, &udptl->them);
}
void ast_udptl_get_us ( const struct ast_udptl udptl,
struct ast_sockaddr us 
)

Definition at line 1070 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::us.

Referenced by add_sdp().

{
   ast_sockaddr_copy(us, &udptl->us);
}
void ast_udptl_init ( void  )

Definition at line 1486 of file udptl.c.

References __ast_udptl_reload(), __stringify, ACO_EXACT, aco_info_init(), aco_option_register, aco_option_register_custom, ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), DEFAULT_UDPTLEND, DEFAULT_UDPTLSTART, FLDSET, MAX_FEC_ENTRIES, MAX_FEC_SPAN, OPT_BOOL_T, OPT_UINT_T, PARSE_DEFAULT, PARSE_IN_RANGE, PARSE_RANGE_DEFAULTS, removed_options_handler(), and udptl_shutdown().

Referenced by main().

{
   if (aco_info_init(&cfg_info)) {
      return;
   }

   aco_option_register(&cfg_info, "udptlstart", ACO_EXACT, general_options, __stringify(DEFAULT_UDPTLSTART),
      OPT_UINT_T, PARSE_IN_RANGE | PARSE_DEFAULT,
      FLDSET(struct udptl_global_options, start), DEFAULT_UDPTLSTART, 1024, 65535);

   aco_option_register(&cfg_info, "udptlend", ACO_EXACT, general_options, __stringify(DEFAULT_UDPTLEND),
      OPT_UINT_T, PARSE_IN_RANGE | PARSE_DEFAULT,
      FLDSET(struct udptl_global_options, end), DEFAULT_UDPTLEND, 1024, 65535);

   aco_option_register(&cfg_info, "udptlfecentries", ACO_EXACT, general_options, NULL,
      OPT_UINT_T, PARSE_IN_RANGE | PARSE_RANGE_DEFAULTS,
      FLDSET(struct udptl_global_options, fecentries), 1, MAX_FEC_ENTRIES);

   aco_option_register(&cfg_info, "udptlfecspan", ACO_EXACT, general_options, NULL,
      OPT_UINT_T, PARSE_IN_RANGE | PARSE_RANGE_DEFAULTS,
      FLDSET(struct udptl_global_options, fecspan), 1, MAX_FEC_SPAN);

   aco_option_register(&cfg_info, "udptlchecksums", ACO_EXACT, general_options, "yes",
      OPT_BOOL_T, 0, FLDSET(struct udptl_global_options, nochecksums));

   aco_option_register(&cfg_info, "use_even_ports", ACO_EXACT, general_options, "no",
      OPT_BOOL_T, 1, FLDSET(struct udptl_global_options, use_even_ports));

   aco_option_register_custom(&cfg_info, "t38faxudpec", ACO_EXACT, general_options, NULL, removed_options_handler, 0);
   aco_option_register_custom(&cfg_info, "t38faxmaxdatagram", ACO_EXACT, general_options, NULL, removed_options_handler, 0);

   __ast_udptl_reload(0);

   ast_cli_register_multiple(cli_udptl, ARRAY_LEN(cli_udptl));

   ast_register_atexit(udptl_shutdown);
}
struct ast_udptl* ast_udptl_new_with_bindaddr ( struct ast_sched_context sched,
struct io_context io,
int  callbackmode,
struct ast_sockaddr in 
) [read]

Definition at line 955 of file udptl.c.

References ao2_cleanup, ao2_global_obj_ref, ast_bind(), ast_calloc, ast_free, ast_io_add(), AST_IO_IN, ast_log(), ast_random(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_set_port, 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, globals, ast_udptl::io, io, ast_udptl::ioid, ast_udptl::local_max_datagram, ast_udptl::local_max_ifp, LOG_ERROR, LOG_WARNING, ast_udptl::rx, ast_udptl::sched, sched, ast_udptl::tx, UDPTL_BUF_MASK, udptlread(), and ast_udptl::us.

Referenced by initialize_udptl().

{
   struct ast_udptl *udptl;
   int x;
   int startplace;
   int i;
   long int flags;
   RAII_VAR(struct udptl_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);

   if (!cfg || !cfg->general) {
      ast_log(LOG_ERROR, "Could not access global udptl options!\n");
      return NULL;
   }

   if (!(udptl = ast_calloc(1, sizeof(*udptl)))) {
      return NULL;
   }

   udptl->error_correction_span = cfg->general->fecspan;
   udptl->error_correction_entries = cfg->general->fecentries;

   udptl->far_max_datagram = -1;
   udptl->far_max_ifp = -1;
   udptl->local_max_ifp = -1;
   udptl->local_max_datagram = -1;

   for (i = 0; i <= UDPTL_BUF_MASK; i++) {
      udptl->rx[i].buf_len = -1;
      udptl->tx[i].buf_len = -1;
   }

   if ((udptl->fd = socket(ast_sockaddr_is_ipv6(addr) ?
               AF_INET6 : AF_INET, SOCK_DGRAM, 0)) < 0) {
      ast_free(udptl);
      ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
      return NULL;
   }
   flags = fcntl(udptl->fd, F_GETFL);
   fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);

#ifdef SO_NO_CHECK
   if (cfg->general->nochecksums)
      setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &cfg->general->nochecksums, sizeof(cfg->general->nochecksums));
#endif

   /* Find us a place */
   x = (cfg->general->start == cfg->general->end) ? cfg->general->start : (ast_random() % (cfg->general->end - cfg->general->start)) + cfg->general->start;
   if (cfg->general->use_even_ports && (x & 1)) {
      ++x;
   }
   startplace = x;
   for (;;) {
      ast_sockaddr_copy(&udptl->us, addr);
      ast_sockaddr_set_port(&udptl->us, x);
      if (ast_bind(udptl->fd, &udptl->us) == 0) {
         break;
      }
      if (errno != EADDRINUSE && errno != EACCES) {
         ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
         close(udptl->fd);
         ast_free(udptl);
         return NULL;
      }
      if (cfg->general->use_even_ports) {
         x += 2;
      } else {
         ++x;
      }
      if (x > cfg->general->end)
         x = cfg->general->start;
      if (x == startplace) {
         ast_log(LOG_WARNING, "No UDPTL ports remaining\n");
         close(udptl->fd);
         ast_free(udptl);
         return NULL;
      }
   }
   if (io && sched && callbackmode) {
      /* Operate this one in a callback mode */
      udptl->sched = sched;
      udptl->io = io;
      udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl);
   }

   return udptl;
}

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

{
   struct ast_udptl_protocol *cur;

   AST_RWLIST_WRLOCK(&protos);
   AST_RWLIST_TRAVERSE(&protos, cur, list) {
      if (cur->type == proto->type) {
         ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
         AST_RWLIST_UNLOCK(&protos);
         return -1;
      }
   }
   AST_RWLIST_INSERT_TAIL(&protos, proto, list);
   AST_RWLIST_UNLOCK(&protos);
   return 0;
}

Definition at line 1145 of file udptl.c.

References AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, and AST_RWLIST_WRLOCK.

Referenced by unload_module().

struct ast_frame* ast_udptl_read ( struct ast_udptl udptl) [read]

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

{
   int res;
   struct ast_sockaddr addr;
   uint8_t *buf;

   buf = udptl->rawdata + AST_FRIENDLY_OFFSET;

   /* Cache where the header will go */
   res = ast_recvfrom(udptl->fd,
         buf,
         sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
         0,
         &addr);
   if (res < 0) {
      if (errno != EAGAIN)
         ast_log(LOG_WARNING, "UDPTL (%s): read error: %s\n",
            LOG_TAG(udptl), strerror(errno));
      ast_assert(errno != EBADF);
      return &ast_null_frame;
   }

   /* Ignore if the other side hasn't been given an address yet. */
   if (ast_sockaddr_isnull(&udptl->them)) {
      return &ast_null_frame;
   }

   if (udptl->nat) {
      /* Send to whoever sent to us */
      if (ast_sockaddr_cmp(&udptl->them, &addr)) {
         ast_sockaddr_copy(&udptl->them, &addr);
         ast_debug(1, "UDPTL (%s): NAT, Using address %s\n",
              LOG_TAG(udptl), ast_sockaddr_stringify(&udptl->them));
      }
   }

   if (udptl_debug_test_addr(&addr)) {
      int seq_no;

      /* Decode sequence number just for verbose message. */
      if (res < 2) {
         /* Short packet. */
         seq_no = -1;
      } else {
         seq_no = (buf[0] << 8) | buf[1];
      }

      ast_verb(1, "UDPTL (%s): packet from %s (seq %d, len %d)\n",
         LOG_TAG(udptl), ast_sockaddr_stringify(&addr), seq_no, res);
   }
   if (udptl_rx_packet(udptl, buf, res) < 1) {
      return &ast_null_frame;
   }

   return &udptl->f[0];
}
int ast_udptl_reload ( void  )
Version:
1.6.1 return changed to int

Definition at line 1469 of file udptl.c.

References __ast_udptl_reload().

{
   __ast_udptl_reload(1);
   return 0;
}
void ast_udptl_reset ( struct ast_udptl udptl)
void ast_udptl_set_callback ( struct ast_udptl udptl,
ast_udptl_callback  callback 
)

Definition at line 679 of file udptl.c.

References ast_udptl::callback.

{
   udptl->callback = callback;
}
void ast_udptl_set_data ( struct ast_udptl udptl,
void *  data 
)

Definition at line 674 of file udptl.c.

References ast_udptl::data.

{
   udptl->data = data;
}
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 924 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().

{
   if (!max_datagram || (max_datagram > FAX_MAX_DATAGRAM_LIMIT)) {
      udptl->far_max_datagram = DEFAULT_FAX_MAX_DATAGRAM;
   } else {
      udptl->far_max_datagram = max_datagram;
   }
   /* reset calculated values so they'll be computed again */
   udptl->far_max_ifp = -1;
}
void ast_udptl_set_local_max_ifp ( struct ast_udptl udptl,
unsigned int  max_ifp 
)

Definition at line 900 of file udptl.c.

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

Referenced by interpret_t38_parameters().

{
   /* make sure max_ifp is a positive value since a cast will take place when
    * when setting local_max_ifp */
   if ((signed int) max_ifp > 0) {
      udptl->local_max_ifp = max_ifp;
      /* reset calculated values so they'll be computed again */
      udptl->local_max_datagram = -1;
   }
}
void ast_udptl_set_m_type ( struct ast_udptl udptl,
unsigned int  pt 
)
void ast_udptl_set_peer ( struct ast_udptl udptl,
const struct ast_sockaddr them 
)

Definition at line 1060 of file udptl.c.

References ast_sockaddr_copy(), and ast_udptl::them.

Referenced by process_sdp().

{
   ast_sockaddr_copy(&udptl->them, them);
}
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 1042 of file udptl.c.

References ast_free, ast_vasprintf, and ast_udptl::tag.

Referenced by change_t38_state().

{
   va_list ap;

   ast_free(udptl->tag);
   udptl->tag = NULL;
   va_start(ap, format);
   if (ast_vasprintf(&udptl->tag, format, ap) == -1) {
      udptl->tag = NULL;
   }
   va_end(ap);
}
void ast_udptl_set_udptlmap_type ( struct ast_udptl udptl,
unsigned int  pt,
char *  mimeType,
char *  mimeSubtype 
)
void ast_udptl_setnat ( struct ast_udptl udptl,
int  nat 
)

Definition at line 684 of file udptl.c.

References ast_udptl::nat, and nat.

Referenced by do_setnat(), and initialize_udptl().

{
   udptl->nat = nat;
}
int ast_udptl_setqos ( struct ast_udptl udptl,
unsigned int  tos,
unsigned int  cos 
)

Definition at line 1055 of file udptl.c.

References ast_set_qos(), and ast_udptl::fd.

Referenced by initialize_udptl().

{
   return ast_set_qos(udptl->fd, tos, cos, "UDPTL");
}
void ast_udptl_stop ( struct ast_udptl udptl)

Definition at line 1075 of file udptl.c.

References ast_sockaddr_setnull(), and ast_udptl::them.

Referenced by process_sdp(), and stop_media_flows().

{
   ast_sockaddr_setnull(&udptl->them);
}
int ast_udptl_write ( struct ast_udptl udptl,
struct ast_frame f 
)

Definition at line 1091 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::data, ast_frame::datalen, DEFAULT_FAX_MAX_DATAGRAM, errno, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, ast_udptl::fd, ast_frame::frametype, ast_frame_subclass::integer, 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().

{
   unsigned int seq;
   unsigned int len = f->datalen;
   /* if no max datagram size is provided, use default value */
   const int bufsize = (s->far_max_datagram > 0) ? s->far_max_datagram : DEFAULT_FAX_MAX_DATAGRAM;
   uint8_t buf[bufsize];

   memset(buf, 0, sizeof(buf));

   /* If we have no peer, return immediately */
   if (ast_sockaddr_isnull(&s->them)) {
      return 0;
   }

   /* If there is no data length, return immediately */
   if (f->datalen == 0)
      return 0;

   if ((f->frametype != AST_FRAME_MODEM) ||
       (f->subclass.integer != AST_MODEM_T38)) {
      ast_log(LOG_WARNING, "UDPTL (%s): UDPTL can only send T.38 data.\n",
         LOG_TAG(s));
      return -1;
   }

   if (len > s->far_max_ifp) {
      ast_log(LOG_WARNING,
         "UDPTL (%s): UDPTL asked to send %d bytes of IFP when far end only prepared to accept %d bytes; data loss will occur."
         "You may need to override the T38FaxMaxDatagram value for this endpoint in the channel driver configuration.\n",
         LOG_TAG(s), len, s->far_max_ifp);
      len = s->far_max_ifp;
   }

   /* Save seq_no for debug output because udptl_build_packet increments it */
   seq = s->tx_seq_no & 0xFFFF;

   /* Cook up the UDPTL packet, with the relevant EC info. */
   len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, len);

   if ((signed int) len > 0 && !ast_sockaddr_isnull(&s->them)) {
      if (ast_sendto(s->fd, buf, len, 0, &s->them) < 0) {
         ast_log(LOG_NOTICE, "UDPTL (%s): Transmission error to %s: %s\n",
            LOG_TAG(s), ast_sockaddr_stringify(&s->them), strerror(errno));
      }
      if (udptl_debug_test_addr(&s->them)) {
         ast_verb(1, "UDPTL (%s): packet to %s (seq %d, len %d)\n",
            LOG_TAG(s), ast_sockaddr_stringify(&s->them), seq, len);
      }
   }

   return 0;
}