#include "asterisk/frame.h"
#include "asterisk/io.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include <netinet/in.h>
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 | { 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 (struct ast_udptl *udptl) |
void | ast_udptl_get_current_formats (struct ast_udptl *udptl, int *astFormats, int *nonAstFormats) |
int | ast_udptl_get_error_correction_scheme (struct ast_udptl *udptl) |
int | ast_udptl_get_far_max_datagram (struct ast_udptl *udptl) |
int | ast_udptl_get_local_max_datagram (struct ast_udptl *udptl) |
void | ast_udptl_get_peer (struct ast_udptl *udptl, struct sockaddr_in *them) |
void | ast_udptl_get_us (struct ast_udptl *udptl, struct sockaddr_in *us) |
void | ast_udptl_init (void) |
int | ast_udptl_lookup_code (struct ast_udptl *udptl, int isAstFormat, int code) |
struct ast_udptl * | ast_udptl_new (struct sched_context *sched, struct io_context *io, int callbackmode) |
struct ast_udptl * | ast_udptl_new_with_bindaddr (struct sched_context *sched, struct io_context *io, int callbackmode, struct in_addr in) |
void | ast_udptl_offered_from_local (struct ast_udptl *udptl, int local) |
int | ast_udptl_proto_register (struct ast_udptl_protocol *proto) |
void | ast_udptl_proto_unregister (struct ast_udptl_protocol *proto) |
struct ast_frame * | ast_udptl_read (struct ast_udptl *udptl) |
void | 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, int ec) |
void | ast_udptl_set_far_max_datagram (struct ast_udptl *udptl, int max_datagram) |
void | ast_udptl_set_local_max_datagram (struct ast_udptl *udptl, int max_datagram) |
void | ast_udptl_set_m_type (struct ast_udptl *udptl, int pt) |
void | ast_udptl_set_peer (struct ast_udptl *udptl, struct sockaddr_in *them) |
void | ast_udptl_set_udptlmap_type (struct ast_udptl *udptl, int pt, char *mimeType, char *mimeSubtype) |
void | ast_udptl_setnat (struct ast_udptl *udptl, int nat) |
int | ast_udptl_settos (struct ast_udptl *udptl, int tos) |
void | ast_udptl_stop (struct ast_udptl *udptl) |
int | ast_udptl_write (struct ast_udptl *udptl, struct ast_frame *f) |
typedef int(* ast_udptl_callback)(struct ast_udptl *udptl, struct ast_frame *f, void *data) |
anonymous enum |
UDPTL_ERROR_CORRECTION_NONE | |
UDPTL_ERROR_CORRECTION_FEC | |
UDPTL_ERROR_CORRECTION_REDUNDANCY |
Definition at line 28 of file udptl.h.
00029 { 00030 UDPTL_ERROR_CORRECTION_NONE, 00031 UDPTL_ERROR_CORRECTION_FEC, 00032 UDPTL_ERROR_CORRECTION_REDUNDANCY 00033 };
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 963 of file udptl.c.
References ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), 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_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_udptl_protocol::set_udptl_peer, and ast_channel::tech_pvt.
00964 { 00965 struct ast_frame *f; 00966 struct ast_channel *who; 00967 struct ast_channel *cs[3]; 00968 struct ast_udptl *p0; 00969 struct ast_udptl *p1; 00970 struct ast_udptl_protocol *pr0; 00971 struct ast_udptl_protocol *pr1; 00972 struct sockaddr_in ac0; 00973 struct sockaddr_in ac1; 00974 struct sockaddr_in t0; 00975 struct sockaddr_in t1; 00976 void *pvt0; 00977 void *pvt1; 00978 int to; 00979 00980 ast_channel_lock(c0); 00981 while (ast_channel_trylock(c1)) { 00982 ast_channel_unlock(c0); 00983 usleep(1); 00984 ast_channel_lock(c0); 00985 } 00986 pr0 = get_proto(c0); 00987 pr1 = get_proto(c1); 00988 if (!pr0) { 00989 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name); 00990 ast_channel_unlock(c0); 00991 ast_channel_unlock(c1); 00992 return -1; 00993 } 00994 if (!pr1) { 00995 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name); 00996 ast_channel_unlock(c0); 00997 ast_channel_unlock(c1); 00998 return -1; 00999 } 01000 pvt0 = c0->tech_pvt; 01001 pvt1 = c1->tech_pvt; 01002 p0 = pr0->get_udptl_info(c0); 01003 p1 = pr1->get_udptl_info(c1); 01004 if (!p0 || !p1) { 01005 /* Somebody doesn't want to play... */ 01006 ast_channel_unlock(c0); 01007 ast_channel_unlock(c1); 01008 return -2; 01009 } 01010 if (pr0->set_udptl_peer(c0, p1)) { 01011 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name); 01012 } else { 01013 /* Store UDPTL peer */ 01014 ast_udptl_get_peer(p1, &ac1); 01015 } 01016 if (pr1->set_udptl_peer(c1, p0)) 01017 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name); 01018 else { 01019 /* Store UDPTL peer */ 01020 ast_udptl_get_peer(p0, &ac0); 01021 } 01022 ast_channel_unlock(c0); 01023 ast_channel_unlock(c1); 01024 cs[0] = c0; 01025 cs[1] = c1; 01026 cs[2] = NULL; 01027 for (;;) { 01028 if ((c0->tech_pvt != pvt0) || 01029 (c1->tech_pvt != pvt1) || 01030 (c0->masq || c0->masqr || c1->masq || c1->masqr)) { 01031 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n"); 01032 /* Tell it to try again later */ 01033 return -3; 01034 } 01035 to = -1; 01036 ast_udptl_get_peer(p1, &t1); 01037 ast_udptl_get_peer(p0, &t0); 01038 if (inaddrcmp(&t1, &ac1)) { 01039 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n", 01040 c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port)); 01041 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n", 01042 c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port)); 01043 memcpy(&ac1, &t1, sizeof(ac1)); 01044 } 01045 if (inaddrcmp(&t0, &ac0)) { 01046 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n", 01047 c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port)); 01048 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n", 01049 c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port)); 01050 memcpy(&ac0, &t0, sizeof(ac0)); 01051 } 01052 who = ast_waitfor_n(cs, 2, &to); 01053 if (!who) { 01054 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 01055 /* check for hangup / whentohangup */ 01056 if (ast_check_hangup(c0) || ast_check_hangup(c1)) 01057 break; 01058 continue; 01059 } 01060 f = ast_read(who); 01061 if (!f) { 01062 *fo = f; 01063 *rc = who; 01064 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup"); 01065 /* That's all we needed */ 01066 return 0; 01067 } else { 01068 if (f->frametype == AST_FRAME_MODEM) { 01069 /* Forward T.38 frames if they happen upon us */ 01070 if (who == c0) { 01071 ast_write(c1, f); 01072 } else if (who == c1) { 01073 ast_write(c0, f); 01074 } 01075 } 01076 ast_frfree(f); 01077 } 01078 /* Swap priority. Not that it's a big deal at this point */ 01079 cs[2] = cs[0]; 01080 cs[0] = cs[1]; 01081 cs[1] = cs[2]; 01082 } 01083 return -1; 01084 }
void ast_udptl_destroy | ( | struct ast_udptl * | udptl | ) |
Definition at line 863 of file udptl.c.
References ast_io_remove(), ast_udptl::fd, free, ast_udptl::io, and ast_udptl::ioid.
Referenced by __sip_destroy(), and create_addr_from_peer().
00864 { 00865 if (udptl->ioid) 00866 ast_io_remove(udptl->io, udptl->ioid); 00867 if (udptl->fd > -1) 00868 close(udptl->fd); 00869 free(udptl); 00870 }
int ast_udptl_fd | ( | struct ast_udptl * | udptl | ) |
Definition at line 589 of file udptl.c.
References ast_udptl::fd.
Referenced by __oh323_new(), and sip_new().
00590 { 00591 return udptl->fd; 00592 }
void ast_udptl_get_current_formats | ( | struct ast_udptl * | udptl, | |
int * | astFormats, | |||
int * | nonAstFormats | |||
) |
int ast_udptl_get_error_correction_scheme | ( | struct ast_udptl * | udptl | ) |
Definition at line 681 of file udptl.c.
References ast_log(), ast_udptl::error_correction_scheme, and LOG_WARNING.
Referenced by create_addr_from_peer(), sip_alloc(), and sip_handle_t38_reinvite().
00682 { 00683 if (udptl) 00684 return udptl->error_correction_scheme; 00685 else { 00686 ast_log(LOG_WARNING, "udptl structure is null\n"); 00687 return -1; 00688 } 00689 }
int ast_udptl_get_far_max_datagram | ( | struct ast_udptl * | udptl | ) |
Definition at line 721 of file udptl.c.
References ast_log(), ast_udptl::far_max_datagram_size, and LOG_WARNING.
00722 { 00723 if (udptl) 00724 return udptl->far_max_datagram_size; 00725 else { 00726 ast_log(LOG_WARNING, "udptl structure is null\n"); 00727 return -1; 00728 } 00729 }
int ast_udptl_get_local_max_datagram | ( | struct ast_udptl * | udptl | ) |
Definition at line 711 of file udptl.c.
References ast_log(), ast_udptl::local_max_datagram_size, and LOG_WARNING.
Referenced by add_t38_sdp(), and sip_handle_t38_reinvite().
00712 { 00713 if (udptl) 00714 return udptl->local_max_datagram_size; 00715 else { 00716 ast_log(LOG_WARNING, "udptl structure is null\n"); 00717 return -1; 00718 } 00719 }
void ast_udptl_get_peer | ( | struct ast_udptl * | udptl, | |
struct sockaddr_in * | them | |||
) |
Definition at line 845 of file udptl.c.
References ast_udptl::them.
Referenced by ast_udptl_bridge(), sip_handle_t38_reinvite(), and sip_set_udptl_peer().
00846 { 00847 them->sin_family = AF_INET; 00848 them->sin_port = udptl->them.sin_port; 00849 them->sin_addr = udptl->them.sin_addr; 00850 }
void ast_udptl_get_us | ( | struct ast_udptl * | udptl, | |
struct sockaddr_in * | us | |||
) |
void ast_udptl_init | ( | void | ) |
Definition at line 1243 of file udptl.c.
References ast_cli_register_multiple(), and ast_udptl_reload().
Referenced by main().
01244 { 01245 ast_cli_register_multiple(cli_udptl, sizeof(cli_udptl) / sizeof(struct ast_cli_entry)); 01246 ast_udptl_reload(); 01247 }
int ast_udptl_lookup_code | ( | struct ast_udptl * | udptl, | |
int | isAstFormat, | |||
int | code | |||
) |
struct ast_udptl* ast_udptl_new | ( | struct sched_context * | sched, | |
struct io_context * | io, | |||
int | callbackmode | |||
) | [read] |
Definition at line 823 of file udptl.c.
References ast_udptl_new_with_bindaddr().
00824 { 00825 struct in_addr ia; 00826 memset(&ia, 0, sizeof(ia)); 00827 return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia); 00828 }
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 747 of file udptl.c.
References ast_calloc, 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_scheme, ast_udptl::error_correction_span, ast_udptl::far_max_datagram_size, ast_udptl::fd, ast_udptl::flags, free, ast_udptl::io, ast_udptl::ioid, ast_udptl::local_max_datagram_size, LOG_WARNING, ast_udptl::rx, ast_udptl::sched, ast_udptl::them, ast_udptl::tx, UDPTL_BUF_MASK, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, udptlread(), and ast_udptl::us.
Referenced by ast_udptl_new(), and sip_alloc().
00748 { 00749 struct ast_udptl *udptl; 00750 int x; 00751 int startplace; 00752 int i; 00753 long int flags; 00754 00755 if (!(udptl = ast_calloc(1, sizeof(*udptl)))) 00756 return NULL; 00757 00758 if (udptlfectype == 2) 00759 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC; 00760 else if (udptlfectype == 1) 00761 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY; 00762 else 00763 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE; 00764 udptl->error_correction_span = udptlfecspan; 00765 udptl->error_correction_entries = udptlfecentries; 00766 00767 udptl->far_max_datagram_size = udptlmaxdatagram; 00768 udptl->local_max_datagram_size = udptlmaxdatagram; 00769 00770 memset(&udptl->rx, 0, sizeof(udptl->rx)); 00771 memset(&udptl->tx, 0, sizeof(udptl->tx)); 00772 for (i = 0; i <= UDPTL_BUF_MASK; i++) { 00773 udptl->rx[i].buf_len = -1; 00774 udptl->tx[i].buf_len = -1; 00775 } 00776 00777 udptl->them.sin_family = AF_INET; 00778 udptl->us.sin_family = AF_INET; 00779 00780 if ((udptl->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 00781 free(udptl); 00782 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno)); 00783 return NULL; 00784 } 00785 flags = fcntl(udptl->fd, F_GETFL); 00786 fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK); 00787 #ifdef SO_NO_CHECK 00788 if (nochecksums) 00789 setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 00790 #endif 00791 /* Find us a place */ 00792 x = (ast_random() % (udptlend - udptlstart)) + udptlstart; 00793 startplace = x; 00794 for (;;) { 00795 udptl->us.sin_port = htons(x); 00796 udptl->us.sin_addr = addr; 00797 if (bind(udptl->fd, (struct sockaddr *) &udptl->us, sizeof(udptl->us)) == 0) 00798 break; 00799 if (errno != EADDRINUSE) { 00800 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno)); 00801 close(udptl->fd); 00802 free(udptl); 00803 return NULL; 00804 } 00805 if (++x > udptlend) 00806 x = udptlstart; 00807 if (x == startplace) { 00808 ast_log(LOG_WARNING, "No UDPTL ports remaining\n"); 00809 close(udptl->fd); 00810 free(udptl); 00811 return NULL; 00812 } 00813 } 00814 if (io && sched && callbackmode) { 00815 /* Operate this one in a callback mode */ 00816 udptl->sched = sched; 00817 udptl->io = io; 00818 udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl); 00819 } 00820 return udptl; 00821 }
void ast_udptl_offered_from_local | ( | struct ast_udptl * | udptl, | |
int | local | |||
) |
Definition at line 673 of file udptl.c.
References ast_log(), LOG_WARNING, and ast_udptl::udptl_offered_from_local.
Referenced by transmit_invite(), transmit_reinvite_with_t38_sdp(), and transmit_response_with_t38_sdp().
00674 { 00675 if (udptl) 00676 udptl->udptl_offered_from_local = local; 00677 else 00678 ast_log(LOG_WARNING, "udptl structure is null\n"); 00679 }
int ast_udptl_proto_register | ( | struct ast_udptl_protocol * | proto | ) |
Definition at line 933 of file udptl.c.
References ast_log(), LOG_WARNING, ast_udptl_protocol::next, and ast_udptl_protocol::type.
Referenced by load_module().
00934 { 00935 struct ast_udptl_protocol *cur; 00936 00937 cur = protos; 00938 while (cur) { 00939 if (cur->type == proto->type) { 00940 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type); 00941 return -1; 00942 } 00943 cur = cur->next; 00944 } 00945 proto->next = protos; 00946 protos = proto; 00947 return 0; 00948 }
void ast_udptl_proto_unregister | ( | struct ast_udptl_protocol * | proto | ) |
Definition at line 913 of file udptl.c.
References ast_udptl_protocol::next.
Referenced by unload_module().
00914 { 00915 struct ast_udptl_protocol *cur; 00916 struct ast_udptl_protocol *prev; 00917 00918 cur = protos; 00919 prev = NULL; 00920 while (cur) { 00921 if (cur == proto) { 00922 if (prev) 00923 prev->next = proto->next; 00924 else 00925 protos = proto->next; 00926 return; 00927 } 00928 prev = cur; 00929 cur = cur->next; 00930 } 00931 }
Definition at line 621 of file udptl.c.
References AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_verbose(), CRASH, errno, ast_udptl::f, ast_udptl::fd, len, LOG_DEBUG, 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().
00622 { 00623 int res; 00624 struct sockaddr_in sin; 00625 socklen_t len; 00626 uint16_t seqno = 0; 00627 uint16_t *udptlheader; 00628 00629 len = sizeof(sin); 00630 00631 /* Cache where the header will go */ 00632 res = recvfrom(udptl->fd, 00633 udptl->rawdata + AST_FRIENDLY_OFFSET, 00634 sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET, 00635 0, 00636 (struct sockaddr *) &sin, 00637 &len); 00638 udptlheader = (uint16_t *)(udptl->rawdata + AST_FRIENDLY_OFFSET); 00639 if (res < 0) { 00640 if (errno != EAGAIN) 00641 ast_log(LOG_WARNING, "UDPTL read error: %s\n", strerror(errno)); 00642 if (errno == EBADF) 00643 CRASH; 00644 return &ast_null_frame; 00645 } 00646 00647 /* Ignore if the other side hasn't been given an address yet. */ 00648 if (!udptl->them.sin_addr.s_addr || !udptl->them.sin_port) 00649 return &ast_null_frame; 00650 00651 if (udptl->nat) { 00652 /* Send to whoever sent to us */ 00653 if ((udptl->them.sin_addr.s_addr != sin.sin_addr.s_addr) || 00654 (udptl->them.sin_port != sin.sin_port)) { 00655 memcpy(&udptl->them, &sin, sizeof(udptl->them)); 00656 ast_log(LOG_DEBUG, "UDPTL NAT: Using address %s:%d\n", ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port)); 00657 } 00658 } 00659 00660 if (udptl_debug_test_addr(&sin)) { 00661 ast_verbose("Got UDPTL packet from %s:%d (type %d, seq %d, len %d)\n", 00662 ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 0, seqno, res); 00663 } 00664 #if 0 00665 printf("Got UDPTL packet from %s:%d (seq %d, len = %d)\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), seqno, res); 00666 #endif 00667 if (udptl_rx_packet(udptl, udptl->rawdata + AST_FRIENDLY_OFFSET, res) < 1) 00668 return &ast_null_frame; 00669 00670 return &udptl->f[0]; 00671 }
void ast_udptl_reload | ( | void | ) |
Definition at line 1167 of file udptl.c.
References ast_config_destroy(), ast_config_load(), ast_false(), ast_log(), ast_variable_retrieve(), ast_verbose(), LOCAL_FAX_MAX_DATAGRAM, LOG_WARNING, MAX_FEC_ENTRIES, MAX_FEC_SPAN, option_verbose, s, and VERBOSE_PREFIX_2.
Referenced by ast_udptl_init().
01168 { 01169 struct ast_config *cfg; 01170 const char *s; 01171 01172 udptlstart = 4500; 01173 udptlend = 4999; 01174 udptlfectype = 0; 01175 udptlfecentries = 0; 01176 udptlfecspan = 0; 01177 udptlmaxdatagram = 0; 01178 01179 if ((cfg = ast_config_load("udptl.conf"))) { 01180 if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) { 01181 udptlstart = atoi(s); 01182 if (udptlstart < 1024) 01183 udptlstart = 1024; 01184 if (udptlstart > 65535) 01185 udptlstart = 65535; 01186 } 01187 if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) { 01188 udptlend = atoi(s); 01189 if (udptlend < 1024) 01190 udptlend = 1024; 01191 if (udptlend > 65535) 01192 udptlend = 65535; 01193 } 01194 if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) { 01195 #ifdef SO_NO_CHECK 01196 if (ast_false(s)) 01197 nochecksums = 1; 01198 else 01199 nochecksums = 0; 01200 #else 01201 if (ast_false(s)) 01202 ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n"); 01203 #endif 01204 } 01205 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) { 01206 if (strcmp(s, "t38UDPFEC") == 0) 01207 udptlfectype = 2; 01208 else if (strcmp(s, "t38UDPRedundancy") == 0) 01209 udptlfectype = 1; 01210 } 01211 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) { 01212 udptlmaxdatagram = atoi(s); 01213 if (udptlmaxdatagram < 0) 01214 udptlmaxdatagram = 0; 01215 if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM) 01216 udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM; 01217 } 01218 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) { 01219 udptlfecentries = atoi(s); 01220 if (udptlfecentries < 0) 01221 udptlfecentries = 0; 01222 if (udptlfecentries > MAX_FEC_ENTRIES) 01223 udptlfecentries = MAX_FEC_ENTRIES; 01224 } 01225 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) { 01226 udptlfecspan = atoi(s); 01227 if (udptlfecspan < 0) 01228 udptlfecspan = 0; 01229 if (udptlfecspan > MAX_FEC_SPAN) 01230 udptlfecspan = MAX_FEC_SPAN; 01231 } 01232 ast_config_destroy(cfg); 01233 } 01234 if (udptlstart >= udptlend) { 01235 ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end\n"); 01236 udptlstart = 4500; 01237 udptlend = 4999; 01238 } 01239 if (option_verbose > 1) 01240 ast_verbose(VERBOSE_PREFIX_2 "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend); 01241 }
void ast_udptl_reset | ( | struct ast_udptl * | udptl | ) |
void ast_udptl_set_callback | ( | struct ast_udptl * | udptl, | |
ast_udptl_callback | callback | |||
) |
Definition at line 599 of file udptl.c.
References ast_udptl::callback.
00600 { 00601 udptl->callback = callback; 00602 }
void ast_udptl_set_data | ( | struct ast_udptl * | udptl, | |
void * | data | |||
) |
Definition at line 594 of file udptl.c.
References ast_udptl::data.
00595 { 00596 udptl->data = data; 00597 }
void ast_udptl_set_error_correction_scheme | ( | struct ast_udptl * | udptl, | |
int | ec | |||
) |
Definition at line 691 of file udptl.c.
References ast_log(), ast_udptl::error_correction_scheme, LOG_WARNING, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.
Referenced by process_sdp(), and sip_handle_t38_reinvite().
00692 { 00693 if (udptl) { 00694 switch (ec) { 00695 case UDPTL_ERROR_CORRECTION_FEC: 00696 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC; 00697 break; 00698 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 00699 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY; 00700 break; 00701 case UDPTL_ERROR_CORRECTION_NONE: 00702 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE; 00703 break; 00704 default: 00705 ast_log(LOG_WARNING, "error correction parameter invalid\n"); 00706 }; 00707 } else 00708 ast_log(LOG_WARNING, "udptl structure is null\n"); 00709 }
void ast_udptl_set_far_max_datagram | ( | struct ast_udptl * | udptl, | |
int | max_datagram | |||
) |
Definition at line 739 of file udptl.c.
References ast_log(), ast_udptl::far_max_datagram_size, and LOG_WARNING.
Referenced by process_sdp(), and sip_handle_t38_reinvite().
00740 { 00741 if (udptl) 00742 udptl->far_max_datagram_size = max_datagram; 00743 else 00744 ast_log(LOG_WARNING, "udptl structure is null\n"); 00745 }
void ast_udptl_set_local_max_datagram | ( | struct ast_udptl * | udptl, | |
int | max_datagram | |||
) |
Definition at line 731 of file udptl.c.
References ast_log(), ast_udptl::local_max_datagram_size, and LOG_WARNING.
Referenced by process_sdp(), and sip_handle_t38_reinvite().
00732 { 00733 if (udptl) 00734 udptl->local_max_datagram_size = max_datagram; 00735 else 00736 ast_log(LOG_WARNING, "udptl structure is null\n"); 00737 }
void ast_udptl_set_m_type | ( | struct ast_udptl * | udptl, | |
int | pt | |||
) |
void ast_udptl_set_peer | ( | struct ast_udptl * | udptl, | |
struct sockaddr_in * | them | |||
) |
Definition at line 839 of file udptl.c.
References ast_udptl::them.
Referenced by process_sdp().
00840 { 00841 udptl->them.sin_port = them->sin_port; 00842 udptl->them.sin_addr = them->sin_addr; 00843 }
void ast_udptl_set_udptlmap_type | ( | struct ast_udptl * | udptl, | |
int | pt, | |||
char * | mimeType, | |||
char * | mimeSubtype | |||
) |
void ast_udptl_setnat | ( | struct ast_udptl * | udptl, | |
int | nat | |||
) |
int ast_udptl_settos | ( | struct ast_udptl * | udptl, | |
int | tos | |||
) |
Definition at line 830 of file udptl.c.
References ast_log(), ast_udptl::fd, and LOG_WARNING.
Referenced by sip_alloc().
00831 { 00832 int res; 00833 00834 if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) 00835 ast_log(LOG_WARNING, "UDPTL unable to set TOS to %d\n", tos); 00836 return res; 00837 }
void ast_udptl_stop | ( | struct ast_udptl * | udptl | ) |
Definition at line 857 of file udptl.c.
References ast_udptl::them.
Referenced by process_sdp(), and stop_media_flows().
00858 { 00859 memset(&udptl->them.sin_addr, 0, sizeof(udptl->them.sin_addr)); 00860 memset(&udptl->them.sin_port, 0, sizeof(udptl->them.sin_port)); 00861 }
Definition at line 872 of file udptl.c.
References AST_FRAME_MODEM, ast_inet_ntoa(), ast_log(), ast_verbose(), ast_frame::data, ast_frame::datalen, errno, ast_udptl::fd, ast_frame::frametype, len, LOCAL_FAX_MAX_DATAGRAM, LOG_NOTICE, LOG_WARNING, seq, ast_udptl::them, ast_udptl::tx_seq_no, udptl_build_packet(), and udptl_debug_test_addr().
Referenced by sip_write().
00873 { 00874 int seq; 00875 int len; 00876 int res; 00877 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]; 00878 00879 /* If we have no peer, return immediately */ 00880 if (s->them.sin_addr.s_addr == INADDR_ANY) 00881 return 0; 00882 00883 /* If there is no data length, return immediately */ 00884 if (f->datalen == 0) 00885 return 0; 00886 00887 if (f->frametype != AST_FRAME_MODEM) { 00888 ast_log(LOG_WARNING, "UDPTL can only send T.38 data\n"); 00889 return -1; 00890 } 00891 00892 /* Save seq_no for debug output because udptl_build_packet increments it */ 00893 seq = s->tx_seq_no & 0xFFFF; 00894 00895 /* Cook up the UDPTL packet, with the relevant EC info. */ 00896 len = udptl_build_packet(s, buf, f->data, f->datalen); 00897 00898 if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) { 00899 if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0) 00900 ast_log(LOG_NOTICE, "UDPTL Transmission error to %s:%d: %s\n", ast_inet_ntoa(s->them.sin_addr), ntohs(s->them.sin_port), strerror(errno)); 00901 #if 0 00902 printf("Sent %d bytes of UDPTL data to %s:%d\n", res, ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port)); 00903 #endif 00904 if (udptl_debug_test_addr(&s->them)) 00905 ast_verbose("Sent UDPTL packet to %s:%d (type %d, seq %d, len %d)\n", 00906 ast_inet_ntoa(s->them.sin_addr), 00907 ntohs(s->them.sin_port), 0, seq, len); 00908 } 00909 00910 return 0; 00911 }