Index: rtp.c =================================================================== --- rtp.c (revision 48974) +++ rtp.c (working copy) @@ -29,7 +29,6 @@ #include "asterisk.h" ASTERISK_FILE_VERSION(__FILE__, "$Revision$") - #include #include #include @@ -42,7 +41,6 @@ #include #include #include - #include "asterisk/rtp.h" #include "asterisk/frame.h" #include "asterisk/logger.h" @@ -56,38 +54,32 @@ #include "asterisk/cli.h" #include "asterisk/unaligned.h" #include "asterisk/utils.h" - #define MAX_TIMESTAMP_SKEW 640 - -#define RTP_SEQ_MOD (1<<16) /*!< A sequence number can't be more than 16 bits */ +#define RTP_SEQ_MOD (1<<16) /*!< A sequence number can't be more than 16 bits */ #define RTCP_DEFAULT_INTERVALMS 5000 /*!< Default milli-seconds between RTCP reports we send */ #define RTCP_MIN_INTERVALMS 500 /*!< Min milli-seconds between RTCP reports we send */ #define RTCP_MAX_INTERVALMS 60000 /*!< Max milli-seconds between RTCP reports we send */ - #define RTCP_PT_FUR 192 #define RTCP_PT_SR 200 #define RTCP_PT_RR 201 #define RTCP_PT_SDES 202 #define RTCP_PT_BYE 203 #define RTCP_PT_APP 204 - #define RTP_MTU 1200 - #define DEFAULT_DTMF_TIMEOUT 3000 /*!< samples */ + static int dtmftimeout = DEFAULT_DTMF_TIMEOUT; -static int dtmftimeout = DEFAULT_DTMF_TIMEOUT; - -static int rtpstart = 0; /*!< First port for RTP sessions (set in rtp.conf) */ -static int rtpend = 0; /*!< Last port for RTP sessions (set in rtp.conf) */ -static int rtpdebug = 0; /*!< Are we debugging? */ -static int rtcpdebug = 0; /*!< Are we debugging RTCP? */ -static int rtcpstats = 0; /*!< Are we debugging RTCP? */ -static int rtcpinterval = RTCP_DEFAULT_INTERVALMS; /*!< Time between rtcp reports in millisecs */ -static int stundebug = 0; /*!< Are we debugging stun? */ -static struct sockaddr_in rtpdebugaddr; /*!< Debug packets to/from this host */ -static struct sockaddr_in rtcpdebugaddr; /*!< Debug RTCP packets to/from this host */ + static int rtpstart = 0; /*!< First port for RTP sessions (set in rtp.conf) */ + static int rtpend = 0; /*!< Last port for RTP sessions (set in rtp.conf) */ + static int rtpdebug = 0; /*!< Are we debugging? */ + static int rtcpdebug = 0; /*!< Are we debugging RTCP? */ + static int rtcpstats = 0; /*!< Are we debugging RTCP? */ + static int rtcpinterval = RTCP_DEFAULT_INTERVALMS; /*!< Time between rtcp reports in millisecs */ + static int stundebug = 0; /*!< Are we debugging stun? */ + static struct sockaddr_in rtpdebugaddr; /*!< Debug packets to/from this host */ + static struct sockaddr_in rtcpdebugaddr; /*!< Debug RTCP packets to/from this host */ #ifdef SO_NO_CHECK -static int nochecksums = 0; + static int nochecksums = 0; #endif /*! @@ -97,87 +89,87 @@ * */ /*! \brief The value of each payload format mapping: */ -struct rtpPayloadType { - int isAstFormat; /*!< whether the following code is an AST_FORMAT */ - int code; -}; + struct rtpPayloadType { + int isAstFormat; /*!< whether the following code is an AST_FORMAT */ + int code; + }; /*! \brief RTP session description */ -struct ast_rtp { - int s; - struct ast_frame f; - unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET]; - unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */ - unsigned int themssrc; /*!< Their SSRC */ - unsigned int rxssrc; - unsigned int lastts; - unsigned int lastrxts; - unsigned int lastividtimestamp; - unsigned int lastovidtimestamp; - unsigned int lasteventseqn; - int lastrxseqno; /*!< Last received sequence number */ - unsigned short seedrxseqno; /*!< What sequence number did they start with?*/ - unsigned int seedrxts; /*!< What RTP timestamp did they start with? */ - unsigned int rxcount; /*!< How many packets have we received? */ - unsigned int rxoctetcount; /*!< How many octets have we received? should be rxcount *160*/ - unsigned int txcount; /*!< How many packets have we sent? */ - unsigned int txoctetcount; /*!< How many octets have we sent? (txcount*160)*/ - unsigned int cycles; /*!< Shifted count of sequence number cycles */ - double rxjitter; /*!< Interarrival jitter at the moment */ - double rxtransit; /*!< Relative transit time for previous packet */ - int lasttxformat; - int lastrxformat; + struct ast_rtp { + int s; + struct ast_frame f; + unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET]; + unsigned int ssrc; /*!< Synchronization source, RFC 3550, page 10. */ + unsigned int themssrc; /*!< Their SSRC */ + unsigned int rxssrc; + unsigned int lastts; + unsigned int lastrxts; + unsigned int lastividtimestamp; + unsigned int lastovidtimestamp; + unsigned int lasteventseqn; + int lastrxseqno; /*!< Last received sequence number */ + unsigned short seedrxseqno; /*!< What sequence number did they start with? */ + unsigned int seedrxts; /*!< What RTP timestamp did they start with? */ + unsigned int rxcount; /*!< How many packets have we received? */ + unsigned int rxoctetcount; /*!< How many octets have we received? should be rxcount *160 */ + unsigned int txcount; /*!< How many packets have we sent? */ + unsigned int txoctetcount; /*!< How many octets have we sent? (txcount*160) */ + unsigned int cycles; /*!< Shifted count of sequence number cycles */ + double rxjitter; /*!< Interarrival jitter at the moment */ + double rxtransit; /*!< Relative transit time for previous packet */ + int lasttxformat; + int lastrxformat; - int rtptimeout; /*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */ - int rtpholdtimeout; /*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */ - int rtpkeepalive; /*!< Send RTP comfort noice packets for keepalive */ + int rtptimeout; /*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */ + int rtpholdtimeout; /*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */ + int rtpkeepalive; /*!< Send RTP comfort noice packets for keepalive */ - /* DTMF Reception Variables */ - char resp; - unsigned int lasteventendseqn; - int dtmfcount; - unsigned int dtmfduration; - /* DTMF Transmission Variables */ - unsigned int lastdigitts; - char send_digit; - int send_payload; - int send_duration; - int nat; - unsigned int flags; - struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ - struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ - struct timeval rxcore; - struct timeval txcore; - double drxcore; /*!< The double representation of the first received packet */ - struct timeval lastrx; /*!< timeval when we last received a packet */ - struct timeval dtmfmute; - struct ast_smoother *smoother; - int *ioid; - unsigned short seqno; /*!< Sequence number, RFC 3550, page 13. */ - unsigned short rxseqno; - struct sched_context *sched; - struct io_context *io; - void *data; - ast_rtp_callback callback; - ast_mutex_t bridge_lock; - struct rtpPayloadType current_RTP_PT[MAX_RTP_PT]; - int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */ - int rtp_lookup_code_cache_code; - int rtp_lookup_code_cache_result; - struct ast_rtcp *rtcp; - struct ast_codec_pref pref; - struct ast_rtp *bridged; /*!< Who we are Packet bridged to */ -}; + /* DTMF Reception Variables */ + char resp; + unsigned int lasteventendseqn; + int dtmfcount; + unsigned int dtmfduration; + /* DTMF Transmission Variables */ + unsigned int lastdigitts; + char send_digit; + int send_payload; + int send_duration; + int nat; + unsigned int flags; + struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ + struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ + struct timeval rxcore; + struct timeval txcore; + double drxcore; /*!< The double representation of the first received packet */ + struct timeval lastrx; /*!< timeval when we last received a packet */ + struct timeval dtmfmute; + struct ast_smoother *smoother; + int *ioid; + unsigned short seqno; /*!< Sequence number, RFC 3550, page 13. */ + unsigned short rxseqno; + struct sched_context *sched; + struct io_context *io; + void *data; + ast_rtp_callback callback; + ast_mutex_t bridge_lock; + struct rtpPayloadType current_RTP_PT[MAX_RTP_PT]; + int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */ + int rtp_lookup_code_cache_code; + int rtp_lookup_code_cache_result; + struct ast_rtcp *rtcp; + struct ast_codec_pref pref; + struct ast_rtp *bridged; /*!< Who we are Packet bridged to */ + }; /* Forward declarations */ -static int ast_rtcp_write(void *data); -static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw); -static int ast_rtcp_write_sr(void *data); -static int ast_rtcp_write_rr(void *data); -static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp); -static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp); -int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit); + static int ast_rtcp_write(void *data); + static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw); + static int ast_rtcp_write_sr(void *data); + static int ast_rtcp_write_rr(void *data); + static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp); + static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp); + int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit); #define FLAG_3389_WARNING (1 << 0) #define FLAG_NAT_ACTIVE (3 << 1) @@ -200,56 +192,58 @@ * RTCP packet is defined on page 9 of RFC 3550. * */ -struct ast_rtcp { - int s; /*!< Socket */ - struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ - struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ - unsigned int soc; /*!< What they told us */ - unsigned int spc; /*!< What they told us */ - unsigned int themrxlsr; /*!< The middle 32 bits of the NTP timestamp in the last received SR*/ - struct timeval rxlsr; /*!< Time when we got their last SR */ - struct timeval txlsr; /*!< Time when we sent or last SR*/ - unsigned int expected_prior; /*!< no. packets in previous interval */ - unsigned int received_prior; /*!< no. packets received in previous interval */ - int schedid; /*!< Schedid returned from ast_sched_add() to schedule RTCP-transmissions*/ - unsigned int rr_count; /*!< number of RRs we've sent, not including report blocks in SR's */ - unsigned int sr_count; /*!< number of SRs we've sent */ - unsigned int lastsrtxcount; /*!< Transmit packet count when last SR sent */ - double accumulated_transit; /*!< accumulated a-dlsr-lsr */ - double rtt; /*!< Last reported rtt */ - unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */ - unsigned int reported_lost; /*!< Reported lost packets in their RR */ - char quality[AST_MAX_USER_FIELD]; - double maxrxjitter; - double minrxjitter; - double maxrtt; - double minrtt; - int sendfur; -}; + struct ast_rtcp { + int s; /*!< Socket */ + struct sockaddr_in us; /*!< Socket representation of the local endpoint. */ + struct sockaddr_in them; /*!< Socket representation of the remote endpoint. */ + unsigned int soc; /*!< What they told us */ + unsigned int spc; /*!< What they told us */ + unsigned int themrxlsr; /*!< The middle 32 bits of the NTP timestamp in the last received SR */ + struct timeval rxlsr; /*!< Time when we got their last SR */ + struct timeval txlsr; /*!< Time when we sent or last SR */ + unsigned int expected_prior; /*!< no. packets in previous interval */ + unsigned int received_prior; /*!< no. packets received in previous interval */ + int schedid; /*!< Schedid returned from ast_sched_add() to schedule RTCP-transmissions */ + unsigned int rr_count; /*!< number of RRs we've sent, not including report blocks in SR's */ + unsigned int sr_count; /*!< number of SRs we've sent */ + unsigned int lastsrtxcount; /*!< Transmit packet count when last SR sent */ + double accumulated_transit; /*!< accumulated a-dlsr-lsr */ + double rtt; /*!< Last reported rtt */ + unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */ + unsigned int reported_lost; /*!< Reported lost packets in their RR */ + char quality[AST_MAX_USER_FIELD]; + double maxrxjitter; + double minrxjitter; + double maxrtt; + double minrtt; + int sendfur; + }; -typedef struct { unsigned int id[4]; } __attribute__((packed)) stun_trans_id; + typedef struct { + unsigned int id[4]; + } __attribute__ ((packed)) stun_trans_id; /* XXX Maybe stun belongs in another file if it ever has use outside of RTP */ -struct stun_header { - unsigned short msgtype; - unsigned short msglen; - stun_trans_id id; - unsigned char ies[0]; -} __attribute__((packed)); + struct stun_header { + unsigned short msgtype; + unsigned short msglen; + stun_trans_id id; + unsigned char ies[0]; + } __attribute__ ((packed)); -struct stun_attr { - unsigned short attr; - unsigned short len; - unsigned char value[0]; -} __attribute__((packed)); + struct stun_attr { + unsigned short attr; + unsigned short len; + unsigned char value[0]; + } __attribute__ ((packed)); -struct stun_addr { - unsigned char unused; - unsigned char family; - unsigned short port; - unsigned int addr; -} __attribute__((packed)); + struct stun_addr { + unsigned char unused; + unsigned char family; + unsigned short port; + unsigned int addr; + } __attribute__ ((packed)); #define STUN_IGNORE (0) #define STUN_ACCEPT (1) @@ -273,9 +267,9 @@ #define STUN_UNKNOWN_ATTRIBUTES 0x000a #define STUN_REFLECTED_FROM 0x000b -static const char *stun_msg2str(int msg) + static const char *stun_msg2str(int msg) { - switch(msg) { + switch (msg) { case STUN_BINDREQ: return "Binding Request"; case STUN_BINDRESP: @@ -294,7 +288,7 @@ static const char *stun_attr2str(int msg) { - switch(msg) { + switch (msg) { case STUN_MAPPED_ADDRESS: return "Mapped Address"; case STUN_RESPONSE_ADDRESS: @@ -330,8 +324,9 @@ { if (stundebug) ast_verbose("Found STUN Attribute %s (%04x), length %d\n", - stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len)); - switch(ntohs(attr->attr)) { + stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), + ntohs(attr->len)); + switch (ntohs(attr->attr)) { case STUN_USERNAME: state->username = (const char *) (attr->value); break; @@ -340,38 +335,41 @@ break; default: if (stundebug) - ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n", - stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len)); + ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n", + stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), + ntohs(attr->len)); } return 0; } -static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left) +static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, + int *len, int *left) { int size = sizeof(**attr) + strlen(s); if (*left > size) { (*attr)->attr = htons(attrval); (*attr)->len = htons(strlen(s)); memcpy((*attr)->value, s, strlen(s)); - (*attr) = (struct stun_attr *)((*attr)->value + strlen(s)); + (*attr) = (struct stun_attr *) ((*attr)->value + strlen(s)); *len += size; *left -= size; } } -static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left) +static void append_attr_address(struct stun_attr **attr, int attrval, + struct sockaddr_in *sin, int *len, int *left) { int size = sizeof(**attr) + 8; struct stun_addr *addr; if (*left > size) { (*attr)->attr = htons(attrval); (*attr)->len = htons(8); - addr = (struct stun_addr *)((*attr)->value); + addr = (struct stun_addr *) ((*attr)->value); addr->unused = 0; addr->family = 0x01; addr->port = sin->sin_port; addr->addr = sin->sin_addr.s_addr; - (*attr) = (struct stun_attr *)((*attr)->value + 8); + (*attr) = (struct stun_attr *) ((*attr)->value + 8); *len += size; *left -= size; } @@ -380,13 +378,13 @@ static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp) { return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0, - (struct sockaddr *)dst, sizeof(*dst)); + (struct sockaddr *) dst, sizeof(*dst)); } static void stun_req_id(struct stun_header *req) { int x; - for (x=0;x<4;x++) + for (x = 0; x < 4; x++) req->id.id[x] = ast_random(); } @@ -395,20 +393,21 @@ return sizeof(struct ast_rtp); } -void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username) +void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, + const char *username) { struct stun_header *req; unsigned char reqdata[1024]; int reqlen, reqleft; struct stun_attr *attr; - req = (struct stun_header *)reqdata; + req = (struct stun_header *) reqdata; stun_req_id(req); reqlen = 0; reqleft = sizeof(reqdata) - sizeof(struct stun_header); req->msgtype = 0; req->msglen = 0; - attr = (struct stun_attr *)req->ies; + attr = (struct stun_attr *) req->ies; if (username) append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft); req->msglen = htons(reqlen); @@ -416,44 +415,53 @@ stun_send(rtp->s, suggestion, req); } -static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len) +static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, + size_t len) { - struct stun_header *resp, *hdr = (struct stun_header *)data; + struct stun_header *resp, *hdr = (struct stun_header *) data; struct stun_attr *attr; struct stun_state st; - int ret = STUN_IGNORE; + int ret = STUN_IGNORE; unsigned char respdata[1024]; int resplen, respleft; - + if (len < sizeof(struct stun_header)) { if (option_debug) - ast_log(LOG_DEBUG, "Runt STUN packet (only %zd, wanting at least %zd)\n", len, sizeof(struct stun_header)); + ast_log(LOG_DEBUG, "Runt STUN packet (only %zd, wanting at least %zd)\n", len, + sizeof(struct stun_header)); return -1; } if (stundebug) - ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), ntohs(hdr->msglen)); + ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", + stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), + ntohs(hdr->msglen)); if (ntohs(hdr->msglen) > len - sizeof(struct stun_header)) { if (option_debug) - ast_log(LOG_DEBUG, "Scrambled STUN packet length (got %d, expecting %zd)\n", ntohs(hdr->msglen), len - sizeof(struct stun_header)); + ast_log(LOG_DEBUG, "Scrambled STUN packet length (got %d, expecting %zd)\n", + ntohs(hdr->msglen), len - sizeof(struct stun_header)); } else len = ntohs(hdr->msglen); data += sizeof(struct stun_header); memset(&st, 0, sizeof(st)); - while(len) { + while (len) { if (len < sizeof(struct stun_attr)) { if (option_debug) - ast_log(LOG_DEBUG, "Runt Attribute (got %zd, expecting %zd)\n", len, sizeof(struct stun_attr)); + ast_log(LOG_DEBUG, "Runt Attribute (got %zd, expecting %zd)\n", len, + sizeof(struct stun_attr)); break; } - attr = (struct stun_attr *)data; + attr = (struct stun_attr *) data; if (ntohs(attr->len) > len) { if (option_debug) - ast_log(LOG_DEBUG, "Inconsistent Attribute (length %d exceeds remaining msg len %zd)\n", ntohs(attr->len), len); + ast_log(LOG_DEBUG, + "Inconsistent Attribute (length %d exceeds remaining msg len %zd)\n", + ntohs(attr->len), len); break; } if (stun_process_attr(&st, attr)) { if (option_debug) - ast_log(LOG_DEBUG, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr)); + ast_log(LOG_DEBUG, "Failed to handle attribute %s (%04x)\n", + stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr)); break; } /* Clear attribute in case previous entry was a string */ @@ -463,21 +471,22 @@ } /* Null terminate any string */ *data = '\0'; - resp = (struct stun_header *)respdata; + resp = (struct stun_header *) respdata; resplen = 0; respleft = sizeof(respdata) - sizeof(struct stun_header); resp->id = hdr->id; resp->msgtype = 0; resp->msglen = 0; - attr = (struct stun_attr *)resp->ies; + attr = (struct stun_attr *) resp->ies; if (!len) { - switch(ntohs(hdr->msgtype)) { + switch (ntohs(hdr->msgtype)) { case STUN_BINDREQ: if (stundebug) - ast_verbose("STUN Bind Request, username: %s\n", - st.username ? st.username : ""); + ast_verbose("STUN Bind Request, username: %s\n", + st.username ? st.username : ""); if (st.username) - append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft); + append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, + &respleft); append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft); resp->msglen = htons(resplen); resp->msgtype = htons(STUN_BINDRESP); @@ -486,7 +495,8 @@ break; default: if (stundebug) - ast_verbose("Dunno what to do with STUN message %04x (%s)\n", ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype))); + ast_verbose("Dunno what to do with STUN message %04x (%s)\n", + ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype))); } } return ret; @@ -498,7 +508,7 @@ static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw) { unsigned int sec, usec, frac; - sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */ + sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */ usec = tv.tv_usec; frac = (usec << 12) + (usec << 8) - ((usec * 3650) >> 6); *msw = sec; @@ -521,7 +531,7 @@ { unsigned int interval; /*! \todo XXX Do a more reasonable calculation on this one - * Look in RFC 3550 Section A.7 for an example*/ + * Look in RFC 3550 Section A.7 for an example*/ interval = rtcpinterval; return interval; } @@ -606,15 +616,17 @@ static struct ast_frame *send_dtmf(struct ast_rtp *rtp, enum ast_frame_type type) { if (((ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && type == AST_FRAME_DTMF_END) || - (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) { + (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) { if (option_debug) - ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(rtp->them.sin_addr)); + ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", + ast_inet_ntoa(rtp->them.sin_addr)); rtp->resp = 0; rtp->dtmfduration = 0; return &ast_null_frame; } if (option_debug) - ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr)); + ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, + ast_inet_ntoa(rtp->them.sin_addr)); if (rtp->resp == 'X') { rtp->f.frametype = AST_FRAME_CONTROL; rtp->f.subclass = AST_CONTROL_FLASH; @@ -627,7 +639,7 @@ rtp->f.mallocd = 0; rtp->f.src = "RTP"; return &rtp->f; - + } static inline int rtp_debug_test_addr(struct sockaddr_in *addr) @@ -636,9 +648,9 @@ return 0; if (rtpdebugaddr.sin_addr.s_addr) { if (((ntohs(rtpdebugaddr.sin_port) != 0) - && (rtpdebugaddr.sin_port != addr->sin_port)) + && (rtpdebugaddr.sin_port != addr->sin_port)) || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) - return 0; + return 0; } return 1; } @@ -649,15 +661,16 @@ return 0; if (rtcpdebugaddr.sin_addr.s_addr) { if (((ntohs(rtcpdebugaddr.sin_port) != 0) - && (rtcpdebugaddr.sin_port != addr->sin_port)) + && (rtcpdebugaddr.sin_port != addr->sin_port)) || (rtcpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) - return 0; + return 0; } return 1; } -static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len) +static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, + int len) { unsigned int event; char resp = 0; @@ -670,43 +683,45 @@ if (len < 4) return f; - /* The format of Cisco RTP DTMF packet looks like next: - +0 - sequence number of DTMF RTP packet (begins from 1, - wrapped to 0) - +1 - set of flags - +1 (bit 0) - flaps by different DTMF digits delimited by audio - or repeated digit without audio??? - +2 (+4,+6,...) - power level? (rises from 0 to 32 at begin of tone - then falls to 0 at its end) - +3 (+5,+7,...) - detected DTMF digit (0..9,*,#,A-D,...) - Repeated DTMF information (bytes 4/5, 6/7) is history shifted right - by each new packet and thus provides some redudancy. - - Sample of Cisco RTP DTMF packet is (all data in hex): - 19 07 00 02 12 02 20 02 - showing end of DTMF digit '2'. + /* The format of Cisco RTP DTMF packet looks like next: + +0 - sequence number of DTMF RTP packet (begins from 1, + wrapped to 0) + +1 - set of flags + +1 (bit 0) - flaps by different DTMF digits delimited by audio + or repeated digit without audio??? + +2 (+4,+6,...) - power level? (rises from 0 to 32 at begin of tone + then falls to 0 at its end) + +3 (+5,+7,...) - detected DTMF digit (0..9,*,#,A-D,...) + Repeated DTMF information (bytes 4/5, 6/7) is history shifted right + by each new packet and thus provides some redudancy. - The packets - 27 07 00 02 0A 02 20 02 - 28 06 20 02 00 02 0A 02 - shows begin of new digit '2' with very short pause (20 ms) after - previous digit '2'. Bit +1.0 flips at begin of new digit. - - Cisco RTP DTMF packets comes as replacement of audio RTP packets - so its uses the same sequencing and timestamping rules as replaced - audio packets. Repeat interval of DTMF packets is 20 ms and not rely - on audio framing parameters. Marker bit isn't used within stream of - DTMFs nor audio stream coming immediately after DTMF stream. Timestamps - are not sequential at borders between DTMF and audio streams, - */ + Sample of Cisco RTP DTMF packet is (all data in hex): + 19 07 00 02 12 02 20 02 + showing end of DTMF digit '2'. + The packets + 27 07 00 02 0A 02 20 02 + 28 06 20 02 00 02 0A 02 + shows begin of new digit '2' with very short pause (20 ms) after + previous digit '2'. Bit +1.0 flips at begin of new digit. + + Cisco RTP DTMF packets comes as replacement of audio RTP packets + so its uses the same sequencing and timestamping rules as replaced + audio packets. Repeat interval of DTMF packets is 20 ms and not rely + on audio framing parameters. Marker bit isn't used within stream of + DTMFs nor audio stream coming immediately after DTMF stream. Timestamps + are not sequential at borders between DTMF and audio streams, + */ + seq = data[0]; flags = data[1]; power = data[2]; event = data[3] & 0x1f; if (option_debug > 2 || rtpdebug) - ast_log(LOG_DEBUG, "Cisco DTMF Digit: %02x (len=%d, seq=%d, flags=%02x, power=%d, history count=%d)\n", event, len, seq, flags, power, (len - 4) / 2); + ast_log(LOG_DEBUG, + "Cisco DTMF Digit: %02x (len=%d, seq=%d, flags=%02x, power=%d, history count=%d)\n", + event, len, seq, flags, power, (len - 4) / 2); if (event < 10) { resp = '0' + event; } else if (event < 11) { @@ -746,7 +761,8 @@ * \param seqno * \returns */ -static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno) +static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, + int len, unsigned int seqno) { unsigned int event; unsigned int event_end; @@ -755,12 +771,12 @@ struct ast_frame *f = NULL; /* Figure out event, event end, and duration */ - event = ntohl(*((unsigned int *)(data))); + event = ntohl(*((unsigned int *) (data))); event >>= 24; - event_end = ntohl(*((unsigned int *)(data))); + event_end = ntohl(*((unsigned int *) (data))); event_end <<= 8; event_end >>= 24; - duration = ntohl(*((unsigned int *)(data))); + duration = ntohl(*((unsigned int *) (data))); duration &= 0xFFFF; /* Print out debug if turned on */ @@ -777,7 +793,7 @@ } else if (event < 16) { resp = 'A' + (event - 12); } else if (event < 17) { /* Event 16: Hook flash */ - resp = 'X'; + resp = 'X'; } if ((!(rtp->resp) && (!(event_end & 0x80))) || (rtp->resp && rtp->resp != resp)) { @@ -789,7 +805,8 @@ f->samples = duration; rtp->resp = 0; rtp->lasteventendseqn = seqno; - } else if (ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && event_end & 0x80 && rtp->lasteventendseqn != seqno) { + } else if (ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && event_end & 0x80 && + rtp->lasteventendseqn != seqno) { rtp->resp = resp; f = send_dtmf(rtp, AST_FRAME_DTMF_END); f->samples = duration; @@ -809,18 +826,21 @@ * This is incomplete at the moment. * */ -static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len) +static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, + int len) { struct ast_frame *f = NULL; /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't totally help us out becuase we don't have an engine to keep it going and we are not guaranteed to have it every 20ms or anything */ if (rtpdebug) - ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", rtp->lastrxformat, len); + ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", + rtp->lastrxformat, len); if (!(ast_test_flag(rtp, FLAG_3389_WARNING))) { - ast_log(LOG_NOTICE, "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s\n", - ast_inet_ntoa(rtp->them.sin_addr)); + ast_log(LOG_NOTICE, + "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s\n", + ast_inet_ntoa(rtp->them.sin_addr)); ast_set_flag(rtp, FLAG_3389_WARNING); } @@ -878,16 +898,18 @@ unsigned int lsw; unsigned int comp; struct ast_frame *f = &ast_null_frame; - + if (!rtp || !rtp->rtcp) return &ast_null_frame; len = sizeof(sin); - - res = recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET, - 0, (struct sockaddr *)&sin, &len); - rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET); - + + res = + recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, + sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET, 0, + (struct sockaddr *) &sin, &len); + rtcpheader = (unsigned int *) (rtcpdata + AST_FRIENDLY_OFFSET); + if (res < 0) { if (errno != EAGAIN) ast_log(LOG_WARNING, "RTCP Read error: %s\n", strerror(errno)); @@ -897,14 +919,17 @@ } packetwords = res / 4; - + if (rtp->nat) { /* Send to whoever sent to us */ if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || - (rtp->rtcp->them.sin_port != sin.sin_port)) { + (rtp->rtcp->them.sin_port != sin.sin_port)) { memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them)); if (option_debug || rtpdebug) - ast_log(LOG_DEBUG, "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); + ast_log(LOG_DEBUG, + "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", + ast_inet_ntoa(rtp->rtcp->them.sin_addr), + ntohs(rtp->rtcp->them.sin_port)); } } @@ -919,32 +944,42 @@ pt = (length & 0xff0000) >> 16; rc = (length & 0x1f000000) >> 24; length &= 0xffff; - + if ((i + length) > packetwords) { ast_log(LOG_WARNING, "RTCP Read too short\n"); return &ast_null_frame; } - + if (rtcp_debug_test_addr(&sin)) { - ast_verbose("\n\nGot RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); - ast_verbose("PT: %d(%s)\n", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown"); - ast_verbose("Reception reports: %d\n", rc); - ast_verbose("SSRC of sender: %u\n", rtcpheader[i + 1]); + ast_verbose("\n\nGot RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), + ntohs(sin.sin_port)); + ast_verbose("PT: %d(%s)\n", pt, + (pt == 200) ? "Sender Report" : (pt == + 201) ? "Receiver Report" : (pt == + 192) + ? "H.261 FUR" : "Unknown"); + ast_verbose("Reception reports: %d\n", rc); + ast_verbose("SSRC of sender: %u\n", rtcpheader[i + 1]); } - - i += 2; /* Advance past header and ssrc */ - + + i += 2; /* Advance past header and ssrc */ + switch (pt) { case RTCP_PT_SR: - gettimeofday(&rtp->rtcp->rxlsr,NULL); /* To be able to populate the dlsr */ - rtp->rtcp->spc = ntohl(rtcpheader[i+3]); + gettimeofday(&rtp->rtcp->rxlsr, NULL); /* To be able to populate the dlsr */ + rtp->rtcp->spc = ntohl(rtcpheader[i + 3]); rtp->rtcp->soc = ntohl(rtcpheader[i + 4]); - rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff) >> 16); /* Going to LSR in RR*/ - + rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff) >> 16); /* Going to LSR in RR */ + if (rtcp_debug_test_addr(&sin)) { - ast_verbose("NTP timestamp: %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[i]), (unsigned long) ntohl(rtcpheader[i + 1]) * 4096); - ast_verbose("RTP timestamp: %lu\n", (unsigned long) ntohl(rtcpheader[i + 2])); - ast_verbose("SPC: %lu\tSOC: %lu\n", (unsigned long) ntohl(rtcpheader[i + 3]), (unsigned long) ntohl(rtcpheader[i + 4])); + ast_verbose("NTP timestamp: %lu.%010lu\n", + (unsigned long) ntohl(rtcpheader[i]), + (unsigned long) ntohl(rtcpheader[i + 1]) * 4096); + ast_verbose("RTP timestamp: %lu\n", + (unsigned long) ntohl(rtcpheader[i + 2])); + ast_verbose("SPC: %lu\tSOC: %lu\n", + (unsigned long) ntohl(rtcpheader[i + 3]), + (unsigned long) ntohl(rtcpheader[i + 4])); } i += 5; if (rc < 1) @@ -956,29 +991,37 @@ gettimeofday(&now, NULL); timeval2ntp(now, &msw, &lsw); /* Use the one we sent them in our SR instead, rtcp->txlsr could have been rewritten if the dlsr is large */ - if (ntohl(rtcpheader[i + 4])) { /* We must have the LSR */ + if (ntohl(rtcpheader[i + 4])) { /* We must have the LSR */ comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16); - a = (double)((comp & 0xffff0000) >> 16) + (double)((double)(comp & 0xffff)/1000000.); - lsr = (double)((ntohl(rtcpheader[i + 4]) & 0xffff0000) >> 16) + (double)((double)(ntohl(rtcpheader[i + 4]) & 0xffff) / 1000000.); - dlsr = (double)(ntohl(rtcpheader[i + 5])/65536.); + a = (double) ((comp & 0xffff0000) >> 16) + + (double) ((double) (comp & 0xffff) / 1000000.); + lsr = + (double) ((ntohl(rtcpheader[i + 4]) & 0xffff0000) >> 16) + + (double) ((double) (ntohl(rtcpheader[i + 4]) & 0xffff) / 1000000.); + dlsr = (double) (ntohl(rtcpheader[i + 5]) / 65536.); rtt = a - dlsr - lsr; rtp->rtcp->accumulated_transit += rtt; rtp->rtcp->rtt = rtt; - if (rtp->rtcp->maxrttrtcp->maxrtt < rtt) rtp->rtcp->maxrtt = rtt; - if (rtp->rtcp->minrtt>rtt) - rtp->rtcp->minrtt = rtt; + if (rtp->rtcp->minrtt > rtt) + rtp->rtcp->minrtt = rtt; } rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]); rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff; if (rtcp_debug_test_addr(&sin)) { - ast_verbose("Fraction lost: %ld\n", (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24)); + ast_verbose("Fraction lost: %ld\n", + (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24)); ast_verbose("Packets lost so far: %d\n", rtp->rtcp->reported_lost); - ast_verbose("Highest sequence number: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff)); - ast_verbose("Sequence number cycles: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff) >> 16); + ast_verbose("Highest sequence number: %ld\n", + (long) (ntohl(rtcpheader[i + 2]) & 0xffff)); + ast_verbose("Sequence number cycles: %ld\n", + (long) (ntohl(rtcpheader[i + 2]) & 0xffff) >> 16); ast_verbose("Interarrival jitter: %u\n", rtp->rtcp->reported_jitter); - ast_verbose("Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096); - ast_verbose("DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0); + ast_verbose("Last SR(our NTP): %lu.%010lu\n", + (unsigned long) ntohl(rtcpheader[i + 4]) >> 16, + ((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096); + ast_verbose("DLSR: %4.4f (sec)\n", ntohl(rtcpheader[i + 5]) / 65536.0); if (rtt) ast_verbose("RTT: %f(sec)\n", rtt); } @@ -996,24 +1039,31 @@ break; case RTCP_PT_SDES: if (rtcp_debug_test_addr(&sin)) - ast_verbose("Received an SDES from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); + ast_verbose("Received an SDES from %s:%d\n", + ast_inet_ntoa(rtp->rtcp->them.sin_addr), + ntohs(rtp->rtcp->them.sin_port)); break; case RTCP_PT_BYE: if (rtcp_debug_test_addr(&sin)) - ast_verbose("Received a BYE from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); + ast_verbose("Received a BYE from %s:%d\n", + ast_inet_ntoa(rtp->rtcp->them.sin_addr), + ntohs(rtp->rtcp->them.sin_port)); break; default: if (option_debug) - ast_log(LOG_DEBUG, "Unknown RTCP packet (pt=%d) received from %s:%d\n", pt, ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); + ast_log(LOG_DEBUG, "Unknown RTCP packet (pt=%d) received from %s:%d\n", + pt, ast_inet_ntoa(rtp->rtcp->them.sin_addr), + ntohs(rtp->rtcp->them.sin_port)); break; } position += (length + 1); } - + return f; } -static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark) +static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, + int mark) { struct timeval now; double transit; @@ -1021,12 +1071,13 @@ double d; double dtv; double prog; - + if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) { gettimeofday(&rtp->rxcore, NULL); - rtp->drxcore = (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000; + rtp->drxcore = + (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000; /* map timestamp to a real time */ - rtp->seedrxts = timestamp; /* Their RTP timestamp started with this */ + rtp->seedrxts = timestamp; /* Their RTP timestamp started with this */ rtp->rxcore.tv_sec -= timestamp / 8000; rtp->rxcore.tv_usec -= (timestamp % 8000) * 125; /* Round to 0.1ms for nice, pretty timestamps */ @@ -1038,7 +1089,7 @@ } } - gettimeofday(&now,NULL); + gettimeofday(&now, NULL); /* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */ tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000; tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125; @@ -1046,15 +1097,15 @@ tv->tv_usec -= 1000000; tv->tv_sec += 1; } - prog = (double)((timestamp-rtp->seedrxts)/8000.); - dtv = (double)rtp->drxcore + (double)(prog); - current_time = (double)now.tv_sec + (double)now.tv_usec/1000000; + prog = (double) ((timestamp - rtp->seedrxts) / 8000.); + dtv = (double) rtp->drxcore + (double) (prog); + current_time = (double) now.tv_sec + (double) now.tv_usec / 1000000; transit = current_time - dtv; d = transit - rtp->rxtransit; rtp->rxtransit = transit; - if (d<0) - d=-d; - rtp->rxjitter += (1./16.) * (d - rtp->rxjitter); + if (d < 0) + d = -d; + rtp->rxjitter += (1. / 16.) * (d - rtp->rxjitter); if (rtp->rtcp && rtp->rxjitter > rtp->rtcp->maxrxjitter) rtp->rtcp->maxrxjitter = rtp->rxjitter; if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter) @@ -1062,12 +1113,13 @@ } /*! \brief Perform a Packet2Packet RTP write */ -static int bridge_p2p_rtp_write(struct ast_rtp *rtp, struct ast_rtp *bridged, unsigned int *rtpheader, int len, int hdrlen) +static int bridge_p2p_rtp_write(struct ast_rtp *rtp, struct ast_rtp *bridged, + unsigned int *rtpheader, int len, int hdrlen) { int res = 0, payload = 0, bridged_payload = 0, version, padding, mark, ext; struct rtpPayloadType rtpPT; unsigned int seqno; - + /* Get fields from packet */ seqno = ntohl(rtpheader[0]); version = (seqno & 0xC0000000) >> 30; @@ -1081,7 +1133,8 @@ rtpPT = ast_rtp_lookup_pt(rtp, payload); /* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */ - if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && rtpPT.code == AST_RTP_DTMF) + if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && + rtpPT.code == AST_RTP_DTMF) return -1; /* Otherwise adjust bridged payload to match */ @@ -1094,22 +1147,36 @@ } /* Reconstruct part of the packet */ - rtpheader[0] = htonl((version << 30) | (mark << 23) | (bridged_payload << 16) | (seqno)); + rtpheader[0] = + htonl((version << 30) | (mark << 23) | (bridged_payload << 16) | (seqno)); /* Send the packet back out */ - res = sendto(bridged->s, (void *)rtpheader, len, 0, (struct sockaddr *)&bridged->them, sizeof(bridged->them)); + res = + sendto(bridged->s, (void *) rtpheader, len, 0, (struct sockaddr *) &bridged->them, + sizeof(bridged->them)); if (res < 0) { - if (!bridged->nat || (bridged->nat && (ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { + if (!bridged->nat || + (bridged->nat && + (ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { if (option_debug) - ast_log(LOG_DEBUG, "RTP Transmission error of packet to %s:%d: %s\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), strerror(errno)); - } else if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) { + ast_log(LOG_DEBUG, "RTP Transmission error of packet to %s:%d: %s\n", + ast_inet_ntoa(bridged->them.sin_addr), + ntohs(bridged->them.sin_port), strerror(errno)); + } else + if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || + rtpdebug) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) { if (option_debug || rtpdebug) - ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port)); + ast_log(LOG_DEBUG, + "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", + ast_inet_ntoa(bridged->them.sin_addr), + ntohs(bridged->them.sin_port)); ast_set_flag(bridged, FLAG_NAT_INACTIVE_NOWARN); } return -1; } else if (rtp_debug_test_addr(&bridged->them)) - ast_verbose("Sent RTP P2P packet to %s:%d (type %-2.2d, len %-6.6u)\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), bridged_payload, len - hdrlen); + ast_verbose("Sent RTP P2P packet to %s:%d (type %-2.2d, len %-6.6u)\n", + ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), + bridged_payload, len - hdrlen); return -1; } @@ -1132,18 +1199,20 @@ unsigned int *rtpheader; struct rtpPayloadType rtpPT; struct ast_rtp *bridged = NULL; - + /* If time is up, kill it */ if (rtp->send_digit) ast_rtp_senddigit_continuation(rtp); len = sizeof(sin); - + /* Cache where the header will go */ - res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, - 0, (struct sockaddr *)&sin, &len); + res = + recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, + sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0, (struct sockaddr *) &sin, + &len); - rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET); + rtpheader = (unsigned int *) (rtp->rawdata + AST_FRIENDLY_OFFSET); if (res < 0) { if (errno != EAGAIN) ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno)); @@ -1151,7 +1220,7 @@ CRASH; return &ast_null_frame; } - + if (res < hdrlen) { ast_log(LOG_WARNING, "RTP Read too short\n"); return &ast_null_frame; @@ -1163,14 +1232,13 @@ /* Check RTP version */ version = (seqno & 0xC0000000) >> 30; if (!version) { - if ((stun_handle_packet(rtp->s, &sin, rtp->rawdata + AST_FRIENDLY_OFFSET, res) == STUN_ACCEPT) && - (!rtp->them.sin_port && !rtp->them.sin_addr.s_addr)) { + if ((stun_handle_packet(rtp->s, &sin, rtp->rawdata + AST_FRIENDLY_OFFSET, res) == + STUN_ACCEPT) && (!rtp->them.sin_port && !rtp->them.sin_addr.s_addr)) { memcpy(&rtp->them, &sin, sizeof(rtp->them)); } return &ast_null_frame; } - -#if 0 /* Allow to receive RTP stream with closed transmission path */ +#if 0 /* Allow to receive RTP stream with closed transmission path */ /* If we don't have the other side's address, then ignore this */ if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) return &ast_null_frame; @@ -1179,21 +1247,24 @@ /* Send to whoever send to us if NAT is turned on */ if (rtp->nat) { if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || - (rtp->them.sin_port != sin.sin_port)) { + (rtp->them.sin_port != sin.sin_port)) { rtp->them = sin; if (rtp->rtcp) { memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them)); - rtp->rtcp->them.sin_port = htons(ntohs(rtp->them.sin_port)+1); + rtp->rtcp->them.sin_port = htons(ntohs(rtp->them.sin_port) + 1); } rtp->rxseqno = 0; ast_set_flag(rtp, FLAG_NAT_ACTIVE); if (option_debug || rtpdebug) - ast_log(LOG_DEBUG, "RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); + ast_log(LOG_DEBUG, + "RTP NAT: Got audio from other end. Now sending to address %s:%d\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); } } /* If we are bridged to another RTP stream, send direct */ - if ((bridged = ast_rtp_get_bridged(rtp)) && !bridge_p2p_rtp_write(rtp, bridged, rtpheader, res, hdrlen)) + if ((bridged = ast_rtp_get_bridged(rtp)) && + !bridge_p2p_rtp_write(rtp, bridged, rtpheader, res, hdrlen)) return &ast_null_frame; if (version != 2) @@ -1206,7 +1277,7 @@ seqno &= 0xffff; timestamp = ntohl(rtpheader[1]); ssrc = ntohl(rtpheader[2]); - + if (!mark && rtp->rxssrc && rtp->rxssrc != ssrc) { if (option_debug || rtpdebug) ast_log(LOG_DEBUG, "Forcing Marker bit, because SSRC has changed\n"); @@ -1214,12 +1285,12 @@ } rtp->rxssrc = ssrc; - + if (padding) { /* Remove padding bytes */ res -= rtp->rawdata[AST_FRIENDLY_OFFSET + res - 1]; } - + if (ext) { /* RTP Extension present */ hdrlen += 4; @@ -1228,7 +1299,8 @@ int profile; profile = (ntohl(rtpheader[3]) & 0xffff0000) >> 16; if (profile == 0x505a) - ast_log(LOG_DEBUG, "Found Zfone extension in RTP stream - zrtp - not supported.\n"); + ast_log(LOG_DEBUG, + "Found Zfone extension in RTP stream - zrtp - not supported.\n"); else ast_log(LOG_DEBUG, "Found unknown RTP Extensions %x\n", profile); } @@ -1239,11 +1311,11 @@ return &ast_null_frame; } - rtp->rxcount++; /* Only count reasonably valid packets, this'll make the rtcp stats more accurate */ + rtp->rxcount++; /* Only count reasonably valid packets, this'll make the rtcp stats more accurate */ - tseqno = rtp->lastrxseqno +1; + tseqno = rtp->lastrxseqno + 1; - if (rtp->rxcount==1) { + if (rtp->rxcount == 1) { /* This is the first RTP packet successfully received from source */ rtp->seedrxseqno = seqno; } @@ -1251,22 +1323,25 @@ /* Do not schedule RR if RTCP isn't run */ if (rtp->rtcp && rtp->rtcp->them.sin_addr.s_addr && rtp->rtcp->schedid < 1) { /* Schedule transmission of Receiver Report */ - rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp); + rtp->rtcp->schedid = + ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp); } - if (tseqno > RTP_SEQ_MOD) { /* if tseqno is greater than RTP_SEQ_MOD it would indicate that the sender cycled */ + if (tseqno > RTP_SEQ_MOD) { /* if tseqno is greater than RTP_SEQ_MOD it would indicate that the sender cycled */ rtp->cycles += RTP_SEQ_MOD; ast_verbose("SEQNO cycled: %u\t%d\n", rtp->cycles, seqno); } rtp->lastrxseqno = seqno; - - if (rtp->themssrc==0) - rtp->themssrc = ntohl(rtpheader[2]); /* Record their SSRC to put in future RR */ - + + if (rtp->themssrc == 0) + rtp->themssrc = ntohl(rtpheader[2]); /* Record their SSRC to put in future RR */ + if (rtp_debug_test_addr(&sin)) - ast_verbose("Got RTP packet from %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", - ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); + ast_verbose + ("Got RTP packet from %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", + ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, + timestamp, res - hdrlen); rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); if (!rtpPT.isAstFormat) { @@ -1281,32 +1356,42 @@ unsigned int event_end; unsigned int duration; data = rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen; - event = ntohl(*((unsigned int *)(data))); + event = ntohl(*((unsigned int *) (data))); event >>= 24; - event_end = ntohl(*((unsigned int *)(data))); + event_end = ntohl(*((unsigned int *) (data))); event_end <<= 8; event_end >>= 24; - duration = ntohl(*((unsigned int *)(data))); + duration = ntohl(*((unsigned int *) (data))); duration &= 0xFFFF; - ast_verbose("Got RTP RFC2833 from %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d) \n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration); + ast_verbose + ("Got RTP RFC2833 from %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d) \n", + ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, + timestamp, res - hdrlen, (mark ? 1 : 0), event, + ((event_end & 0x80) ? 1 : 0), duration); } - f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno); + f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, + res - hdrlen, seqno); } else if (rtpPT.code == AST_RTP_CISCO_DTMF) { /* It's really special -- process it the Cisco way */ - if (rtp->lasteventseqn <= seqno || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { - f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); + if (rtp->lasteventseqn <= seqno || + (rtp->lasteventseqn >= 65530 && seqno <= 6)) { + f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, + res - hdrlen); rtp->lasteventseqn = seqno; } } else if (rtpPT.code == AST_RTP_CN) { /* Comfort Noise */ - f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); + f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, + res - hdrlen); } else { - ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n", payloadtype, ast_inet_ntoa(rtp->them.sin_addr)); + ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n", payloadtype, + ast_inet_ntoa(rtp->them.sin_addr)); } return f ? f : &ast_null_frame; } rtp->lastrxformat = rtp->f.subclass = rtpPT.code; - rtp->f.frametype = (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) ? AST_FRAME_VOICE : AST_FRAME_VIDEO; + rtp->f.frametype = + (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) ? AST_FRAME_VOICE : AST_FRAME_VIDEO; if (!rtp->lastrxts) rtp->lastrxts = timestamp; @@ -1322,7 +1407,7 @@ rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET; if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) { rtp->f.samples = ast_codec_get_samples(&rtp->f); - if (rtp->f.subclass == AST_FORMAT_SLINEAR) + if (rtp->f.subclass == AST_FORMAT_SLINEAR) ast_frame_byteswap_be(&rtp->f); calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark); /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */ @@ -1340,7 +1425,7 @@ rtp->f.delivery.tv_usec = 0; if (mark) rtp->f.subclass |= 0x1; - + } rtp->f.src = "RTP"; return &rtp->f; @@ -1350,33 +1435,33 @@ of our codecs, or RTP-specific data type. */ static struct { struct rtpPayloadType payloadType; - char* type; - char* subtype; + char *type; + char *subtype; } mimeTypes[] = { - {{1, AST_FORMAT_G723_1}, "audio", "G723"}, - {{1, AST_FORMAT_GSM}, "audio", "GSM"}, - {{1, AST_FORMAT_ULAW}, "audio", "PCMU"}, - {{1, AST_FORMAT_ALAW}, "audio", "PCMA"}, - {{1, AST_FORMAT_G726}, "audio", "G726-32"}, - {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"}, - {{1, AST_FORMAT_SLINEAR}, "audio", "L16"}, - {{1, AST_FORMAT_LPC10}, "audio", "LPC"}, - {{1, AST_FORMAT_G729A}, "audio", "G729"}, - {{1, AST_FORMAT_SPEEX}, "audio", "speex"}, - {{1, AST_FORMAT_ILBC}, "audio", "iLBC"}, - {{1, AST_FORMAT_G722}, "audio", "G722"}, - {{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"}, - {{0, AST_RTP_DTMF}, "audio", "telephone-event"}, - {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"}, - {{0, AST_RTP_CN}, "audio", "CN"}, - {{1, AST_FORMAT_JPEG}, "video", "JPEG"}, - {{1, AST_FORMAT_PNG}, "video", "PNG"}, - {{1, AST_FORMAT_H261}, "video", "H261"}, - {{1, AST_FORMAT_H263}, "video", "H263"}, - {{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"}, - {{1, AST_FORMAT_H264}, "video", "H264"}, - {{1, AST_FORMAT_T140}, "text", "T140"}, -}; + { { + 1, AST_FORMAT_G723_1}, "audio", "G723"}, { { + 1, AST_FORMAT_GSM}, "audio", "GSM"}, { { + 1, AST_FORMAT_ULAW}, "audio", "PCMU"}, { { + 1, AST_FORMAT_ALAW}, "audio", "PCMA"}, { { + 1, AST_FORMAT_G726}, "audio", "G726-32"}, { { + 1, AST_FORMAT_ADPCM}, "audio", "DVI4"}, { { + 1, AST_FORMAT_SLINEAR}, "audio", "L16"}, { { + 1, AST_FORMAT_LPC10}, "audio", "LPC"}, { { + 1, AST_FORMAT_G729A}, "audio", "G729"}, { { + 1, AST_FORMAT_SPEEX}, "audio", "speex"}, { { + 1, AST_FORMAT_ILBC}, "audio", "iLBC"}, { { + 1, AST_FORMAT_G722}, "audio", "G722"}, { { + 1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"}, { { + 0, AST_RTP_DTMF}, "audio", "telephone-event"}, { { + 0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"}, { { + 0, AST_RTP_CN}, "audio", "CN"}, { { + 1, AST_FORMAT_JPEG}, "video", "JPEG"}, { { + 1, AST_FORMAT_PNG}, "video", "PNG"}, { { + 1, AST_FORMAT_H261}, "video", "H261"}, { { + 1, AST_FORMAT_H263}, "video", "H263"}, { { + 1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"}, { { + 1, AST_FORMAT_H264}, "video", "H264"}, { { +1, AST_FORMAT_T140}, "text", "T140"},}; /* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s: also, our own choices for dynamic payload types. This is our master @@ -1384,20 +1469,20 @@ static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = { [0] = {1, AST_FORMAT_ULAW}, #ifdef USE_DEPRECATED_G726 - [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */ + [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */ #endif [3] = {1, AST_FORMAT_GSM}, [4] = {1, AST_FORMAT_G723_1}, - [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */ - [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */ + [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */ + [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */ [7] = {1, AST_FORMAT_LPC10}, [8] = {1, AST_FORMAT_ALAW}, [9] = {1, AST_FORMAT_G722}, - [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */ - [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */ + [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */ + [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */ [13] = {0, AST_RTP_CN}, - [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */ - [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */ + [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */ + [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */ [18] = {1, AST_FORMAT_G729A}, [19] = {0, AST_RTP_CN}, /* Also used for CN */ [26] = {1, AST_FORMAT_JPEG}, @@ -1411,10 +1496,10 @@ [110] = {1, AST_FORMAT_SPEEX}, [111] = {1, AST_FORMAT_G726}, [112] = {1, AST_FORMAT_G726_AAL2}, - [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */ + [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */ }; -void ast_rtp_pt_clear(struct ast_rtp* rtp) +void ast_rtp_pt_clear(struct ast_rtp *rtp) { int i; @@ -1435,7 +1520,7 @@ ast_mutex_unlock(&rtp->bridge_lock); } -void ast_rtp_pt_default(struct ast_rtp* rtp) +void ast_rtp_pt_default(struct ast_rtp *rtp) { int i; @@ -1461,11 +1546,9 @@ ast_mutex_lock(&dest->bridge_lock); ast_mutex_lock(&src->bridge_lock); - for (i=0; i < MAX_RTP_PT; ++i) { - dest->current_RTP_PT[i].isAstFormat = - src->current_RTP_PT[i].isAstFormat; - dest->current_RTP_PT[i].code = - src->current_RTP_PT[i].code; + for (i = 0; i < MAX_RTP_PT; ++i) { + dest->current_RTP_PT[i].isAstFormat = src->current_RTP_PT[i].isAstFormat; + dest->current_RTP_PT[i].code = src->current_RTP_PT[i].code; } dest->rtp_lookup_code_cache_isAstFormat = 0; dest->rtp_lookup_code_cache_code = 0; @@ -1493,17 +1576,19 @@ int ast_rtp_early_bridge(struct ast_channel *c0, struct ast_channel *c1) { // dest = c0, src = c1 - struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */ - struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */ + struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */ + struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */ struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL; - enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED; - enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED; + enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = + AST_RTP_GET_FAILED; + enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = + AST_RTP_GET_FAILED; int srccodec, nat_active = 0; /* Lock channels */ ast_channel_lock(c0); if (c1) { - while(ast_channel_trylock(c1)) { + while (ast_channel_trylock(c1)) { ast_channel_unlock(c0); usleep(1); ast_channel_lock(c0); @@ -1524,7 +1609,8 @@ } if (!srcpr) { if (option_debug) - ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", c1 ? c1->name : ""); + ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", + c1 ? c1->name : ""); ast_channel_unlock(c0); if (c1) ast_channel_unlock(c1); @@ -1533,10 +1619,12 @@ /* Get audio and video interface (if native bridge is possible) */ audio_dest_res = destpr->get_rtp_info(c0, &destp); - video_dest_res = destpr->get_vrtp_info ? destpr->get_vrtp_info(c0, &vdestp) : AST_RTP_GET_FAILED; + video_dest_res = + destpr->get_vrtp_info ? destpr->get_vrtp_info(c0, &vdestp) : AST_RTP_GET_FAILED; if (srcpr) { audio_src_res = srcpr->get_rtp_info(c1, &srcp); - video_src_res = srcpr->get_vrtp_info ? srcpr->get_vrtp_info(c1, &vsrcp) : AST_RTP_GET_FAILED; + video_src_res = + srcpr->get_vrtp_info ? srcpr->get_vrtp_info(c1, &vsrcp) : AST_RTP_GET_FAILED; } /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */ @@ -1558,27 +1646,31 @@ nat_active = 1; /* Bridge media early */ if (destpr->set_rtp_peer(c0, srcp, vsrcp, srccodec, nat_active)) - ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", c0->name, c1 ? c1->name : ""); + ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", + c0->name, c1 ? c1->name : ""); ast_channel_unlock(c0); if (c1) ast_channel_unlock(c1); if (option_debug) - ast_log(LOG_DEBUG, "Setting early bridge SDP of '%s' with that of '%s'\n", c0->name, c1 ? c1->name : ""); + ast_log(LOG_DEBUG, "Setting early bridge SDP of '%s' with that of '%s'\n", + c0->name, c1 ? c1->name : ""); return 0; } int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media) { - struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */ - struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */ + struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */ + struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */ struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL; - enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED; - enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED; + enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = + AST_RTP_GET_FAILED; + enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = + AST_RTP_GET_FAILED; int srccodec; /* Lock channels */ ast_channel_lock(dest); - while(ast_channel_trylock(src)) { + while (ast_channel_trylock(src)) { ast_channel_unlock(dest); usleep(1); ast_channel_lock(dest); @@ -1587,14 +1679,16 @@ /* Find channel driver interfaces */ if (!(destpr = get_proto(dest))) { if (option_debug) - ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name); + ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", + dest->name); ast_channel_unlock(dest); ast_channel_unlock(src); return 0; } if (!(srcpr = get_proto(src))) { if (option_debug) - ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src->name); + ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", + src->name); ast_channel_unlock(dest); ast_channel_unlock(src); return 0; @@ -1602,9 +1696,11 @@ /* Get audio and video interface (if native bridge is possible) */ audio_dest_res = destpr->get_rtp_info(dest, &destp); - video_dest_res = destpr->get_vrtp_info ? destpr->get_vrtp_info(dest, &vdestp) : AST_RTP_GET_FAILED; + video_dest_res = + destpr->get_vrtp_info ? destpr->get_vrtp_info(dest, &vdestp) : AST_RTP_GET_FAILED; audio_src_res = srcpr->get_rtp_info(src, &srcp); - video_src_res = srcpr->get_vrtp_info ? srcpr->get_vrtp_info(src, &vsrcp) : AST_RTP_GET_FAILED; + video_src_res = + srcpr->get_vrtp_info ? srcpr->get_vrtp_info(src, &vsrcp) : AST_RTP_GET_FAILED; /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */ if (audio_dest_res != AST_RTP_TRY_NATIVE || audio_src_res != AST_RTP_TRY_NATIVE) { @@ -1622,13 +1718,17 @@ srccodec = 0; if (media) { /* Bridge early */ - if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, ast_test_flag(srcp, FLAG_NAT_ACTIVE))) - ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", dest->name, src->name); + if (destpr-> + set_rtp_peer(dest, srcp, vsrcp, srccodec, + ast_test_flag(srcp, FLAG_NAT_ACTIVE))) + ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", + dest->name, src->name); } ast_channel_unlock(dest); ast_channel_unlock(src); if (option_debug) - ast_log(LOG_DEBUG, "Seeded SDP of '%s' with that of '%s'\n", dest->name, src->name); + ast_log(LOG_DEBUG, "Seeded SDP of '%s' with that of '%s'\n", dest->name, + src->name); return 1; } @@ -1636,37 +1736,37 @@ * By default, use the well-known value for this type (although it may * still be set to a different value by a subsequent "a=rtpmap:" line) */ -void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) +void ast_rtp_set_m_type(struct ast_rtp *rtp, int pt) { - if (pt < 0 || pt > MAX_RTP_PT || static_RTP_PT[pt].code == 0) - return; /* bogus payload type */ + if (pt < 0 || pt > MAX_RTP_PT || static_RTP_PT[pt].code == 0) + return; /* bogus payload type */ ast_mutex_lock(&rtp->bridge_lock); rtp->current_RTP_PT[pt] = static_RTP_PT[pt]; ast_mutex_unlock(&rtp->bridge_lock); -} +} /*! \brief Make a note of a RTP payload type (with MIME type) that was seen in * an SDP "a=rtpmap:" line. */ void ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt, - char *mimeType, char *mimeSubtype, - enum ast_rtp_options options) + char *mimeType, char *mimeSubtype, + enum ast_rtp_options options) { unsigned int i; - if (pt < 0 || pt > MAX_RTP_PT) - return; /* bogus payload type */ - + if (pt < 0 || pt > MAX_RTP_PT) + return; /* bogus payload type */ + ast_mutex_lock(&rtp->bridge_lock); - for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) { + for (i = 0; i < sizeof(mimeTypes) / sizeof(mimeTypes[0]); ++i) { if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 && - strcasecmp(mimeType, mimeTypes[i].type) == 0) { + strcasecmp(mimeType, mimeTypes[i].type) == 0) { rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType; if ((mimeTypes[i].payloadType.code == AST_FORMAT_G726) && - mimeTypes[i].payloadType.isAstFormat && - (options & AST_RTP_OPT_G726_NONSTANDARD)) + mimeTypes[i].payloadType.isAstFormat && + (options & AST_RTP_OPT_G726_NONSTANDARD)) rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2; break; } @@ -1675,17 +1775,16 @@ ast_mutex_unlock(&rtp->bridge_lock); return; -} +} /*! \brief Return the union of all of the codecs that were set by rtp_set...() calls * They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */ -void ast_rtp_get_current_formats(struct ast_rtp* rtp, - int* astFormats, int* nonAstFormats) +void ast_rtp_get_current_formats(struct ast_rtp *rtp, int *astFormats, int *nonAstFormats) { int pt; - + ast_mutex_lock(&rtp->bridge_lock); - + *astFormats = *nonAstFormats = 0; for (pt = 0; pt < MAX_RTP_PT; ++pt) { if (rtp->current_RTP_PT[pt].isAstFormat) { @@ -1694,20 +1793,20 @@ *nonAstFormats |= rtp->current_RTP_PT[pt].code; } } - + ast_mutex_unlock(&rtp->bridge_lock); - + return; } -struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) +struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp *rtp, int pt) { struct rtpPayloadType result; result.isAstFormat = result.code = 0; - if (pt < 0 || pt > MAX_RTP_PT) - return result; /* bogus payload type */ + if (pt < 0 || pt > MAX_RTP_PT) + return result; /* bogus payload type */ /* Start with negotiated codecs */ ast_mutex_lock(&rtp->bridge_lock); @@ -1715,14 +1814,14 @@ ast_mutex_unlock(&rtp->bridge_lock); /* If it doesn't exist, check our static RTP type list, just in case */ - if (!result.code) + if (!result.code) result = static_RTP_PT[pt]; return result; } /*! \brief Looks up an RTP code out of our *static* outbound list */ -int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code) +int ast_rtp_lookup_code(struct ast_rtp *rtp, const int isAstFormat, const int code) { int pt = 0; @@ -1738,7 +1837,8 @@ /* Check the dynamic list first */ for (pt = 0; pt < MAX_RTP_PT; ++pt) { - if (rtp->current_RTP_PT[pt].code == code && rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) { + if (rtp->current_RTP_PT[pt].code == code && + rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) { rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat; rtp->rtp_lookup_code_cache_code = code; rtp->rtp_lookup_code_cache_result = pt; @@ -1749,9 +1849,10 @@ /* Then the static list */ for (pt = 0; pt < MAX_RTP_PT; ++pt) { - if (static_RTP_PT[pt].code == code && static_RTP_PT[pt].isAstFormat == isAstFormat) { + if (static_RTP_PT[pt].code == code && + static_RTP_PT[pt].isAstFormat == isAstFormat) { rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat; - rtp->rtp_lookup_code_cache_code = code; + rtp->rtp_lookup_code_cache_code = code; rtp->rtp_lookup_code_cache_result = pt; ast_mutex_unlock(&rtp->bridge_lock); return pt; @@ -1764,15 +1865,15 @@ } const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code, - enum ast_rtp_options options) + enum ast_rtp_options options) { unsigned int i; - for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) { - if ((mimeTypes[i].payloadType.code == code) && (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) { - if (isAstFormat && - (code == AST_FORMAT_G726_AAL2) && - (options & AST_RTP_OPT_G726_NONSTANDARD)) + for (i = 0; i < sizeof(mimeTypes) / sizeof(mimeTypes[0]); ++i) { + if ((mimeTypes[i].payloadType.code == code) && + (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) { + if (isAstFormat && (code == AST_FORMAT_G726_AAL2) && + (options & AST_RTP_OPT_G726_NONSTANDARD)) return "G726-32"; else return mimeTypes[i].subtype; @@ -1783,7 +1884,7 @@ } char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability, - const int isAstFormat, enum ast_rtp_options options) + const int isAstFormat, enum ast_rtp_options options) { int format; unsigned len; @@ -1812,10 +1913,10 @@ } if (start == end) - snprintf(start, size, "nothing)"); + snprintf(start, size, "nothing)"); else if (size > 1) - *(end -1) = ')'; - + *(end - 1) = ')'; + return buf; } @@ -1877,13 +1978,15 @@ return; } -struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr) +struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, + struct io_context *io, int rtcpenable, + int callbackmode, struct in_addr addr) { struct ast_rtp *rtp; int x; int first; int startplace; - + if (!(rtp = ast_calloc(1, sizeof(*rtp)))) return NULL; @@ -1899,9 +2002,9 @@ rtp->sched = sched; rtp->rtcp = ast_rtcp_new(); } - + /* Select a random port number in the range of possible RTP */ - x = (ast_random() % (rtpend-rtpstart)) + rtpstart; + x = (ast_random() % (rtpend - rtpstart)) + rtpstart; x = x & ~1; /* Save it for future references. */ startplace = x; @@ -1917,8 +2020,10 @@ rtp->rtcp->us.sin_addr = addr; } /* Try to bind it/them. */ - if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) && - (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us)))) + if (!(first = bind(rtp->s, (struct sockaddr *) &rtp->us, sizeof(rtp->us))) && + (!rtp->rtcp || + !bind(rtp->rtcp->s, (struct sockaddr *) &rtp->rtcp->us, + sizeof(rtp->rtcp->us)))) break; if (!first) { /* Primary bind succeeded! Gotta recreate it */ @@ -1945,7 +2050,8 @@ /* Check if we reached the place were we started. */ if (x == startplace) { /* If so, there's no ports available. */ - ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n"); + ast_log(LOG_ERROR, + "No RTP ports remaining. Can't setup media stream for this call.\n"); close(rtp->s); if (rtp->rtcp) { close(rtp->rtcp->s); @@ -1965,7 +2071,8 @@ return rtp; } -struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode) +struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, + int rtcpenable, int callbackmode) { struct in_addr ia; @@ -1977,7 +2084,7 @@ { int res; - if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) + if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); return res; } @@ -2035,7 +2142,7 @@ memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->rtcp->them.sin_addr)); memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->rtcp->them.sin_port)); } - + ast_clear_flag(rtp, FLAG_P2P_SENT_MARK); } @@ -2062,18 +2169,23 @@ char *ast_rtp_get_quality(struct ast_rtp *rtp) { /* - *ssrc our ssrc - *themssrc their ssrc - *lp lost packets - *rxjitter our calculated jitter(rx) - *rxcount no. received packets - *txjitter reported jitter of the other end - *txcount transmitted packets - *rlp remote lost packets - */ - - snprintf(rtp->rtcp->quality, sizeof(rtp->rtcp->quality), "ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f", rtp->ssrc, rtp->themssrc, rtp->rtcp->expected_prior - rtp->rtcp->received_prior, rtp->rxjitter, rtp->rxcount, (double)rtp->rtcp->reported_jitter/65536., rtp->txcount, rtp->rtcp->reported_lost, rtp->rtcp->rtt); - + *ssrc our ssrc + *themssrc their ssrc + *lp lost packets + *rxjitter our calculated jitter(rx) + *rxcount no. received packets + *txjitter reported jitter of the other end + *txcount transmitted packets + *rlp remote lost packets + */ + + snprintf(rtp->rtcp->quality, sizeof(rtp->rtcp->quality), + "ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f", + rtp->ssrc, rtp->themssrc, + rtp->rtcp->expected_prior - rtp->rtcp->received_prior, rtp->rxjitter, + rtp->rxcount, (double) rtp->rtcp->reported_jitter / 65536., rtp->txcount, + rtp->rtcp->reported_lost, rtp->rtcp->rtt); + return rtp->rtcp->quality; } @@ -2085,7 +2197,8 @@ ast_verbose("* Our Receiver:\n"); ast_verbose(" SSRC: %u\n", rtp->themssrc); ast_verbose(" Received packets: %u\n", rtp->rxcount); - ast_verbose(" Lost packets: %u\n", rtp->rtcp->expected_prior - rtp->rtcp->received_prior); + ast_verbose(" Lost packets: %u\n", + rtp->rtcp->expected_prior - rtp->rtcp->received_prior); ast_verbose(" Jitter: %.4f\n", rtp->rxjitter); ast_verbose(" Transit: %.4f\n", rtp->rxtransit); ast_verbose(" RR-count: %u\n", rtp->rtcp->rr_count); @@ -2109,7 +2222,7 @@ ast_sched_del(rtp->sched, rtp->rtcp->schedid); close(rtp->rtcp->s); free(rtp->rtcp); - rtp->rtcp=NULL; + rtp->rtcp = NULL; } ast_mutex_destroy(&rtp->bridge_lock); @@ -2158,7 +2271,7 @@ return 0; } - /* If we have no peer, return immediately */ + /* If we have no peer, return immediately */ if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) return 0; @@ -2166,24 +2279,27 @@ rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); rtp->send_duration = 160; - + /* Get a pointer to the header */ - rtpheader = (unsigned int *)data; + rtpheader = (unsigned int *) data; rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno)); rtpheader[1] = htonl(rtp->lastdigitts); - rtpheader[2] = htonl(rtp->ssrc); + rtpheader[2] = htonl(rtp->ssrc); for (i = 0; i < 2; i++) { rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration)); - res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); - if (res < 0) + res = + sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, + (struct sockaddr *) &rtp->them, sizeof(rtp->them)); + if (res < 0) ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", - ast_inet_ntoa(rtp->them.sin_addr), - ntohs(rtp->them.sin_port), strerror(errno)); + ast_inet_ntoa(rtp->them.sin_addr), + ntohs(rtp->them.sin_port), strerror(errno)); if (rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent RTP DTMF packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", - ast_inet_ntoa(rtp->them.sin_addr), - ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); + ast_verbose + ("Sent RTP DTMF packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, + rtp->seqno, rtp->lastdigitts, res - hdrlen); /* Increment sequence number */ rtp->seqno++; /* Increment duration */ @@ -2210,23 +2326,27 @@ return 0; /* Setup packet to send */ - rtpheader = (unsigned int *)data; - rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); - rtpheader[1] = htonl(rtp->lastdigitts); - rtpheader[2] = htonl(rtp->ssrc); - rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration)); + rtpheader = (unsigned int *) data; + rtpheader[0] = + htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); + rtpheader[1] = htonl(rtp->lastdigitts); + rtpheader[2] = htonl(rtp->ssrc); + rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration)); rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno)); - + /* Transmit */ - res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); + res = + sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, + sizeof(rtp->them)); if (res < 0) ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", - ast_inet_ntoa(rtp->them.sin_addr), - ntohs(rtp->them.sin_port), strerror(errno)); + ast_inet_ntoa(rtp->them.sin_addr), + ntohs(rtp->them.sin_port), strerror(errno)); if (rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent RTP DTMF packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", - ast_inet_ntoa(rtp->them.sin_addr), - ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); + ast_verbose + ("Sent RTP DTMF packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), + rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); /* Increment sequence number */ rtp->seqno++; @@ -2242,11 +2362,11 @@ unsigned int *rtpheader; int hdrlen = 12, res = 0, i = 0; char data[256]; - + /* If no address, then bail out */ if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) return 0; - + if ((digit <= '9') && (digit >= '0')) digit -= '0'; else if (digit == '*') @@ -2264,8 +2384,9 @@ rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); - rtpheader = (unsigned int *)data; - rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); + rtpheader = (unsigned int *) data; + rtpheader[0] = + htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); rtpheader[1] = htonl(rtp->lastdigitts); rtpheader[2] = htonl(rtp->ssrc); rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration)); @@ -2274,15 +2395,18 @@ rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno)); /* Send 3 termination packets */ for (i = 0; i < 3; i++) { - res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); + res = + sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, + (struct sockaddr *) &rtp->them, sizeof(rtp->them)); if (res < 0) ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", - ast_inet_ntoa(rtp->them.sin_addr), - ntohs(rtp->them.sin_port), strerror(errno)); + ast_inet_ntoa(rtp->them.sin_addr), + ntohs(rtp->them.sin_port), strerror(errno)); if (rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent RTP DTMF packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", - ast_inet_ntoa(rtp->them.sin_addr), - ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); + ast_verbose + ("Sent RTP DTMF packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), + rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); } rtp->send_digit = 0; /* Increment lastdigitts */ @@ -2300,7 +2424,7 @@ rtp->rtcp->sendfur = 1; res = ast_rtcp_write(data); - + return res; } @@ -2325,10 +2449,10 @@ char bdata[512]; /* Commented condition is always not NULL if rtp->rtcp is not NULL */ - if (!rtp || !rtp->rtcp/* || (&rtp->rtcp->them.sin_addr == 0)*/) + if (!rtp || !rtp->rtcp /* || (&rtp->rtcp->them.sin_addr == 0) */ ) return 0; - - if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */ + + if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */ ast_verbose("RTCP SR transmission error, rtcp halted\n"); if (rtp->rtcp->schedid > 0) ast_sched_del(rtp->sched, rtp->rtcp->schedid); @@ -2337,19 +2461,19 @@ } gettimeofday(&now, NULL); - timeval2ntp(now, &now_msw, &now_lsw); /* fill thses ones in from utils.c*/ - rtcpheader = (unsigned int *)bdata; - rtcpheader[1] = htonl(rtp->ssrc); /* Our SSRC */ - rtcpheader[2] = htonl(now_msw); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970*/ - rtcpheader[3] = htonl(now_lsw); /* now, LSW */ - rtcpheader[4] = htonl(rtp->lastts); /* FIXME shouldn't be that, it should be now */ - rtcpheader[5] = htonl(rtp->txcount); /* No. packets sent */ - rtcpheader[6] = htonl(rtp->txoctetcount); /* No. bytes sent */ + timeval2ntp(now, &now_msw, &now_lsw); /* fill thses ones in from utils.c */ + rtcpheader = (unsigned int *) bdata; + rtcpheader[1] = htonl(rtp->ssrc); /* Our SSRC */ + rtcpheader[2] = htonl(now_msw); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970 */ + rtcpheader[3] = htonl(now_lsw); /* now, LSW */ + rtcpheader[4] = htonl(rtp->lastts); /* FIXME shouldn't be that, it should be now */ + rtcpheader[5] = htonl(rtp->txcount); /* No. packets sent */ + rtcpheader[6] = htonl(rtp->txoctetcount); /* No. bytes sent */ len += 28; - + extended = rtp->cycles + rtp->lastrxseqno; expected = extended - rtp->seedrxseqno + 1; - if (rtp->rxcount > expected) + if (rtp->rxcount > expected) expected += rtp->rxcount - expected; lost = expected - rtp->rxcount; expected_interval = expected - rtp->rtcp->expected_prior; @@ -2365,46 +2489,53 @@ rtcpheader[7] = htonl(rtp->themssrc); rtcpheader[8] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff)); rtcpheader[9] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff))); - rtcpheader[10] = htonl((unsigned int)rtp->rxjitter); + rtcpheader[10] = htonl((unsigned int) rtp->rxjitter); rtcpheader[11] = htonl(rtp->rtcp->themrxlsr); - rtcpheader[12] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000); + rtcpheader[12] = + htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000); len += 24; - - rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SR << 16) | ((len/4)-1)); + rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SR << 16) | ((len / 4) - 1)); + if (rtp->rtcp->sendfur) { rtcpheader[13] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1); - rtcpheader[14] = htonl(rtp->ssrc); /* Our SSRC */ + rtcpheader[14] = htonl(rtp->ssrc); /* Our SSRC */ len += 8; rtp->rtcp->sendfur = 0; } - - /* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */ + + /* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */ /* it can change mid call, and SDES can't) */ - rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2); - rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */ - rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */ + rtcpheader[len / 4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2); + rtcpheader[(len / 4) + 1] = htonl(rtp->ssrc); /* Our SSRC */ + rtcpheader[(len / 4) + 2] = htonl(0x01 << 24); /* Empty for the moment */ len += 12; - - res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them)); + + res = + sendto(rtp->rtcp->s, (unsigned int *) rtcpheader, len, 0, + (struct sockaddr *) &rtp->rtcp->them, sizeof(rtp->rtcp->them)); if (res < 0) { - ast_log(LOG_ERROR, "RTCP SR transmission error to %s:%d, rtcp halted %s\n",ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), strerror(errno)); + ast_log(LOG_ERROR, "RTCP SR transmission error to %s:%d, rtcp halted %s\n", + ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), + strerror(errno)); if (rtp->rtcp->schedid > 0) ast_sched_del(rtp->sched, rtp->rtcp->schedid); rtp->rtcp->schedid = -1; return 0; } - + /* FIXME Don't need to get a new one */ gettimeofday(&rtp->rtcp->txlsr, NULL); rtp->rtcp->sr_count++; - rtp->rtcp->lastsrtxcount = rtp->txcount; - + rtp->rtcp->lastsrtxcount = rtp->txcount; + if (rtcp_debug_test_addr(&rtp->rtcp->them)) { - ast_verbose("* Sent RTCP SR to %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); + ast_verbose("* Sent RTCP SR to %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), + ntohs(rtp->rtcp->them.sin_port)); ast_verbose(" Our SSRC: %u\n", rtp->ssrc); - ast_verbose(" Sent(NTP): %u.%010u\n", (unsigned int)now.tv_sec, (unsigned int)now.tv_usec*4096); + ast_verbose(" Sent(NTP): %u.%010u\n", (unsigned int) now.tv_sec, + (unsigned int) now.tv_usec * 4096); ast_verbose(" Sent(RTP): %u\n", rtp->lastts); ast_verbose(" Sent packets: %u\n", rtp->txcount); ast_verbose(" Sent octets: %u\n", rtp->txoctetcount); @@ -2413,7 +2544,8 @@ ast_verbose(" Cumulative loss: %u\n", lost); ast_verbose(" IA jitter: %.4f\n", rtp->rxjitter); ast_verbose(" Their last SR: %u\n", rtp->rtcp->themrxlsr); - ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(ntohl(rtcpheader[12])/65536.0)); + ast_verbose(" DLSR: %4.4f (sec)\n\n", + (double) (ntohl(rtcpheader[12]) / 65536.0)); } return res; } @@ -2438,9 +2570,10 @@ if (!rtp || !rtp->rtcp || (&rtp->rtcp->them.sin_addr == 0)) return 0; - + if (!rtp->rtcp->them.sin_addr.s_addr) { - ast_log(LOG_ERROR, "RTCP RR transmission error to, rtcp halted %s\n",strerror(errno)); + ast_log(LOG_ERROR, "RTCP RR transmission error to, rtcp halted %s\n", + strerror(errno)); if (rtp->rtcp->schedid > 0) ast_sched_del(rtp->sched, rtp->rtcp->schedid); rtp->rtcp->schedid = -1; @@ -2461,34 +2594,38 @@ fraction = (lost_interval << 8) / expected_interval; gettimeofday(&now, NULL); timersub(&now, &rtp->rtcp->rxlsr, &dlsr); - rtcpheader = (unsigned int *)bdata; - rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_RR << 16) | ((len/4)-1)); + rtcpheader = (unsigned int *) bdata; + rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_RR << 16) | ((len / 4) - 1)); rtcpheader[1] = htonl(rtp->ssrc); rtcpheader[2] = htonl(rtp->themssrc); rtcpheader[3] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff)); rtcpheader[4] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff))); - rtcpheader[5] = htonl((unsigned int)rtp->rxjitter); + rtcpheader[5] = htonl((unsigned int) rtp->rxjitter); rtcpheader[6] = htonl(rtp->rtcp->themrxlsr); - rtcpheader[7] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000); + rtcpheader[7] = + htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000); if (rtp->rtcp->sendfur) { - rtcpheader[8] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1); /* Header from page 36 in RFC 3550 */ - rtcpheader[9] = htonl(rtp->ssrc); /* Our SSRC */ + rtcpheader[8] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1); /* Header from page 36 in RFC 3550 */ + rtcpheader[9] = htonl(rtp->ssrc); /* Our SSRC */ len += 8; rtp->rtcp->sendfur = 0; } /*! \note Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos - it can change mid call, and SDES can't) */ - rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2); - rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */ - rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */ + it can change mid call, and SDES can't) */ + rtcpheader[len / 4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2); + rtcpheader[(len / 4) + 1] = htonl(rtp->ssrc); /* Our SSRC */ + rtcpheader[(len / 4) + 2] = htonl(0x01 << 24); /* Empty for the moment */ len += 12; - - res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them)); + res = + sendto(rtp->rtcp->s, (unsigned int *) rtcpheader, len, 0, + (struct sockaddr *) &rtp->rtcp->them, sizeof(rtp->rtcp->them)); + if (res < 0) { - ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n",strerror(errno)); + ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n", + strerror(errno)); /* Remove the scheduler */ if (rtp->rtcp->schedid > 0) ast_sched_del(rtp->sched, rtp->rtcp->schedid); @@ -2500,16 +2637,15 @@ if (rtcp_debug_test_addr(&rtp->rtcp->them)) { ast_verbose("\n* Sending RTCP RR to %s:%d\n" - " Our SSRC: %u\nTheir SSRC: %u\niFraction lost: %d\nCumulative loss: %u\n" - " IA jitter: %.4f\n" - " Their last SR: %u\n" - " DLSR: %4.4f (sec)\n\n", - ast_inet_ntoa(rtp->rtcp->them.sin_addr), - ntohs(rtp->rtcp->them.sin_port), - rtp->ssrc, rtp->themssrc, fraction, lost, - rtp->rxjitter, - rtp->rtcp->themrxlsr, - (double)(ntohl(rtcpheader[7])/65536.0)); + " Our SSRC: %u\nTheir SSRC: %u\niFraction lost: %d\nCumulative loss: %u\n" + " IA jitter: %.4f\n" + " Their last SR: %u\n" + " DLSR: %4.4f (sec)\n\n", + ast_inet_ntoa(rtp->rtcp->them.sin_addr), + ntohs(rtp->rtcp->them.sin_port), + rtp->ssrc, rtp->themssrc, fraction, lost, + rtp->rxjitter, + rtp->rtcp->themrxlsr, (double) (ntohl(rtcpheader[7]) / 65536.0)); } return res; @@ -2522,12 +2658,12 @@ { struct ast_rtp *rtp = data; int res; - + if (rtp->txcount > rtp->rtcp->lastsrtxcount) res = ast_rtcp_write_sr(data); else res = ast_rtcp_write_rr(data); - + return res; } @@ -2542,26 +2678,32 @@ level = 127 - (level & 0x7f); payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN); - /* If we have no peer, return immediately */ + /* If we have no peer, return immediately */ if (!rtp->them.sin_addr.s_addr) return 0; rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); /* Get a pointer to the header */ - rtpheader = (unsigned int *)data; + rtpheader = (unsigned int *) data; rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++)); rtpheader[1] = htonl(rtp->lastts); - rtpheader[2] = htonl(rtp->ssrc); + rtpheader[2] = htonl(rtp->ssrc); data[12] = level; if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { - res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); - if (res <0) - ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); + res = + sendto(rtp->s, (void *) rtpheader, hdrlen + 1, 0, + (struct sockaddr *) &rtp->them, sizeof(rtp->them)); + if (res < 0) + ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), + strerror(errno)); if (rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %u, len %d)\n" - , ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen); - + ast_verbose + ("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %u, len %d)\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, + rtp->seqno, rtp->lastts, res - hdrlen); + } return 0; } @@ -2590,7 +2732,8 @@ rtp->lastts = pred; else { if (option_debug > 2) - ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms); + ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", + abs(rtp->lastts - pred), ms); mark = 1; } } @@ -2606,14 +2749,17 @@ rtp->lastovidtimestamp += f->samples; } else { if (option_debug > 2) - ast_log(LOG_DEBUG, "Difference is %d, ms is %d (%d), pred/ts/samples %d/%d/%d\n", abs(rtp->lastts - pred), ms, ms * 90, rtp->lastts, pred, f->samples); + ast_log(LOG_DEBUG, + "Difference is %d, ms is %d (%d), pred/ts/samples %d/%d/%d\n", + abs(rtp->lastts - pred), ms, ms * 90, rtp->lastts, pred, + f->samples); rtp->lastovidtimestamp = rtp->lastts; } } } /* If the timestamp for non-digit packets has moved beyond the timestamp for digits, update the digit timestamp. - */ + */ if (rtp->lastts > rtp->lastdigitts) rtp->lastdigitts = rtp->lastts; @@ -2621,35 +2767,50 @@ rtp->lastts = f->ts * 8; /* Get a pointer to the header */ - rtpheader = (unsigned char *)(f->data - hdrlen); + rtpheader = (unsigned char *) (f->data - hdrlen); - put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23))); + put_unaligned_uint32(rtpheader, + htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23))); put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts)); - put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); + put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { - res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); - if (res <0) { - if (!rtp->nat || (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { + res = + sendto(rtp->s, (void *) rtpheader, f->datalen + hdrlen, 0, + (struct sockaddr *) &rtp->them, sizeof(rtp->them)); + if (res < 0) { + if (!rtp->nat || + (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { if (option_debug) - ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n", rtp->seqno, ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); - } else if (((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(rtp, FLAG_NAT_INACTIVE_NOWARN)) { + ast_log(LOG_DEBUG, + "RTP Transmission error of packet %d to %s:%d: %s\n", + rtp->seqno, ast_inet_ntoa(rtp->them.sin_addr), + ntohs(rtp->them.sin_port), strerror(errno)); + } else + if (((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || + rtpdebug) && !ast_test_flag(rtp, FLAG_NAT_INACTIVE_NOWARN)) { /* Only give this error message once if we are not RTP debugging */ if (option_debug || rtpdebug) - ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); + ast_log(LOG_DEBUG, + "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); ast_set_flag(rtp, FLAG_NAT_INACTIVE_NOWARN); } } else { rtp->txcount++; - rtp->txoctetcount +=(res - hdrlen); - - if (rtp->rtcp && rtp->rtcp->schedid < 1) - rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp); + rtp->txoctetcount += (res - hdrlen); + + if (rtp->rtcp && rtp->rtcp->schedid < 1) + rtp->rtcp->schedid = + ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, + rtp); } - + if (rtp_debug_test_addr(&rtp->them)) - ast_verbose("Sent RTP packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", - ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen); + ast_verbose + ("Sent RTP packet to %s:%d (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, + rtp->seqno, rtp->lastts, res - hdrlen); } rtp->seqno++; @@ -2660,7 +2821,7 @@ int ast_rtp_codec_setpref(struct ast_rtp *rtp, struct ast_codec_pref *prefs) { int x; - for (x = 0; x < 32; x++) { /* Ugly way */ + for (x = 0; x < 32; x++) { /* Ugly way */ rtp->pref.order[x] = prefs->order[x]; rtp->pref.framing[x] = prefs->framing[x]; } @@ -2678,7 +2839,7 @@ int ast_rtp_codec_getformat(int pt) { if (pt < 0 || pt > MAX_RTP_PT) - return 0; /* bogus payload type */ + return 0; /* bogus payload type */ if (static_RTP_PT[pt].isAstFormat) return static_RTP_PT[pt].code; @@ -2692,16 +2853,16 @@ int codec; int hdrlen = 12; int subclass; - - /* If we have no peer, return immediately */ + + /* If we have no peer, return immediately */ if (!rtp->them.sin_addr.s_addr) return 0; /* If there is no data length, return immediately */ - if (!_f->datalen) + if (!_f->datalen) return 0; - + /* Make sure we have enough space for RTP header */ if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) { ast_log(LOG_WARNING, "RTP can only send voice and video\n"); @@ -2714,14 +2875,16 @@ codec = ast_rtp_lookup_code(rtp, 1, subclass); if (codec < 0) { - ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass)); + ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", + ast_getformatname(_f->subclass)); return -1; } if (rtp->lasttxformat != subclass) { /* New format, reset the smoother */ if (option_debug) - ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass)); + ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", + ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass)); rtp->lasttxformat = subclass; if (rtp->smoother) ast_smoother_free(rtp->smoother); @@ -2730,15 +2893,20 @@ if (!rtp->smoother) { struct ast_format_list fmt = ast_codec_pref_getsize(&rtp->pref, subclass); - if (fmt.inc_ms) { /* if codec parameters is set / avoid division by zero */ - if (!(rtp->smoother = ast_smoother_new((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms))) { - ast_log(LOG_WARNING, "Unable to create smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms)); + if (fmt.inc_ms) { /* if codec parameters is set / avoid division by zero */ + if (! + (rtp->smoother = + ast_smoother_new((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms))) { + ast_log(LOG_WARNING, + "Unable to create smoother: format: %d ms: %d len: %d\n", + subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms)); return -1; } if (fmt.flags) ast_smoother_set_flags(rtp->smoother, fmt.flags); if (option_debug) - ast_log(LOG_DEBUG, "Created smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms)); + ast_log(LOG_DEBUG, "Created smoother: format: %d ms: %d len: %d\n", + subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms)); } } if (rtp->smoother) { @@ -2748,11 +2916,11 @@ ast_smoother_feed(rtp->smoother, _f); } - while((f = ast_smoother_read(rtp->smoother))) + while ((f = ast_smoother_read(rtp->smoother))) ast_rtp_raw_write(rtp, f, codec); } else { - /* Don't buffer outgoing frames; send them one-per-packet: */ - if (_f->offset < hdrlen) + /* Don't buffer outgoing frames; send them one-per-packet: */ + if (_f->offset < hdrlen) f = ast_frdup(_f); /*! \bug XXX this might never be free'd. Why do we do this? */ else f = _f; @@ -2760,7 +2928,7 @@ if (f != _f) ast_frfree(f); } - + return 0; } @@ -2778,27 +2946,43 @@ struct ast_rtp_protocol *cur; AST_LIST_LOCK(&protos); - AST_LIST_TRAVERSE(&protos, cur, list) { + AST_LIST_TRAVERSE(&protos, cur, list) { if (!strcmp(cur->type, proto->type)) { - ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type); + ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", + cur->type); AST_LIST_UNLOCK(&protos); return -1; } } AST_LIST_INSERT_HEAD(&protos, proto, list); AST_LIST_UNLOCK(&protos); - + return 0; } /*! \brief Bridge loop for true native bridge (reinvite) */ -static enum ast_bridge_result bridge_native_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, struct ast_rtp *vp0, struct ast_rtp *vp1, struct ast_rtp_protocol *pr0, struct ast_rtp_protocol *pr1, int codec0, int codec1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1) +static enum ast_bridge_result bridge_native_loop(struct ast_channel *c0, + struct ast_channel *c1, + struct ast_rtp *p0, struct ast_rtp *p1, + struct ast_rtp *vp0, struct ast_rtp *vp1, + struct ast_rtp_protocol *pr0, + struct ast_rtp_protocol *pr1, int codec0, + int codec1, int timeoutms, int flags, + struct ast_frame **fo, + struct ast_channel **rc, void *pvt0, + void *pvt1) { struct ast_frame *fr = NULL; - struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, }; + struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, }; int oldcodec0 = codec0, oldcodec1 = codec1; - struct sockaddr_in ac1 = {0,}, vac1 = {0,}, ac0 = {0,}, vac0 = {0,}; - struct sockaddr_in t1 = {0,}, vt1 = {0,}, t0 = {0,}, vt0 = {0,}; + struct sockaddr_in ac1 = { 0, }, vac1 = { + 0,}, ac0 = { + 0,}, vac0 = { + 0,}; + struct sockaddr_in t1 = { 0, }, vt1 = { + 0,}, t0 = { + 0,}, vt0 = { + 0,}; /* Set it up so audio goes directly between the two endpoints */ @@ -2809,7 +2993,7 @@ ast_rtp_get_peer(vp1, &vac1); } else ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name); - + /* Test the second channel */ if (!(pr1->set_rtp_peer(c1, p0, vp0, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE)))) { ast_rtp_get_peer(p0, &ac0); @@ -2829,16 +3013,17 @@ for (;;) { /* Check if anything changed */ if ((c0->tech_pvt != pvt0) || - (c1->tech_pvt != pvt1) || - (c0->masq || c0->masqr || c1->masq || c1->masqr)) { + (c1->tech_pvt != pvt1) || (c0->masq || c0->masqr || c1->masq || c1->masqr)) { if (option_debug) ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n"); if (c0->tech_pvt == pvt0) if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) - ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); + ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", + c0->name); if (c1->tech_pvt == pvt1) if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) - ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); + ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", + c1->name); return AST_BRIDGE_RETRY; } @@ -2854,34 +3039,44 @@ if (pr0->get_codec) codec0 = pr0->get_codec(c0); if ((inaddrcmp(&t1, &ac1)) || - (vp1 && inaddrcmp(&vt1, &vac1)) || - (codec1 != oldcodec1)) { + (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) { if (option_debug > 1) { - ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", - c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), codec1); - ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", - c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), codec1); - ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", - c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1); - ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", - c1->name, ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1); + ast_log(LOG_DEBUG, + "Oooh, '%s' changed end address to %s:%d (format %d)\n", c1->name, + ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), codec1); + ast_log(LOG_DEBUG, + "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", + c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), + codec1); + ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", c1->name, + ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1); + ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", c1->name, + ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1); } - if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE))) - ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name); + if (pr0-> + set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, + vt1.sin_addr.s_addr ? vp1 : NULL, codec1, ast_test_flag(p1, + FLAG_NAT_ACTIVE))) + ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, + c1->name); memcpy(&ac1, &t1, sizeof(ac1)); memcpy(&vac1, &vt1, sizeof(vac1)); oldcodec1 = codec1; } - if ((inaddrcmp(&t0, &ac0)) || - (vp0 && inaddrcmp(&vt0, &vac0))) { + if ((inaddrcmp(&t0, &ac0)) || (vp0 && inaddrcmp(&vt0, &vac0))) { if (option_debug > 1) { - ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", - c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), codec0); - ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", - c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0); + ast_log(LOG_DEBUG, + "Oooh, '%s' changed end address to %s:%d (format %d)\n", c0->name, + ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), codec0); + ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", c0->name, + ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0); } - if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE))) - ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name); + if (pr1-> + set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, + vt0.sin_addr.s_addr ? vp0 : NULL, codec0, ast_test_flag(p0, + FLAG_NAT_ACTIVE))) + ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, + c0->name); memcpy(&ac0, &t0, sizeof(ac0)); memcpy(&vac0, &vt0, sizeof(vac0)); oldcodec0 = codec0; @@ -2900,8 +3095,8 @@ fr = ast_read(who); other = (who == c0) ? c1 : c0; if (!fr || ((fr->frametype == AST_FRAME_DTMF) && - (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || - ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) { + (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || + ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) { /* Break out of bridge */ *fo = fr; *rc = who; @@ -2909,28 +3104,31 @@ ast_log(LOG_DEBUG, "Oooh, got a %s\n", fr ? "digit" : "hangup"); if (c0->tech_pvt == pvt0) if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) - ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); + ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", + c0->name); if (c1->tech_pvt == pvt1) if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) - ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); + ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", + c1->name); return AST_BRIDGE_COMPLETE; - } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { - if ((fr->subclass == AST_CONTROL_HOLD) || - (fr->subclass == AST_CONTROL_UNHOLD) || - (fr->subclass == AST_CONTROL_VIDUPDATE)) { + } else if ((fr->frametype == AST_FRAME_CONTROL) && + !(flags & AST_BRIDGE_IGNORE_SIGS)) { + if ((fr->subclass == AST_CONTROL_HOLD) || (fr->subclass == AST_CONTROL_UNHOLD) + || (fr->subclass == AST_CONTROL_VIDUPDATE)) { ast_indicate(other, fr->subclass); ast_frfree(fr); } else { *fo = fr; *rc = who; if (option_debug) - ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name); + ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", + fr->subclass, who->name); return AST_BRIDGE_COMPLETE; } } else { if ((fr->frametype == AST_FRAME_DTMF) || - (fr->frametype == AST_FRAME_VOICE) || - (fr->frametype == AST_FRAME_VIDEO)) { + (fr->frametype == AST_FRAME_VOICE) || + (fr->frametype == AST_FRAME_VIDEO)) { ast_write(other, fr); } ast_frfree(fr); @@ -2957,20 +3155,25 @@ return 1; len = sizeof(sin); - if ((res = recvfrom(fd, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0, (struct sockaddr *)&sin, &len)) < 0) + if ((res = + recvfrom(fd, rtp->rawdata + AST_FRIENDLY_OFFSET, + sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0, (struct sockaddr *) &sin, + &len)) < 0) return 1; - header = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET); + header = (unsigned int *) (rtp->rawdata + AST_FRIENDLY_OFFSET); /* If NAT support is turned on, then see if we need to change their address */ - if ((rtp->nat) && - ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || - (rtp->them.sin_port != sin.sin_port))) { + if ((rtp->nat) && + ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || + (rtp->them.sin_port != sin.sin_port))) { rtp->them = sin; rtp->rxseqno = 0; ast_set_flag(rtp, FLAG_NAT_ACTIVE); if (option_debug || rtpdebug) - ast_log(LOG_DEBUG, "P2P RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); + ast_log(LOG_DEBUG, + "P2P RTP NAT: Got audio from other end. Now sending to address %s:%d\n", + ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); } /* Write directly out to other RTP stream if bridged */ @@ -2984,7 +3187,8 @@ static int p2p_callback_enable(struct ast_channel *chan, struct ast_rtp *rtp, int **iod) { /* If we need DTMF, are looking for STUN, or we have no IO structure then we can't do direct callback */ - if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) || ast_test_flag(rtp, FLAG_HAS_STUN) || !rtp->io) + if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) || ast_test_flag(rtp, FLAG_HAS_STUN) || + !rtp->io) return 0; /* If the RTP structure is already in callback mode, remove it temporarily */ @@ -3024,11 +3228,11 @@ /*! \brief Helper function that sets what an RTP structure is bridged to */ static void p2p_set_bridge(struct ast_rtp *rtp0, struct ast_rtp *rtp1) { - ast_mutex_lock(&rtp0->bridge_lock); - rtp0->bridged = rtp1; - ast_mutex_unlock(&rtp0->bridge_lock); + ast_mutex_lock(&rtp0->bridge_lock); + rtp0->bridged = rtp1; + ast_mutex_unlock(&rtp0->bridge_lock); - return; + return; } /*! \brief Bridge loop for partial native bridge (packet2packet) @@ -3037,11 +3241,17 @@ rtp/rtcp we get in to the channel. \note this currently only works for Audio */ -static enum ast_bridge_result bridge_p2p_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1) +static enum ast_bridge_result bridge_p2p_loop(struct ast_channel *c0, + struct ast_channel *c1, struct ast_rtp *p0, + struct ast_rtp *p1, int timeoutms, + int flags, struct ast_frame **fo, + struct ast_channel **rc, void *pvt0, + void *pvt1) { struct ast_frame *fr = NULL; - struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, }; - int *p0_iod[2] = {NULL, NULL}, *p1_iod[2] = {NULL, NULL}; + struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, }; + int *p0_iod[2] = { NULL, NULL }, *p1_iod[2] = { + NULL, NULL}; int p0_callback = 0, p1_callback = 0; enum ast_bridge_result res = AST_BRIDGE_FAILED; @@ -3066,10 +3276,10 @@ for (;;) { /* Check if anything changed */ if ((c0->tech_pvt != pvt0) || - (c1->tech_pvt != pvt1) || - (c0->masq || c0->masqr || c1->masq || c1->masqr)) { + (c1->tech_pvt != pvt1) || (c0->masq || c0->masqr || c1->masq || c1->masqr)) { if (option_debug > 2) - ast_log(LOG_DEBUG, "p2p-rtp-bridge: Oooh, something is weird, backing out\n"); + ast_log(LOG_DEBUG, + "p2p-rtp-bridge: Oooh, something is weird, backing out\n"); res = AST_BRIDGE_RETRY; break; } @@ -3090,19 +3300,20 @@ other = (who == c0) ? c1 : c0; /* Depending on the frame we may need to break out of our bridge */ if (!fr || ((fr->frametype == AST_FRAME_DTMF) && - ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) | - ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) { + ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) | + ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) { /* Record received frame and who */ *fo = fr; *rc = who; if (option_debug > 2) - ast_log(LOG_DEBUG, "p2p-rtp-bridge: Ooh, got a %s\n", fr ? "digit" : "hangup"); + ast_log(LOG_DEBUG, "p2p-rtp-bridge: Ooh, got a %s\n", + fr ? "digit" : "hangup"); res = AST_BRIDGE_COMPLETE; break; - } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { - if ((fr->subclass == AST_CONTROL_HOLD) || - (fr->subclass == AST_CONTROL_UNHOLD) || - (fr->subclass == AST_CONTROL_VIDUPDATE)) { + } else if ((fr->frametype == AST_FRAME_CONTROL) && + !(flags & AST_BRIDGE_IGNORE_SIGS)) { + if ((fr->subclass == AST_CONTROL_HOLD) || (fr->subclass == AST_CONTROL_UNHOLD) + || (fr->subclass == AST_CONTROL_VIDUPDATE)) { /* If we are going on hold, then break callback mode and P2P bridging */ if (fr->subclass == AST_CONTROL_HOLD) { if (p0_callback) @@ -3126,15 +3337,17 @@ *fo = fr; *rc = who; if (option_debug > 2) - ast_log(LOG_DEBUG, "p2p-rtp-bridge: Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name); + ast_log(LOG_DEBUG, + "p2p-rtp-bridge: Got a FRAME_CONTROL (%d) frame on channel %s\n", + fr->subclass, who->name); res = AST_BRIDGE_COMPLETE; break; } } else { /* If this is a DTMF, voice, or video frame write it to the other channel */ if ((fr->frametype == AST_FRAME_DTMF) || - (fr->frametype == AST_FRAME_VOICE) || - (fr->frametype == AST_FRAME_VIDEO)) { + (fr->frametype == AST_FRAME_VOICE) || + (fr->frametype == AST_FRAME_VIDEO)) { ast_write(other, fr); } ast_frfree(fr); @@ -3188,20 +3401,24 @@ - ast_channel_early_bridge() - ast_channel_bridge() */ -enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) +enum ast_bridge_result ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, + int flags, struct ast_frame **fo, + struct ast_channel **rc, int timeoutms) { - struct ast_rtp *p0 = NULL, *p1 = NULL; /* Audio RTP Channels */ + struct ast_rtp *p0 = NULL, *p1 = NULL; /* Audio RTP Channels */ struct ast_rtp *vp0 = NULL, *vp1 = NULL; /* Video RTP channels */ struct ast_rtp_protocol *pr0 = NULL, *pr1 = NULL; - enum ast_rtp_get_result audio_p0_res = AST_RTP_GET_FAILED, video_p0_res = AST_RTP_GET_FAILED; - enum ast_rtp_get_result audio_p1_res = AST_RTP_GET_FAILED, video_p1_res = AST_RTP_GET_FAILED; + enum ast_rtp_get_result audio_p0_res = AST_RTP_GET_FAILED, video_p0_res = + AST_RTP_GET_FAILED; + enum ast_rtp_get_result audio_p1_res = AST_RTP_GET_FAILED, video_p1_res = + AST_RTP_GET_FAILED; enum ast_bridge_result res = AST_BRIDGE_FAILED; int codec0 = 0, codec1 = 0; void *pvt0 = NULL, *pvt1 = NULL; /* Lock channels */ ast_channel_lock(c0); - while(ast_channel_trylock(c1)) { + while (ast_channel_trylock(c1)) { ast_channel_unlock(c0); usleep(1); ast_channel_lock(c0); @@ -3232,9 +3449,11 @@ video_p1_res = pr1->get_vrtp_info ? pr1->get_vrtp_info(c1, &vp1) : AST_RTP_GET_FAILED; /* If we are carrying video, and both sides are not reinviting... then fail the native bridge */ - if (video_p0_res != AST_RTP_GET_FAILED && (audio_p0_res != AST_RTP_TRY_NATIVE || video_p0_res != AST_RTP_TRY_NATIVE)) + if (video_p0_res != AST_RTP_GET_FAILED && + (audio_p0_res != AST_RTP_TRY_NATIVE || video_p0_res != AST_RTP_TRY_NATIVE)) audio_p0_res = AST_RTP_GET_FAILED; - if (video_p1_res != AST_RTP_GET_FAILED && (audio_p1_res != AST_RTP_TRY_NATIVE || video_p1_res != AST_RTP_TRY_NATIVE)) + if (video_p1_res != AST_RTP_GET_FAILED && + (audio_p1_res != AST_RTP_TRY_NATIVE || video_p1_res != AST_RTP_TRY_NATIVE)) audio_p1_res = AST_RTP_GET_FAILED; /* Check if a bridge is possible (partial/native) */ @@ -3262,7 +3481,9 @@ if (codec0 && codec1 && !(codec0 & codec1)) { /* Hey, we can't do native bridging if both parties speak different codecs */ if (option_debug > 2) - ast_log(LOG_DEBUG, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1); + ast_log(LOG_DEBUG, + "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", + codec0, codec1); ast_channel_unlock(c0); ast_channel_unlock(c1); return AST_BRIDGE_FAILED_NOWARN; @@ -3271,20 +3492,26 @@ /* If either side can only do a partial bridge, then don't try for a true native bridge */ if (audio_p0_res == AST_RTP_TRY_PARTIAL || audio_p1_res == AST_RTP_TRY_PARTIAL) { /* In order to do Packet2Packet bridging both sides must be in the same rawread/rawwrite */ - if (c0->rawreadformat != c1->rawwriteformat || c1->rawreadformat != c0->rawwriteformat) { + if (c0->rawreadformat != c1->rawwriteformat || + c1->rawreadformat != c0->rawwriteformat) { if (option_debug) - ast_log(LOG_DEBUG, "Cannot packet2packet bridge - raw formats are incompatible\n"); + ast_log(LOG_DEBUG, + "Cannot packet2packet bridge - raw formats are incompatible\n"); ast_channel_unlock(c0); ast_channel_unlock(c1); return AST_BRIDGE_FAILED_NOWARN; } if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Packet2Packet bridging %s and %s\n", c0->name, c1->name); + ast_verbose(VERBOSE_PREFIX_3 "Packet2Packet bridging %s and %s\n", c0->name, + c1->name); res = bridge_p2p_loop(c0, c1, p0, p1, timeoutms, flags, fo, rc, pvt0, pvt1); } else { - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); - res = bridge_native_loop(c0, c1, p0, p1, vp0, vp1, pr0, pr1, codec0, codec1, timeoutms, flags, fo, rc, pvt0, pvt1); + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, + c1->name); + res = + bridge_native_loop(c0, c1, p0, p1, vp0, vp1, pr0, pr1, codec0, codec1, + timeoutms, flags, fo, rc, pvt0, pvt1); } return res; @@ -3313,9 +3540,11 @@ memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr)); rtpdebugaddr.sin_port = htons(port); if (port == 0) - ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtpdebugaddr.sin_addr)); + ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", + ast_inet_ntoa(rtpdebugaddr.sin_addr)); else - ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtpdebugaddr.sin_addr), port); + ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", + ast_inet_ntoa(rtpdebugaddr.sin_addr), port); rtpdebug = 1; return RESULT_SUCCESS; } @@ -3343,9 +3572,11 @@ memcpy(&rtcpdebugaddr.sin_addr, hp->h_addr, sizeof(rtcpdebugaddr.sin_addr)); rtcpdebugaddr.sin_port = htons(port); if (port == 0) - ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr)); + ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", + ast_inet_ntoa(rtcpdebugaddr.sin_addr)); else - ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port); + ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", + ast_inet_ntoa(rtcpdebugaddr.sin_addr), port); rtcpdebug = 1; return RESULT_SUCCESS; } @@ -3358,24 +3589,26 @@ return rtp_do_debug_ip(fd, argc, argv); } rtpdebug = 1; - memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr)); + memset(&rtpdebugaddr, 0, sizeof(rtpdebugaddr)); ast_cli(fd, "RTP Debugging Enabled\n"); return RESULT_SUCCESS; } - -static int rtcp_do_debug(int fd, int argc, char *argv[]) { + +static int rtcp_do_debug(int fd, int argc, char *argv[]) +{ if (argc != 2) { if (argc != 4) return RESULT_SHOWUSAGE; return rtcp_do_debug_ip(fd, argc, argv); } rtcpdebug = 1; - memset(&rtcpdebugaddr,0,sizeof(rtcpdebugaddr)); + memset(&rtcpdebugaddr, 0, sizeof(rtcpdebugaddr)); ast_cli(fd, "RTCP Debugging Enabled\n"); return RESULT_SUCCESS; } -static int rtcp_do_stats(int fd, int argc, char *argv[]) { +static int rtcp_do_stats(int fd, int argc, char *argv[]) +{ if (argc != 2) { return RESULT_SHOWUSAGE; } @@ -3389,7 +3622,7 @@ if (argc != 3) return RESULT_SHOWUSAGE; rtpdebug = 0; - ast_cli(fd,"RTP Debugging Disabled\n"); + ast_cli(fd, "RTP Debugging Disabled\n"); return RESULT_SUCCESS; } @@ -3398,7 +3631,7 @@ if (argc != 3) return RESULT_SHOWUSAGE; rtcpdebug = 0; - ast_cli(fd,"RTCP Debugging Disabled\n"); + ast_cli(fd, "RTCP Debugging Disabled\n"); return RESULT_SUCCESS; } @@ -3407,7 +3640,7 @@ if (argc != 3) return RESULT_SHOWUSAGE; rtcpstats = 0; - ast_cli(fd,"RTCP Stats Disabled\n"); + ast_cli(fd, "RTCP Stats Disabled\n"); return RESULT_SUCCESS; } @@ -3420,7 +3653,7 @@ ast_cli(fd, "STUN Debugging Enabled\n"); return RESULT_SUCCESS; } - + static int stun_no_debug(int fd, int argc, char *argv[]) { if (argc != 3) @@ -3431,77 +3664,72 @@ } static const char debug_usage[] = - "Usage: rtp debug [ip host[:port]]\n" - " Enable dumping of all RTP packets to and from host.\n"; + "Usage: rtp debug [ip host[:port]]\n" + " Enable dumping of all RTP packets to and from host.\n"; static const char no_debug_usage[] = - "Usage: rtp debug off\n" - " Disable all RTP debugging\n"; + "Usage: rtp debug off\n" " Disable all RTP debugging\n"; static const char stun_debug_usage[] = - "Usage: stun debug\n" - " Enable STUN (Simple Traversal of UDP through NATs) debugging\n"; + "Usage: stun debug\n" + " Enable STUN (Simple Traversal of UDP through NATs) debugging\n"; static const char stun_no_debug_usage[] = - "Usage: stun debug off\n" - " Disable STUN debugging\n"; + "Usage: stun debug off\n" " Disable STUN debugging\n"; static const char rtcp_debug_usage[] = - "Usage: rtcp debug [ip host[:port]]\n" - " Enable dumping of all RTCP packets to and from host.\n"; - + "Usage: rtcp debug [ip host[:port]]\n" + " Enable dumping of all RTCP packets to and from host.\n"; + static const char rtcp_no_debug_usage[] = - "Usage: rtcp debug off\n" - " Disable all RTCP debugging\n"; + "Usage: rtcp debug off\n" " Disable all RTCP debugging\n"; static const char rtcp_stats_usage[] = - "Usage: rtcp stats\n" - " Enable dumping of RTCP stats.\n"; - + "Usage: rtcp stats\n" " Enable dumping of RTCP stats.\n"; + static const char rtcp_no_stats_usage[] = - "Usage: rtcp stats off\n" - " Disable all RTCP stats\n"; + "Usage: rtcp stats off\n" " Disable all RTCP stats\n"; static struct ast_cli_entry cli_rtp[] = { - { { "rtp", "debug", "ip", NULL }, - rtp_do_debug, "Enable RTP debugging on IP", - debug_usage }, + {{"rtp", "debug", "ip", NULL}, + rtp_do_debug, "Enable RTP debugging on IP", + debug_usage}, - { { "rtp", "debug", NULL }, - rtp_do_debug, "Enable RTP debugging", - debug_usage }, + {{"rtp", "debug", NULL}, + rtp_do_debug, "Enable RTP debugging", + debug_usage}, - { { "rtp", "debug", "off", NULL }, - rtp_no_debug, "Disable RTP debugging", - no_debug_usage }, + {{"rtp", "debug", "off", NULL}, + rtp_no_debug, "Disable RTP debugging", + no_debug_usage}, - { { "rtcp", "debug", "ip", NULL }, - rtcp_do_debug, "Enable RTCP debugging on IP", - rtcp_debug_usage }, + {{"rtcp", "debug", "ip", NULL}, + rtcp_do_debug, "Enable RTCP debugging on IP", + rtcp_debug_usage}, - { { "rtcp", "debug", NULL }, - rtcp_do_debug, "Enable RTCP debugging", - rtcp_debug_usage }, + {{"rtcp", "debug", NULL}, + rtcp_do_debug, "Enable RTCP debugging", + rtcp_debug_usage}, - { { "rtcp", "debug", "off", NULL }, - rtcp_no_debug, "Disable RTCP debugging", - rtcp_no_debug_usage }, + {{"rtcp", "debug", "off", NULL}, + rtcp_no_debug, "Disable RTCP debugging", + rtcp_no_debug_usage}, - { { "rtcp", "stats", NULL }, - rtcp_do_stats, "Enable RTCP stats", - rtcp_stats_usage }, + {{"rtcp", "stats", NULL}, + rtcp_do_stats, "Enable RTCP stats", + rtcp_stats_usage}, - { { "rtcp", "stats", "off", NULL }, - rtcp_no_stats, "Disable RTCP stats", - rtcp_no_stats_usage }, + {{"rtcp", "stats", "off", NULL}, + rtcp_no_stats, "Disable RTCP stats", + rtcp_no_stats_usage}, - { { "stun", "debug", NULL }, - stun_do_debug, "Enable STUN debugging", - stun_debug_usage }, + {{"stun", "debug", NULL}, + stun_do_debug, "Enable STUN debugging", + stun_debug_usage}, - { { "stun", "debug", "off", NULL }, - stun_no_debug, "Disable STUN debugging", - stun_no_debug_usage }, + {{"stun", "debug", "off", NULL}, + stun_no_debug, "Disable STUN debugging", + stun_no_debug_usage}, }; int ast_rtp_reload(void) @@ -3531,9 +3759,9 @@ if ((s = ast_variable_retrieve(cfg, "general", "rtcpinterval"))) { rtcpinterval = atoi(s); if (rtcpinterval == 0) - rtcpinterval = 0; /* Just so we're clear... it's zero */ + rtcpinterval = 0; /* Just so we're clear... it's zero */ if (rtcpinterval < RTCP_MIN_INTERVALMS) - rtcpinterval = RTCP_MIN_INTERVALMS; /* This catches negative numbers too */ + rtcpinterval = RTCP_MIN_INTERVALMS; /* This catches negative numbers too */ if (rtcpinterval > RTCP_MAX_INTERVALMS) rtcpinterval = RTCP_MAX_INTERVALMS; } @@ -3545,14 +3773,16 @@ nochecksums = 0; #else if (ast_false(s)) - ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); + ast_log(LOG_WARNING, + "Disabling RTP checksums is not supported on this operating system!\n"); #endif } if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) { dtmftimeout = atoi(s); if ((dtmftimeout < 0) || (dtmftimeout > 20000)) { - ast_log(LOG_WARNING, "DTMF timeout of '%d' outside range, using default of '%d' instead\n", - dtmftimeout, DEFAULT_DTMF_TIMEOUT); + ast_log(LOG_WARNING, + "DTMF timeout of '%d' outside range, using default of '%d' instead\n", + dtmftimeout, DEFAULT_DTMF_TIMEOUT); dtmftimeout = DEFAULT_DTMF_TIMEOUT; }; } @@ -3564,7 +3794,8 @@ rtpend = 31000; } if (option_verbose > 1) - ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend); + ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", + rtpstart, rtpend); return 0; } @@ -3574,4 +3805,3 @@ ast_cli_register_multiple(cli_rtp, sizeof(cli_rtp) / sizeof(struct ast_cli_entry)); ast_rtp_reload(); } -