switch_channel_set_flag(switch_core_session_get_channel(session), CF_VERBOSE_EVENTS);
}
+SWITCH_STANDARD_APP(cng_plc_function)
+{
+ switch_channel_set_flag(switch_core_session_get_channel(session), CF_CNG_PLC);
+}
+
SWITCH_STANDARD_APP(early_hangup_function)
{
switch_channel_set_flag(switch_core_session_get_channel(session), CF_EARLY_HANGUP);
"<ip> <acl | cidr> [<hangup_cause>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
+ SWITCH_ADD_APP(app_interface, "cng_plc", "Do PLC on CNG frames", "", cng_plc_function, "",
+ SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "early_hangup", "Enable early hangup", "", early_hangup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
}
if (status == SWITCH_STATUS_SUCCESS) {
- if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && !session->plc) {
+ if ((switch_channel_test_flag(session->channel, CF_JITTERBUFFER) || switch_channel_test_flag(session->channel, CF_CNG_PLC))
+ && !session->plc) {
session->plc = plc_init(NULL);
}
uint32_t ts;
uint32_t last_write_ts;
uint32_t last_read_ts;
+ uint32_t last_cng_ts;
uint32_t last_write_samplecount;
uint32_t next_write_samplecount;
switch_time_t last_write_timestamp;
{
switch_status_t status = SWITCH_STATUS_FALSE;
stfu_frame_t *jb_frame;
+ uint32_t ts;
switch_assert(bytes);
*bytes = sizeof(rtp_msg_t);
status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes);
+ ts = ntohl(rtp_session->recv_msg.header.ts);
+
+ if (ts && !rtp_session->jb && ts <= rtp_session->last_cng_ts) {
+ /* we already sent this frame..... */
+ *bytes = 0;
+ return SWITCH_STATUS_SUCCESS;
+ }
if (*bytes) {
rtp_session->stats.inbound.raw_bytes += *bytes;
}
- rtp_session->last_read_ts = ntohl(rtp_session->recv_msg.header.ts);
+ rtp_session->last_read_ts = ts;
if (rtp_session->jb && rtp_session->recv_msg.header.version == 2 && *bytes) {
if (rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te &&
if (do_cng) {
uint8_t *data = (uint8_t *) rtp_session->recv_msg.body;
-
+ rtp_session->last_cng_ts = rtp_session->last_read_ts + rtp_session->samples_per_interval;
+
memset(data, 0, 2);
data[0] = 65;
rtp_session->recv_msg.header.pt = (uint32_t) rtp_session->cng_pt ? rtp_session->cng_pt : SWITCH_RTP_CNG_PAYLOAD;