#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 970 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.
00971 { 00972 struct ast_frame *f; 00973 struct ast_channel *who; 00974 struct ast_channel *cs[3]; 00975 struct ast_udptl *p0; 00976 struct ast_udptl *p1; 00977 struct ast_udptl_protocol *pr0; 00978 struct ast_udptl_protocol *pr1; 00979 struct sockaddr_in ac0; 00980 struct sockaddr_in ac1; 00981 struct sockaddr_in t0; 00982 struct sockaddr_in t1; 00983 void *pvt0; 00984 void *pvt1; 00985 int to; 00986 00987 ast_channel_lock(c0); 00988 while (ast_channel_trylock(c1)) { 00989 ast_channel_unlock(c0); 00990 usleep(1); 00991 ast_channel_lock(c0); 00992 } 00993 pr0 = get_proto(c0); 00994 pr1 = get_proto(c1); 00995 if (!pr0) { 00996 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name); 00997 ast_channel_unlock(c0); 00998 ast_channel_unlock(c1); 00999 return -1; 01000 } 01001 if (!pr1) { 01002 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name); 01003 ast_channel_unlock(c0); 01004 ast_channel_unlock(c1); 01005 return -1; 01006 } 01007 pvt0 = c0->tech_pvt; 01008 pvt1 = c1->tech_pvt; 01009 p0 = pr0->get_udptl_info(c0); 01010 p1 = pr1->get_udptl_info(c1); 01011 if (!p0 || !p1) { 01012 /* Somebody doesn't want to play... */ 01013 ast_channel_unlock(c0); 01014 ast_channel_unlock(c1); 01015 return -2; 01016 } 01017 if (pr0->set_udptl_peer(c0, p1)) { 01018 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name); 01019 } else { 01020 /* Store UDPTL peer */ 01021 ast_udptl_get_peer(p1, &ac1); 01022 } 01023 if (pr1->set_udptl_peer(c1, p0)) 01024 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name); 01025 else { 01026 /* Store UDPTL peer */ 01027 ast_udptl_get_peer(p0, &ac0); 01028 } 01029 ast_channel_unlock(c0); 01030 ast_channel_unlock(c1); 01031 cs[0] = c0; 01032 cs[1] = c1; 01033 cs[2] = NULL; 01034 for (;;) { 01035 if ((c0->tech_pvt != pvt0) || 01036 (c1->tech_pvt != pvt1) || 01037 (c0->masq || c0->masqr || c1->masq || c1->masqr)) { 01038 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n"); 01039 /* Tell it to try again later */ 01040 return -3; 01041 } 01042 to = -1; 01043 ast_udptl_get_peer(p1, &t1); 01044 ast_udptl_get_peer(p0, &t0); 01045 if (inaddrcmp(&t1, &ac1)) { 01046 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n", 01047 c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port)); 01048 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n", 01049 c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port)); 01050 memcpy(&ac1, &t1, sizeof(ac1)); 01051 } 01052 if (inaddrcmp(&t0, &ac0)) { 01053 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d\n", 01054 c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port)); 01055 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d\n", 01056 c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port)); 01057 memcpy(&ac0, &t0, sizeof(ac0)); 01058 } 01059 who = ast_waitfor_n(cs, 2, &to); 01060 if (!who) { 01061 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 01062 /* check for hangup / whentohangup */ 01063 if (ast_check_hangup(c0) || ast_check_hangup(c1)) 01064 break; 01065 continue; 01066 } 01067 f = ast_read(who); 01068 if (!f) { 01069 *fo = f; 01070 *rc = who; 01071 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup"); 01072 /* That's all we needed */ 01073 return 0; 01074 } else { 01075 if (f->frametype == AST_FRAME_MODEM) { 01076 /* Forward T.38 frames if they happen upon us */ 01077 if (who == c0) { 01078 ast_write(c1, f); 01079 } else if (who == c1) { 01080 ast_write(c0, f); 01081 } 01082 } 01083 ast_frfree(f); 01084 } 01085 /* Swap priority. Not that it's a big deal at this point */ 01086 cs[2] = cs[0]; 01087 cs[0] = cs[1]; 01088 cs[1] = cs[2]; 01089 } 01090 return -1; 01091 }
void ast_udptl_destroy | ( | struct ast_udptl * | udptl | ) |
Definition at line 874 of file udptl.c.
References ast_io_remove(), ast_udptl::fd, free, ast_udptl::io, and ast_udptl::ioid.
00875 { 00876 if (udptl->ioid) 00877 ast_io_remove(udptl->io, udptl->ioid); 00878 if (udptl->fd > -1) 00879 close(udptl->fd); 00880 free(udptl); 00881 }
int ast_udptl_fd | ( | struct ast_udptl * | udptl | ) |
Definition at line 600 of file udptl.c.
References ast_udptl::fd.
00601 { 00602 return udptl->fd; 00603 }
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 691 of file udptl.c.
References ast_log(), ast_udptl::error_correction_scheme, and LOG_WARNING.
00692 { 00693 if (udptl) 00694 return udptl->error_correction_scheme; 00695 else { 00696 ast_log(LOG_WARNING, "udptl structure is null\n"); 00697 return -1; 00698 } 00699 }
int ast_udptl_get_far_max_datagram | ( | struct ast_udptl * | udptl | ) |
Definition at line 731 of file udptl.c.
References ast_log(), ast_udptl::far_max_datagram_size, and LOG_WARNING.
00732 { 00733 if (udptl) 00734 return udptl->far_max_datagram_size; 00735 else { 00736 ast_log(LOG_WARNING, "udptl structure is null\n"); 00737 return -1; 00738 } 00739 }
int ast_udptl_get_local_max_datagram | ( | struct ast_udptl * | udptl | ) |
Definition at line 721 of file udptl.c.
References ast_log(), ast_udptl::local_max_datagram_size, and LOG_WARNING.
00722 { 00723 if (udptl) 00724 return udptl->local_max_datagram_size; 00725 else { 00726 ast_log(LOG_WARNING, "udptl structure is null\n"); 00727 return -1; 00728 } 00729 }
void ast_udptl_get_peer | ( | struct ast_udptl * | udptl, | |
struct sockaddr_in * | them | |||
) |
Definition at line 856 of file udptl.c.
References ast_udptl::them.
00857 { 00858 them->sin_family = AF_INET; 00859 them->sin_port = udptl->them.sin_port; 00860 them->sin_addr = udptl->them.sin_addr; 00861 }
void ast_udptl_get_us | ( | struct ast_udptl * | udptl, | |
struct sockaddr_in * | us | |||
) |
void ast_udptl_init | ( | void | ) |
Definition at line 1250 of file udptl.c.
References ast_cli_register_multiple(), and ast_udptl_reload().
01251 { 01252 ast_cli_register_multiple(cli_udptl, sizeof(cli_udptl) / sizeof(struct ast_cli_entry)); 01253 ast_udptl_reload(); 01254 }
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 834 of file udptl.c.
References ast_udptl_new_with_bindaddr().
00835 { 00836 struct in_addr ia; 00837 memset(&ia, 0, sizeof(ia)); 00838 return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia); 00839 }
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 757 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, 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::seqno, 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.
00758 { 00759 struct ast_udptl *udptl; 00760 int x; 00761 int startplace; 00762 int i; 00763 long int flags; 00764 00765 if (!(udptl = ast_calloc(1, sizeof(*udptl)))) 00766 return NULL; 00767 00768 if (udptlfectype == 2) 00769 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC; 00770 else if (udptlfectype == 1) 00771 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY; 00772 else 00773 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE; 00774 udptl->error_correction_span = udptlfecspan; 00775 udptl->error_correction_entries = udptlfecentries; 00776 00777 udptl->far_max_datagram_size = udptlmaxdatagram; 00778 udptl->local_max_datagram_size = udptlmaxdatagram; 00779 00780 memset(&udptl->rx, 0, sizeof(udptl->rx)); 00781 memset(&udptl->tx, 0, sizeof(udptl->tx)); 00782 for (i = 0; i <= UDPTL_BUF_MASK; i++) { 00783 udptl->rx[i].buf_len = -1; 00784 udptl->tx[i].buf_len = -1; 00785 } 00786 00787 udptl->seqno = ast_random() & 0xffff; 00788 udptl->them.sin_family = AF_INET; 00789 udptl->us.sin_family = AF_INET; 00790 00791 if ((udptl->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 00792 free(udptl); 00793 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno)); 00794 return NULL; 00795 } 00796 flags = fcntl(udptl->fd, F_GETFL); 00797 fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK); 00798 #ifdef SO_NO_CHECK 00799 if (nochecksums) 00800 setsockopt(udptl->fd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 00801 #endif 00802 /* Find us a place */ 00803 x = (ast_random() % (udptlend - udptlstart)) + udptlstart; 00804 startplace = x; 00805 for (;;) { 00806 udptl->us.sin_port = htons(x); 00807 udptl->us.sin_addr = addr; 00808 if (bind(udptl->fd, (struct sockaddr *) &udptl->us, sizeof(udptl->us)) == 0) 00809 break; 00810 if (errno != EADDRINUSE) { 00811 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno)); 00812 close(udptl->fd); 00813 free(udptl); 00814 return NULL; 00815 } 00816 if (++x > udptlend) 00817 x = udptlstart; 00818 if (x == startplace) { 00819 ast_log(LOG_WARNING, "No UDPTL ports remaining\n"); 00820 close(udptl->fd); 00821 free(udptl); 00822 return NULL; 00823 } 00824 } 00825 if (io && sched && callbackmode) { 00826 /* Operate this one in a callback mode */ 00827 udptl->sched = sched; 00828 udptl->io = io; 00829 udptl->ioid = ast_io_add(udptl->io, udptl->fd, udptlread, AST_IO_IN, udptl); 00830 } 00831 return udptl; 00832 }
void ast_udptl_offered_from_local | ( | struct ast_udptl * | udptl, | |
int | local | |||
) |
Definition at line 683 of file udptl.c.
References ast_log(), LOG_WARNING, and ast_udptl::udptl_offered_from_local.
00684 { 00685 if (udptl) 00686 udptl->udptl_offered_from_local = local; 00687 else 00688 ast_log(LOG_WARNING, "udptl structure is null\n"); 00689 }
int ast_udptl_proto_register | ( | struct ast_udptl_protocol * | proto | ) |
Definition at line 940 of file udptl.c.
References ast_log(), LOG_WARNING, ast_udptl_protocol::next, and ast_udptl_protocol::type.
00941 { 00942 struct ast_udptl_protocol *cur; 00943 00944 cur = protos; 00945 while (cur) { 00946 if (cur->type == proto->type) { 00947 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type); 00948 return -1; 00949 } 00950 cur = cur->next; 00951 } 00952 proto->next = protos; 00953 protos = proto; 00954 return 0; 00955 }
void ast_udptl_proto_unregister | ( | struct ast_udptl_protocol * | proto | ) |
Definition at line 920 of file udptl.c.
References ast_udptl_protocol::next.
00921 { 00922 struct ast_udptl_protocol *cur; 00923 struct ast_udptl_protocol *prev; 00924 00925 cur = protos; 00926 prev = NULL; 00927 while (cur) { 00928 if (cur == proto) { 00929 if (prev) 00930 prev->next = proto->next; 00931 else 00932 protos = proto->next; 00933 return; 00934 } 00935 prev = cur; 00936 cur = cur->next; 00937 } 00938 }
Definition at line 632 of file udptl.c.
References AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_verbose(), CRASH, 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().
00633 { 00634 int res; 00635 struct sockaddr_in sin; 00636 socklen_t len; 00637 uint16_t seqno = 0; 00638 uint16_t *udptlheader; 00639 00640 len = sizeof(sin); 00641 00642 /* Cache where the header will go */ 00643 res = recvfrom(udptl->fd, 00644 udptl->rawdata + AST_FRIENDLY_OFFSET, 00645 sizeof(udptl->rawdata) - AST_FRIENDLY_OFFSET, 00646 0, 00647 (struct sockaddr *) &sin, 00648 &len); 00649 udptlheader = (uint16_t *)(udptl->rawdata + AST_FRIENDLY_OFFSET); 00650 if (res < 0) { 00651 if (errno != EAGAIN) 00652 ast_log(LOG_WARNING, "UDPTL read error: %s\n", strerror(errno)); 00653 if (errno == EBADF) 00654 CRASH; 00655 return &ast_null_frame; 00656 } 00657 00658 /* Ignore if the other side hasn't been given an address yet. */ 00659 if (!udptl->them.sin_addr.s_addr || !udptl->them.sin_port) 00660 return &ast_null_frame; 00661 00662 if (udptl->nat) { 00663 /* Send to whoever sent to us */ 00664 if ((udptl->them.sin_addr.s_addr != sin.sin_addr.s_addr) || 00665 (udptl->them.sin_port != sin.sin_port)) { 00666 memcpy(&udptl->them, &sin, sizeof(udptl->them)); 00667 ast_log(LOG_DEBUG, "UDPTL NAT: Using address %s:%d\n", ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port)); 00668 } 00669 } 00670 00671 if (udptl_debug_test_addr(&sin)) { 00672 ast_verbose("Got UDPTL packet from %s:%d (type %d, seq %d, len %d)\n", 00673 ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), 0, seqno, res); 00674 } 00675 #if 0 00676 printf("Got UDPTL packet from %s:%d (seq %d, len = %d)\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), seqno, res); 00677 #endif 00678 udptl_rx_packet(udptl, udptl->rawdata + AST_FRIENDLY_OFFSET, res); 00679 00680 return &udptl->f[0]; 00681 }
void ast_udptl_reload | ( | void | ) |
Definition at line 1174 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.
01175 { 01176 struct ast_config *cfg; 01177 const char *s; 01178 01179 udptlstart = 4500; 01180 udptlend = 4999; 01181 udptlfectype = 0; 01182 udptlfecentries = 0; 01183 udptlfecspan = 0; 01184 udptlmaxdatagram = 0; 01185 01186 if ((cfg = ast_config_load("udptl.conf"))) { 01187 if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) { 01188 udptlstart = atoi(s); 01189 if (udptlstart < 1024) 01190 udptlstart = 1024; 01191 if (udptlstart > 65535) 01192 udptlstart = 65535; 01193 } 01194 if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) { 01195 udptlend = atoi(s); 01196 if (udptlend < 1024) 01197 udptlend = 1024; 01198 if (udptlend > 65535) 01199 udptlend = 65535; 01200 } 01201 if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) { 01202 #ifdef SO_NO_CHECK 01203 if (ast_false(s)) 01204 nochecksums = 1; 01205 else 01206 nochecksums = 0; 01207 #else 01208 if (ast_false(s)) 01209 ast_log(LOG_WARNING, "Disabling UDPTL checksums is not supported on this operating system!\n"); 01210 #endif 01211 } 01212 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxUdpEC"))) { 01213 if (strcmp(s, "t38UDPFEC") == 0) 01214 udptlfectype = 2; 01215 else if (strcmp(s, "t38UDPRedundancy") == 0) 01216 udptlfectype = 1; 01217 } 01218 if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) { 01219 udptlmaxdatagram = atoi(s); 01220 if (udptlmaxdatagram < 0) 01221 udptlmaxdatagram = 0; 01222 if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM) 01223 udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM; 01224 } 01225 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) { 01226 udptlfecentries = atoi(s); 01227 if (udptlfecentries < 0) 01228 udptlfecentries = 0; 01229 if (udptlfecentries > MAX_FEC_ENTRIES) 01230 udptlfecentries = MAX_FEC_ENTRIES; 01231 } 01232 if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) { 01233 udptlfecspan = atoi(s); 01234 if (udptlfecspan < 0) 01235 udptlfecspan = 0; 01236 if (udptlfecspan > MAX_FEC_SPAN) 01237 udptlfecspan = MAX_FEC_SPAN; 01238 } 01239 ast_config_destroy(cfg); 01240 } 01241 if (udptlstart >= udptlend) { 01242 ast_log(LOG_WARNING, "Unreasonable values for UDPTL start/end\n"); 01243 udptlstart = 4500; 01244 udptlend = 4999; 01245 } 01246 if (option_verbose > 1) 01247 ast_verbose(VERBOSE_PREFIX_2 "UDPTL allocating from port range %d -> %d\n", udptlstart, udptlend); 01248 }
void ast_udptl_reset | ( | struct ast_udptl * | udptl | ) |
void ast_udptl_set_callback | ( | struct ast_udptl * | udptl, | |
ast_udptl_callback | callback | |||
) |
Definition at line 610 of file udptl.c.
References ast_udptl::callback.
00611 { 00612 udptl->callback = callback; 00613 }
void ast_udptl_set_data | ( | struct ast_udptl * | udptl, | |
void * | data | |||
) |
Definition at line 605 of file udptl.c.
References ast_udptl::data.
00606 { 00607 udptl->data = data; 00608 }
void ast_udptl_set_error_correction_scheme | ( | struct ast_udptl * | udptl, | |
int | ec | |||
) |
Definition at line 701 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.
00702 { 00703 if (udptl) { 00704 switch (ec) { 00705 case UDPTL_ERROR_CORRECTION_FEC: 00706 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_FEC; 00707 break; 00708 case UDPTL_ERROR_CORRECTION_REDUNDANCY: 00709 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_REDUNDANCY; 00710 break; 00711 case UDPTL_ERROR_CORRECTION_NONE: 00712 udptl->error_correction_scheme = UDPTL_ERROR_CORRECTION_NONE; 00713 break; 00714 default: 00715 ast_log(LOG_WARNING, "error correction parameter invalid\n"); 00716 }; 00717 } else 00718 ast_log(LOG_WARNING, "udptl structure is null\n"); 00719 }
void ast_udptl_set_far_max_datagram | ( | struct ast_udptl * | udptl, | |
int | max_datagram | |||
) |
Definition at line 749 of file udptl.c.
References ast_log(), ast_udptl::far_max_datagram_size, and LOG_WARNING.
00750 { 00751 if (udptl) 00752 udptl->far_max_datagram_size = max_datagram; 00753 else 00754 ast_log(LOG_WARNING, "udptl structure is null\n"); 00755 }
void ast_udptl_set_local_max_datagram | ( | struct ast_udptl * | udptl, | |
int | max_datagram | |||
) |
Definition at line 741 of file udptl.c.
References ast_log(), ast_udptl::local_max_datagram_size, and LOG_WARNING.
00742 { 00743 if (udptl) 00744 udptl->local_max_datagram_size = max_datagram; 00745 else 00746 ast_log(LOG_WARNING, "udptl structure is null\n"); 00747 }
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 850 of file udptl.c.
References ast_udptl::them.
00851 { 00852 udptl->them.sin_port = them->sin_port; 00853 udptl->them.sin_addr = them->sin_addr; 00854 }
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 841 of file udptl.c.
References ast_log(), ast_udptl::fd, and LOG_WARNING.
00842 { 00843 int res; 00844 00845 if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) 00846 ast_log(LOG_WARNING, "UDPTL unable to set TOS to %d\n", tos); 00847 return res; 00848 }
void ast_udptl_stop | ( | struct ast_udptl * | udptl | ) |
Definition at line 883 of file udptl.c.
References AST_FRAME_MODEM, ast_inet_ntoa(), ast_log(), ast_verbose(), ast_frame::data, ast_frame::datalen, ast_udptl::fd, ast_frame::frametype, len, LOCAL_FAX_MAX_DATAGRAM, LOG_NOTICE, LOG_WARNING, ast_udptl::seqno, ast_udptl::them, udptl_build_packet(), and udptl_debug_test_addr().
00884 { 00885 int len; 00886 int res; 00887 uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]; 00888 00889 /* If we have no peer, return immediately */ 00890 if (s->them.sin_addr.s_addr == INADDR_ANY) 00891 return 0; 00892 00893 /* If there is no data length, return immediately */ 00894 if (f->datalen == 0) 00895 return 0; 00896 00897 if (f->frametype != AST_FRAME_MODEM) { 00898 ast_log(LOG_WARNING, "UDPTL can only send T.38 data\n"); 00899 return -1; 00900 } 00901 00902 /* Cook up the UDPTL packet, with the relevant EC info. */ 00903 len = udptl_build_packet(s, buf, f->data, f->datalen); 00904 00905 if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) { 00906 if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0) 00907 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)); 00908 #if 0 00909 printf("Sent %d bytes of UDPTL data to %s:%d\n", res, ast_inet_ntoa(udptl->them.sin_addr), ntohs(udptl->them.sin_port)); 00910 #endif 00911 if (udptl_debug_test_addr(&s->them)) 00912 ast_verbose("Sent UDPTL packet to %s:%d (type %d, seq %d, len %d)\n", 00913 ast_inet_ntoa(s->them.sin_addr), 00914 ntohs(s->them.sin_port), 0, s->seqno, len); 00915 } 00916 00917 return 0; 00918 }