diff --git a/build/modules.conf.in b/build/modules.conf.in index 783eddf41f..559b06e8ea 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -7,8 +7,10 @@ applications/mod_hash applications/mod_spandsp dialplans/mod_dialplan_xml endpoints/mod_sofia -endpoints/mod_media_gateway +#endpoints/mod_media_gateway ../../libs/freetdm/mod_freetdm xml_int/mod_xml_cdr event_handlers/mod_event_socket codecs/mod_sangoma_codec +event_handlers/mod_radius_cdr +applications/mod_rad_auth diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 185fdb64af..593e921bcd 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -547,6 +547,8 @@ typedef struct { typedef struct { uint32_t packet_count; uint32_t octet_count; + + uint32_t peer_ssrc; } switch_rtcp_numbers_t; typedef struct { @@ -769,7 +771,6 @@ typedef struct { unsigned type:8; /* packet type */ unsigned length:16; /* length in 32-bit words - 1 */ } switch_rtcp_hdr_t; - #else /* BIG_ENDIAN */ typedef struct { diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c index 64caa13a99..c1772ae89b 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c @@ -12,7 +12,7 @@ static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) ; static switch_xml_config_item_t *get_peer_instructions(mg_peer_profile_t *profile) ; static int mg_sap_id; -static switch_status_t modify_mid(char* mid); +static switch_status_t modify_mid(char** pmid); /****************************************************************************************************************************/ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) @@ -59,10 +59,11 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) profile->total_peers++; } - if(SWITCH_STATUS_FALSE == (status = modify_mid(profile->mid))){ + if(SWITCH_STATUS_FALSE == (status = modify_mid(&profile->mid))){ goto done; } + profile->idx = ++mg_sap_id; /* we should break from here , profile name should be unique */ @@ -100,7 +101,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) goto done; } - if(SWITCH_STATUS_FALSE == (status = modify_mid(peer_profile->mid))){ + if(SWITCH_STATUS_FALSE == (status = modify_mid(&peer_profile->mid))){ goto done; } @@ -213,55 +214,57 @@ static switch_xml_config_item_t *get_instructions(megaco_profile_t *profile) { /****************************************************************************************************************************/ -static switch_status_t modify_mid(char* mid) +static switch_status_t modify_mid(char** pmid) { - char dup[64]; + char* mid = *pmid; + char* dup; char* val[10]; int count; - + switch_status_t status = SWITCH_STATUS_FALSE; switch_assert(mid); - memset(&dup[0],0,sizeof(dup)); + dup = strdup(mid); /* If MID type is IP then add mid into [] brackets , * If MID type is domain then add mid into <> brackets * */ - strcpy(&dup[0],mid); - count = switch_split(&dup[0], '.', val); + count = switch_split(dup, '.', val); if(!count) { /* Input string is not separated by '.', check if its separated by '-' as format could be xxx-xx-xxx/xxx-xx-xx-xxx */ - memset(&dup[0],0,sizeof(dup)); - strcpy(&dup[0],mid); if(0 == (count = switch_split(dup, '-', val))){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid input MID string[%s]\n",mid); - return SWITCH_STATUS_FALSE; + goto done; } } if(('<' == val[0][0]) || ('[' == val[0][0])){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "MID = %s is already prefixed with proper brackets \n",mid); - return SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; + goto done; } /*first check could be if count is 3 means domain name as generally we have xxx-xx-xxx/xxx.xx.xxx domain */ if(3 == count){ /* domain-type, add value into <> */ - memset(&dup[0],0,sizeof(dup)); - strcpy(&dup[0],mid); - sprintf(mid,"<%s>",dup); + *pmid = switch_mprintf("<%s>", mid); + free(mid); + mid = *pmid; }else if(4 == count){ /* IP address in xxx.xxx.xxx.xxx format */ - memset(&dup[0],0,sizeof(dup)); - strcpy(&dup[0],mid); - sprintf(mid,"[%s]",dup); + *pmid = switch_mprintf("[%s]", mid); + free(mid); + mid = *pmid; }else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid input MID string[%s]\n",mid); - return SWITCH_STATUS_FALSE; + goto done; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added proper brackets to MID = %s \n",mid); - return SWITCH_STATUS_SUCCESS; + status = SWITCH_STATUS_SUCCESS; + +done: + return status; } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 5e741c4eb7..ff03a8d054 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -264,6 +264,46 @@ struct switch_rtp { switch_size_t last_flush_packet_count; }; +struct switch_rtcp_source { + unsigned ssrc1:32; + unsigned fraction_lost:8; + unsigned cumulative_lost:24; + unsigned hi_seq_recieved:32; + unsigned interarrival_jitter:32; + unsigned lsr:32; + unsigned lsr_delay:32; +}; + + +#if SWITCH_BYTE_ORDER == __BIG_ENDIAN +struct switch_rtcp_s_desc_head { + unsigned v:2; + unsigned padding:1; + unsigned sc:5; + unsigned pt:8; + unsigned length:16; +}; + +#else /* BIG_ENDIAN */ + +struct switch_rtcp_s_desc_head { + unsigned sc:5; + unsigned padding:1; + unsigned v:2; + unsigned pt:8; + unsigned length:16; +}; + +#endif + + +struct switch_rtcp_s_desc_trunk { + unsigned ssrc:32; + unsigned cname:8; + unsigned length:8; + char text[1]; +}; + struct switch_rtcp_senderinfo { unsigned ssrc:32; unsigned ntp_msw:32; @@ -271,6 +311,9 @@ struct switch_rtcp_senderinfo { unsigned ts:32; unsigned pc:32; unsigned oc:32; + struct switch_rtcp_source sr_source; + struct switch_rtcp_s_desc_head sr_desc_head; + struct switch_rtcp_s_desc_trunk sr_desc_ssrc; }; typedef enum { @@ -1637,8 +1680,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->rtcp_send_msg.header.version = 2; rtp_session->rtcp_send_msg.header.p = 0; rtp_session->rtcp_send_msg.header.type = 200; - rtp_session->rtcp_send_msg.header.count = 0; - rtp_session->rtcp_send_msg.header.length = htons(6); + rtp_session->rtcp_send_msg.header.count = 1; + rtp_session->rtcp_send_msg.header.length = htons(12); switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval); @@ -2823,9 +2866,10 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t rtp_session->stats.rtcp.packet_count += sr->pc; rtp_session->stats.rtcp.octet_count += sr->oc; + rtp_session->stats.rtcp.peer_ssrc = ntohl(sr->ssrc); /* sender report */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \ + switch_log_printf(SWITCH_CHANNEL_LOG, /*SWITCH_LOG_DEBUG10*/ SWITCH_LOG_INFO,"Received a SR with %d report blocks, " \ "length in words = %d, " \ "SSRC = 0x%X, " \ "NTP MSW = %u, " \ @@ -4025,15 +4069,52 @@ static int rtp_common_write(switch_rtp_t *rtp_session, switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) && rtp_session->rtcp_interval && (rtp_session->stats.outbound.packet_count % rtp_session->rtcp_interval) == 0) { struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body; + const char* str_cname=NULL; sr->ssrc = send_msg->header.ssrc; - sr->ntp_msw = htonl((u_long)rtp_session->send_time / 1000000 + 2208988800UL); + sr->ntp_msw = htonl((u_long)(rtp_session->send_time / 1000000 + 2208988800UL)); + /* sr->ntp_lsw = htonl((u_long)(rtp_session->send_time % 1000000 * ((UINT_MAX * 1.0)/ 1000000.0))); + */ + sr->ntp_lsw = htonl((u_long)(rtp_session->send_time % 1000000 * 4294.967296)); sr->ts = send_msg->header.ts; sr->pc = htonl(rtp_session->stats.outbound.packet_count); sr->oc = htonl((rtp_session->stats.outbound.raw_bytes - rtp_session->stats.outbound.packet_count * sizeof(srtp_hdr_t))); - rtcp_bytes = sizeof(switch_rtcp_hdr_t) + sizeof(struct switch_rtcp_senderinfo); + + sr->sr_source.ssrc1 = htonl(rtp_session->stats.rtcp.peer_ssrc); + sr->sr_source.fraction_lost |= 0; + sr->sr_source.cumulative_lost |= 0; + sr->sr_source.hi_seq_recieved = htonl(rtp_session->last_seq); + sr->sr_source.interarrival_jitter = htonl(0); + sr->sr_source.lsr = htonl(0); + sr->sr_source.lsr_delay = htonl(0); + + sr->sr_desc_head.v = 0x02; + sr->sr_desc_head.padding = 0; + sr->sr_desc_head.sc = 1; + sr->sr_desc_head.pt = 202; + sr->sr_desc_head.length = htons(5); + + + sr->sr_desc_ssrc.ssrc = send_msg->header.ssrc; /*htonl(rtp_session->stats.rtcp.peer_ssrc); */ + sr->sr_desc_ssrc.cname = 0x1; + { + char bufa[30]; + str_cname = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtcp_local_addr); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Setting RTCP src-1 to %s\n", str_cname); + sr->sr_desc_ssrc.length = strlen(str_cname); + memcpy ((char*)sr->sr_desc_ssrc.text, str_cname, strlen(str_cname)); + } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Setting RTCP src-1 LENGTH to %d (%d, %s)\n", sr->sr_desc_ssrc.length, sr->sr_desc_head.length, str_cname); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Setting msw = %d, lsw = %d \n", sr->ntp_msw, sr->ntp_lsw); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "now = %lld, now lo = %d, now hi = %d\n", (int64_t)now, (int32_t)(now&0xFFFFFFFF), (int32_t)((now>>32&0xFFFFFFFF))); + + + rtcp_bytes = sizeof(switch_rtcp_hdr_t) + sizeof(struct switch_rtcp_senderinfo) + sr->sr_desc_ssrc.length -1 ; + + #ifdef ENABLE_SRTP if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) { int sbytes = (int) rtcp_bytes;