static switch_status_t channel_on_destroy(switch_core_session_t *session) { ctdm_private_t *tech_pvt = switch_core_session_get_private(session); if ((tech_pvt = switch_core_session_get_private(session))) { if (FTDM_SUCCESS != ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to enable echo cancellation.\n"); } if (tech_pvt->read_codec.implementation) { switch_core_codec_destroy(&tech_pvt->read_codec); } if (tech_pvt->write_codec.implementation) { switch_core_codec_destroy(&tech_pvt->write_codec); } switch_core_session_unset_read_codec(session); switch_core_session_unset_write_codec(session); ftdm_channel_close(&tech_pvt->ftdm_channel); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) { crtp_private_t *tech_pvt; switch_channel_t *channel; //int frames = 0, bytes = 0, samples = 0; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); #if 0 if (!switch_test_flag(frame, SFF_CNG) && !switch_test_flag(frame, SFF_PROXY_PACKET)) { if (tech_pvt->read_codec.implementation->encoded_bytes_per_packet) { bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_packet; frames = ((int) frame->datalen / bytes); } else frames = 1; samples = frames * tech_pvt->read_codec.implementation->samples_per_packet; } tech_pvt->timestamp_send += samples; #endif if (tech_pvt->mode == RTP_RECVONLY) { return SWITCH_STATUS_SUCCESS; } switch_rtp_write_frame(tech_pvt->rtp_session, frame); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch (sig) { case SWITCH_SIG_BREAK: break; case SWITCH_SIG_KILL: tech_pvt->dead = 1; break; default: break; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel)); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) { private_t *tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); switch_clear_flag_locked(tech_pvt, TFLAG_LINKED); switch_mutex_lock(tech_pvt->mutex); if (tech_pvt->other_tech_pvt) { switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_LINKED); tech_pvt->other_tech_pvt = NULL; } if (tech_pvt->other_session) { switch_channel_hangup(tech_pvt->other_channel, switch_channel_get_cause(channel)); switch_core_session_rwunlock(tech_pvt->other_session); tech_pvt->other_channel = NULL; tech_pvt->other_session = NULL; } switch_mutex_unlock(tech_pvt->mutex); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch (sig) { case SWITCH_SIG_KILL: switch_clear_flag_locked(tech_pvt, TFLAG_IO); switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); //switch_thread_cond_signal(tech_pvt->cond); break; case SWITCH_SIG_BREAK: switch_set_flag_locked(tech_pvt, TFLAG_BREAK); break; default: break; } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch_clear_flag_locked(tech_pvt, TFLAG_IO); switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); //switch_thread_cond_signal(tech_pvt->cond); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); switch_mutex_lock(globals.mutex); globals.calls--; if (globals.calls < 0) { globals.calls = 0; } switch_mutex_unlock(globals.mutex); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_routing(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; const char *app, *arg; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); do_reset(tech_pvt); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(channel)); if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && (app = switch_channel_get_variable(channel, "loopback_app"))) { switch_caller_extension_t *extension = NULL; arg = switch_channel_get_variable(channel, "loopback_app_arg"); extension = switch_caller_extension_new(session, app, app); switch_caller_extension_add_application(session, extension, "pre_answer", NULL); switch_caller_extension_add_application(session, extension, app, arg); switch_channel_set_caller_extension(channel, extension); switch_channel_set_state(channel, CS_EXECUTE); return SWITCH_STATUS_FALSE; } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_destroy(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; void *pop; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); if (tech_pvt) { switch_core_timer_destroy(&tech_pvt->timer); if (switch_core_codec_ready(&tech_pvt->read_codec)) { switch_core_codec_destroy(&tech_pvt->read_codec); } if (switch_core_codec_ready(&tech_pvt->write_codec)) { switch_core_codec_destroy(&tech_pvt->write_codec); } if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } while (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { switch_frame_t *frame = (switch_frame_t *) pop; switch_frame_free(&frame); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch (sig) { case SWITCH_SIG_BREAK: break; case SWITCH_SIG_KILL: switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); switch_clear_flag_locked(tech_pvt, TFLAG_LINKED); switch_mutex_lock(tech_pvt->mutex); if (tech_pvt->other_tech_pvt) { switch_clear_flag_locked(tech_pvt->other_tech_pvt, TFLAG_LINKED); } switch_mutex_unlock(tech_pvt->mutex); break; default: break; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel)); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; //switch_frame_t *pframe; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); if (!switch_test_flag(tech_pvt, TFLAG_IO)) { return SWITCH_STATUS_FALSE; } #if SWITCH_BYTE_ORDER == __BIG_ENDIAN if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { switch_swap_linear(frame->data, (int) frame->datalen / 2); } #endif return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_destroy(switch_core_session_t *session) { crtp_private_t *tech_pvt = switch_core_session_get_private(session); if ((tech_pvt = switch_core_session_get_private(session))) { if (tech_pvt->read_codec.implementation) { switch_core_codec_destroy(&tech_pvt->read_codec); } if (tech_pvt->write_codec.implementation) { switch_core_codec_destroy(&tech_pvt->write_codec); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_hibernate(switch_core_session_t *session) { switch_assert(switch_core_session_get_private(session)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s HIBERNATE\n", switch_channel_get_name(switch_core_session_get_channel(session))); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; //switch_time_t started = switch_time_now(); //unsigned int elapsed; switch_byte_t *data; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); tech_pvt->read_frame.flags = SFF_NONE; *frame = NULL; while (switch_test_flag(tech_pvt, TFLAG_IO)) { if (switch_test_flag(tech_pvt, TFLAG_BREAK)) { switch_clear_flag(tech_pvt, TFLAG_BREAK); goto cng; } if (!switch_test_flag(tech_pvt, TFLAG_IO)) { return SWITCH_STATUS_FALSE; } if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); if (!tech_pvt->read_frame.datalen) { continue; } *frame = &tech_pvt->read_frame; #if SWITCH_BYTE_ORDER == __BIG_ENDIAN if (switch_test_flag(tech_pvt, TFLAG_LINEAR)) { switch_swap_linear((*frame)->data, (int) (*frame)->datalen / 2); } #endif return SWITCH_STATUS_SUCCESS; } switch_cond_next(); } return SWITCH_STATUS_FALSE; cng: data = (switch_byte_t *) tech_pvt->read_frame.data; data[0] = 65; data[1] = 0; tech_pvt->read_frame.datalen = 2; tech_pvt->read_frame.flags = SFF_CNG; *frame = &tech_pvt->read_frame; return SWITCH_STATUS_SUCCESS; }
static switch_status_t loopback_bowout_on_execute_state_handler(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_state_t state = switch_channel_get_state(channel); private_t *tech_pvt = NULL; if (state == CS_EXECUTE) { const char *uuid; switch_core_session_t *other_session = NULL; switch_channel_t *b_channel = NULL; tech_pvt = switch_core_session_get_private(session); if (switch_core_session_read_lock(tech_pvt->other_session) == SWITCH_STATUS_SUCCESS) { b_channel = switch_core_session_get_channel(tech_pvt->other_session); /* Wait for b_channel to be fully bridged */ switch_channel_wait_for_flag(b_channel, CF_BRIDGED, SWITCH_TRUE, 5000, NULL); uuid = switch_channel_get_partner_uuid(b_channel); if (uuid && (other_session = switch_core_session_locate(uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_caller_profile_t *cp, *clone; switch_channel_wait_for_state(other_channel, NULL, CS_EXCHANGE_MEDIA); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->other_session), SWITCH_LOG_INFO, "Replacing loopback channel: %s with real channel: %s\n", switch_channel_get_name(b_channel), switch_channel_get_name(other_channel)); if ((cp = switch_channel_get_caller_profile(channel))) { clone = switch_caller_profile_clone(other_session, cp); clone->originator_caller_profile = NULL; clone->originatee_caller_profile = NULL; switch_channel_set_caller_profile(other_channel, clone); } switch_channel_caller_extension_masquerade(channel, other_channel, 0); switch_channel_set_state(other_channel, CS_RESET); switch_channel_wait_for_state(other_channel, NULL, CS_RESET); switch_channel_set_variable(channel, "process_cdr", "false"); switch_channel_set_variable(b_channel, "process_cdr", "false"); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); switch_channel_set_state(other_channel, CS_EXECUTE); switch_core_session_rwunlock(other_session); } switch_core_session_rwunlock(tech_pvt->other_session); } switch_core_event_hook_remove_state_change(session, loopback_bowout_on_execute_state_handler); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_reset(switch_core_session_t *session) { private_t *tech_pvt = (private_t *) switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); do_reset(tech_pvt); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s RESET\n", switch_channel_get_name(switch_core_session_get_channel(session))); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event) { struct private_object *tech_pvt = switch_core_session_get_private(session); char *body = switch_event_get_body(event); switch_assert(tech_pvt != NULL); if (!body) { body = ""; } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_routing(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) { private_t *tech_pvt = NULL; tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); if (tech_pvt->other_channel) { switch_channel_queue_dtmf(tech_pvt->other_channel, dtmf); } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf) { ctdm_private_t *tech_pvt = NULL; char tmp[2] = ""; tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); tmp[0] = dtmf->digit; ftdm_channel_command(tech_pvt->ftdm_channel, FTDM_COMMAND_SEND_DTMF, tmp); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_exchange_media(switch_core_session_t *session) { switch_channel_t *channel = NULL; loopback_private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CHANNEL LOOPBACK\n"); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_execute(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); return SWITCH_STATUS_SUCCESS; }
uint8_t sofia_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp) { uint8_t t, p = 0; private_object_t *tech_pvt = switch_core_session_get_private(session); if ((t = switch_core_media_negotiate_sdp(session, r_sdp, &p))) { sofia_set_flag_locked(tech_pvt, TFLAG_SDP); } if (!p) { sofia_set_flag(tech_pvt, TFLAG_NOREPLY); } return t; }
static switch_status_t channel_on_consume_media(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "CHANNEL CONSUME_MEDIA\n"); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_on_execute(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_caller_extension_t *exten; int bow = 0; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel)); if ((exten = switch_channel_get_caller_extension(channel))) { switch_caller_application_t *app_p; for (app_p = exten->applications; app_p; app_p = app_p->next) { int32_t flags; switch_core_session_get_app_flags(app_p->application_name, &flags); if ((flags & SAF_NO_LOOPBACK)) { bow = 1; break; } } } if (bow) { switch_core_session_t *other_session; const char *other_uuid; if ((find_non_loopback_bridge(tech_pvt->other_session, &other_session, &other_uuid) == SWITCH_STATUS_SUCCESS)) { switch_caller_extension_t *extension; switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_caller_extension_clone(&extension, exten, switch_core_session_get_pool(other_session)); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_INFO, "BOWOUT Transfering current extension to non-loopback leg.\n"); switch_channel_transfer_to_extension(other_channel, extension); switch_core_session_rwunlock(other_session); } } return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id) { ftdm_wait_flag_t wflags = FTDM_WRITE; ctdm_private_t *tech_pvt; const char *name; switch_channel_t *channel; uint32_t span_id, chan_id; ftdm_size_t len; unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); span_id = ftdm_channel_get_span_id(tech_pvt->ftdm_channel); chan_id = ftdm_channel_get_id(tech_pvt->ftdm_channel); name = switch_channel_get_name(channel); if (switch_test_flag(frame, SFF_CNG)) { frame->data = data; frame->buflen = sizeof(data); if ((frame->datalen = tech_pvt->write_codec.implementation->encoded_bytes_per_packet) > frame->buflen) { goto fail; } memset(data, 255, frame->datalen); } wflags = FTDM_WRITE; ftdm_channel_wait(tech_pvt->ftdm_channel, &wflags, ftdm_channel_get_io_interval(tech_pvt->ftdm_channel) * 10); if (!(wflags & FTDM_WRITE)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Dropping frame! (write not ready) in channel %s device %d:%d!\n", name, span_id, chan_id); return SWITCH_STATUS_SUCCESS; } len = frame->datalen; if (ftdm_channel_write(tech_pvt->ftdm_channel, frame->data, frame->buflen, &len) != FTDM_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Failed to write to channel %s device %d:%d!\n", name, span_id, chan_id); } return SWITCH_STATUS_SUCCESS; fail: return SWITCH_STATUS_GENERR; }
static switch_status_t channel_on_hangup(switch_core_session_t *session) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel)); t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_HANGUP); return SWITCH_STATUS_SUCCESS; }
/* State methods they get called when the state changes to the specific state returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it. */ static switch_status_t channel_on_init(switch_core_session_t *session) { switch_channel_t *channel; private_t *tech_pvt = NULL; tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); channel = switch_core_session_get_channel(session); assert(channel != NULL); switch_set_flag_locked(tech_pvt, TFLAG_IO); switch_mutex_lock(globals.mutex); globals.calls++; switch_mutex_unlock(globals.mutex); return SWITCH_STATUS_SUCCESS; }
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; int r, samples_wanted, samples_read = 0; int16_t *data; channel = switch_core_session_get_channel(session); switch_assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); switch_assert(tech_pvt != NULL); if (tech_pvt->dead) return SWITCH_STATUS_FALSE; data = tech_pvt->read_frame.data; samples_wanted = tech_pvt->read_codec.implementation->samples_per_packet; tech_pvt->read_frame.flags = SFF_NONE; switch_core_timer_next(&tech_pvt->timer); do { r = t31_tx(tech_pvt->modem->t31_state, data + samples_read, samples_wanted - samples_read); if (r < 0) break; samples_read += r; } while(samples_read < samples_wanted && r > 0); if (r < 0) { return SWITCH_STATUS_FALSE; } else if (samples_read < samples_wanted) { memset(data + samples_read, 0, sizeof(int16_t)*(samples_wanted - samples_read)); samples_read = samples_wanted; } tech_pvt->read_frame.samples = samples_read; tech_pvt->read_frame.datalen = samples_read * 2; *frame = &tech_pvt->read_frame; return status; }
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { crtp_private_t *tech_pvt; switch_channel_t *channel; switch_status_t status; channel = switch_core_session_get_channel(session); assert(channel != NULL); tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); if (!tech_pvt->rtp_session || tech_pvt->mode == RTP_SENDONLY) { switch_yield(20000); /* replace by local timer XXX */ goto cng; } if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) { switch_dtmf_t dtmf = { 0 }; switch_rtp_dequeue_dtmf(tech_pvt->rtp_session, &dtmf); switch_channel_queue_dtmf(channel, &dtmf); } tech_pvt->read_frame.flags = SFF_NONE; tech_pvt->read_frame.codec = &tech_pvt->read_codec; status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame, flags); if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto cng; } *frame = &tech_pvt->read_frame; return SWITCH_STATUS_SUCCESS; cng: *frame = &tech_pvt->read_frame; tech_pvt->read_frame.codec = &tech_pvt->read_codec; tech_pvt->read_frame.flags |= SFF_CNG; tech_pvt->read_frame.datalen = 0; return SWITCH_STATUS_SUCCESS; }