Thu Apr 28 2011 17:14:03

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 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 sockaddr_in *them)
void ast_udptl_get_us (const struct ast_udptl *udptl, struct sockaddr_in *us)
void ast_udptl_init (void)
struct ast_udptlast_udptl_new (struct sched_context *sched, struct io_context *io, int callbackmode)
struct ast_udptlast_udptl_new_with_bindaddr (struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr 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 sockaddr_in *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 57 of file udptl.h.


Enumeration Type Documentation

Enumerator:
UDPTL_ERROR_CORRECTION_NONE 
UDPTL_ERROR_CORRECTION_FEC 
UDPTL_ERROR_CORRECTION_REDUNDANCY 

Definition at line 36 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 1139 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_inet_ntoa(), ast_log(), ast_read(), ast_udptl_get_peer(), ast_waitfor_n(), ast_write(), f, ast_frame::frametype, get_proto(), ast_udptl_protocol::get_udptl_info, inaddrcmp(), LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::name, ast_udptl_protocol::set_udptl_peer, and ast_channel::tech_pvt.

{
   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 sockaddr_in ac0;
   struct sockaddr_in ac1;
   struct sockaddr_in t0;
   struct sockaddr_in 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", c0->name);
      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", c1->name);
      ast_channel_unlock(c0);
      ast_channel_unlock(c1);
      return -1;
   }
   pvt0 = c0->tech_pvt;
   pvt1 = c1->tech_pvt;
   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", c0->name, c1->name);
      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", c1->name, c0->name);
      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 ((c0->tech_pvt != pvt0) ||
         (c1->tech_pvt != pvt1) ||
         (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
            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 (inaddrcmp(&t1, &ac1)) {
         ast_debug(1, "Oooh, '%s' changed end address to %s:%d\n", 
            c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port));
         ast_debug(1, "Oooh, '%s' was %s:%d\n", 
            c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port));
         memcpy(&ac1, &t1, sizeof(ac1));
      }
      if (inaddrcmp(&t0, &ac0)) {
         ast_debug(1, "Oooh, '%s' changed end address to %s:%d\n", 
            c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port));
         ast_debug(1, "Oooh, '%s' was %s:%d\n", 
            c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port));
         memcpy(&ac0, &t0, sizeof(ac0));
      }
      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 1038 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(), and create_addr_from_peer().

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

References ast_udptl::fd.

Referenced by __oh323_new(), and sip_new().

{
   return udptl->fd;
}
enum ast_t38_ec_modes ast_udptl_get_error_correction_scheme ( const struct ast_udptl udptl)

Definition at line 820 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 888 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 896 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 864 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 sockaddr_in *  them 
)

Definition at line 1019 of file udptl.c.

References ast_udptl::them.

Referenced by ast_udptl_bridge(), and sip_set_udptl_peer().

{
   memset(them, 0, sizeof(*them));
   them->sin_family = AF_INET;
   them->sin_port = udptl->them.sin_port;
   them->sin_addr = udptl->them.sin_addr;
}
void ast_udptl_get_us ( const struct ast_udptl udptl,
struct sockaddr_in *  us 
)

Definition at line 1027 of file udptl.c.

References ast_udptl::us.

Referenced by add_sdp().

{
   memcpy(us, &udptl->us, sizeof(udptl->us));
}
void ast_udptl_init ( void  )
struct ast_udptl* ast_udptl_new ( struct sched_context sched,
struct io_context io,
int  callbackmode 
) [read]

Definition at line 986 of file udptl.c.

References ast_udptl_new_with_bindaddr().

{
   struct in_addr ia;
   memset(&ia, 0, sizeof(ia));
   return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia);
}
struct ast_udptl* ast_udptl_new_with_bindaddr ( struct sched_context sched,
struct io_context io,
int  callbackmode,
struct in_addr  in 
) [read]

Definition at line 908 of file udptl.c.

References ast_calloc, ast_free, ast_io_add(), AST_IO_IN, ast_log(), ast_random(), 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, io, ast_udptl::io, ast_udptl::ioid, ast_udptl::local_max_datagram, ast_udptl::local_max_ifp, LOG_WARNING, ast_udptl::rx, sched, ast_udptl::sched, ast_udptl::them, ast_udptl::tx, UDPTL_BUF_MASK, udptlend, udptlfecentries, udptlfecspan, udptlread(), udptlstart, and ast_udptl::us.

Referenced by ast_udptl_new(), create_addr_from_peer(), handle_request_invite(), and sip_alloc().

{
   struct ast_udptl *udptl;
   int x;
   int startplace;
   int i;
   long int flags;

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

   udptl->error_correction_span = udptlfecspan;
   udptl->error_correction_entries = udptlfecentries;
   
   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;
   }

   udptl->them.sin_family = AF_INET;
   udptl->us.sin_family = AF_INET;

   if ((udptl->fd = socket(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 (nochecksums)
      setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
#endif
   /* Find us a place */
   x = (udptlstart == udptlend) ? udptlstart : (ast_random() % (udptlend - udptlstart)) + udptlstart;
   if (use_even_ports && (x & 1)) {
      ++x;
   }
   startplace = x;
   for (;;) {
      udptl->us.sin_port = htons(x);
      udptl->us.sin_addr = addr;
      if (bind(udptl->fd, (struct sockaddr *) &udptl->us, sizeof(udptl->us)) == 0)
         break;
      if (errno != EADDRINUSE) {
         ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
         close(udptl->fd);
         ast_free(udptl);
         return NULL;
      }
      if (use_even_ports) {
         x += 2;
      } else {
         ++x;
      }
      if (x > udptlend)
         x = udptlstart;
      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;
}
int ast_udptl_proto_register ( struct ast_udptl_protocol proto)

Definition at line 1108 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;
}
void ast_udptl_proto_unregister ( struct ast_udptl_protocol proto)

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

References ast_assert, ast_debug, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_verb, errno, ast_udptl::f, ast_udptl::fd, len(), 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 sockaddr_in sin;
   socklen_t len;
   uint16_t seqno = 0;
   uint16_t *udptlheader;

   len = sizeof(sin);
   
   /* Cache where the header will go */
   res = recvfrom(udptl->fd,
         udptl->rawdata + AST_FRIENDLY_OFFSET,
         sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET,
         0,
         (struct sockaddr *) &sin,
         &len);
   udptlheader = (uint16_t *)(udptl->rawdata + AST_FRIENDLY_OFFSET);
   if (res < 0) {
      if (errno != EAGAIN)
         ast_log(LOG_WARNING, "(%s): UDPTL 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 (!udptl->them.sin_addr.s_addr || !udptl->them.sin_port)
      return &ast_null_frame;

   if (udptl->nat) {
      /* Send to whoever sent to us */
      if ((udptl->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
         (udptl->them.sin_port != sin.sin_port)) {
         memcpy(&udptl->them, &sin, sizeof(udptl->them));
         ast_debug(1, "UDPTL NAT (%s): Using address %s:%d\n",
              LOG_TAG(udptl), ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port));
      }
   }

   if (udptl_debug_test_addr(&sin)) {
      ast_verb(1, "UDPTL (%s): packet from %s:%d (type %d, seq %d, len %d)\n",
          LOG_TAG(udptl), ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 0, seqno, res);
   }
   if (udptl_rx_packet(udptl, udptl->rawdata + AST_FRIENDLY_OFFSET, 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 1431 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 639 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 634 of file udptl.c.

References ast_udptl::data.

{
   udptl->data = 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.

Definition at line 877 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 853 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 sockaddr_in *  them 
)

Definition at line 1013 of file udptl.c.

References ast_udptl::them.

Referenced by process_sdp().

{
   udptl->them.sin_port = them->sin_port;
   udptl->them.sin_addr = them->sin_addr;
}
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 993 of file udptl.c.

References ast_free, ast_vasprintf, and ast_udptl::tag.

Referenced by change_t38_state().

{
   va_list ap;

   if (udptl->tag) {
      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 644 of file udptl.c.

References nat, and ast_udptl::nat.

Referenced by do_setnat().

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

Definition at line 1008 of file udptl.c.

References ast_netsock_set_qos(), and ast_udptl::fd.

Referenced by sip_alloc().

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

Definition at line 1032 of file udptl.c.

References ast_udptl::them.

Referenced by process_sdp(), and stop_media_flows().

{
   memset(&udptl->them.sin_addr, 0, sizeof(udptl->them.sin_addr));
   memset(&udptl->them.sin_port, 0, sizeof(udptl->them.sin_port));
}
int ast_udptl_write ( struct ast_udptl udptl,
struct ast_frame f 
)

Definition at line 1049 of file udptl.c.

References AST_FRAME_MODEM, ast_inet_ntoa(), ast_log(), AST_MODEM_T38, ast_verb, buf, ast_frame::data, ast_frame::datalen, DEFAULT_FAX_MAX_DATAGRAM, errno, ast_udptl::far_max_datagram, ast_udptl::far_max_ifp, ast_udptl::fd, ast_frame::frametype, 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;
   int res;
   /* 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 (s->them.sin_addr.s_addr == INADDR_ANY)
      return 0;

   /* If there is no data length, return immediately */
   if (f->datalen == 0)
      return 0;
   
   if ((f->frametype != AST_FRAME_MODEM) ||
       (f->subclass != AST_MODEM_T38)) {
      ast_log(LOG_WARNING, "(%s): UDPTL can only send T.38 data.\n",
         LOG_TAG(s));
      return -1;
   }

   if (len > s->far_max_ifp) {
      ast_log(LOG_WARNING,
         "(%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 && s->them.sin_port && s->them.sin_addr.s_addr) {
      if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)
         ast_log(LOG_NOTICE, "(%s): UDPTL Transmission error to %s:%d: %s\n",
            LOG_TAG(s), ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), strerror(errno));
      if (udptl_debug_test_addr(&s->them))
         ast_verb(1, "UDPTL (%s): packet to %s:%d (type %d, seq %d, len %d)\n",
             LOG_TAG(s), ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), 0, seq, len);
   }
      
   return 0;
}