提交 fea30084 authored 作者: Marc Olivier Chouinard's avatar Marc Olivier Chouinard

Merge branch 'master' of ssh://git.freeswitch.org/freeswitch

......@@ -320,7 +320,7 @@ export QA_RPATHS=$[ 0x0001|0x0002 ]
# Application Modules
#
###############################################################################################################################
APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr"
APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr applications/mod_callcenter"
APPLICATION_MODULES_FM="applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_lcr applications/mod_limit applications/mod_memcache"
......@@ -595,6 +595,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/mime.types
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/acl.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/alsa.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/callcenter.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_csv.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_pg_csv.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cidlookup.conf.xml
......@@ -741,6 +742,7 @@ fi
%{prefix}/mod/mod_event_multicast.so*
%{prefix}/mod/mod_event_socket.so*
%{prefix}/mod/mod_expr.so*
%{prefix}/mod/mod_callcenter.so*
%{prefix}/mod/mod_fifo.so*
%{prefix}/mod/mod_file_string.so*
%{prefix}/mod/mod_flite.so*
......
......@@ -2261,11 +2261,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
return FTDM_FAIL;
}
if (!ftdm_test_flag(check, FTDM_CHANNEL_INUSE)) {
ftdm_log(FTDM_LOG_WARNING, "Called ftdm_channel_close but never ftdm_channel_open in chan %d:%d??\n", check->span_id, check->chan_id);
return FTDM_FAIL;
}
if (ftdm_test_flag(check, FTDM_CHANNEL_CONFIGURED)) {
ftdm_mutex_lock(check->mutex);
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
......@@ -2275,6 +2270,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
ftdm_channel_reset(check);
*ftdmchan = NULL;
}
} else {
ftdm_log_chan_msg(check, FTDM_LOG_WARNING, "Called ftdm_channel_close but never ftdm_channel_open??\n");
}
check->ring_count = 0;
ftdm_mutex_unlock(check->mutex);
......
......@@ -483,8 +483,6 @@ static switch_status_t do_billing(switch_core_session_t *session)
/* Setup new billing data (based on call answer time, in case this module started late with active calls) */
nibble_data->lastts = profile->times->answered; /* Set the initial answer time to match when the call was really answered */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Beginning new billing on %s\n", uuid);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Last successful billing time was %s\n", date);
}
switch_time_exp_lt(&tm, nibble_data->lastts);
......
......@@ -126,6 +126,9 @@ struct codec_data {
long lastrxseqno;
unsigned long rxlost;
/* discarded silence packets */
unsigned long rxdiscarded;
/* avg Rx time */
switch_time_t avgrxus;
switch_time_t last_rx_time;
......@@ -400,26 +403,31 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec
sess->encoder.tx++;
/* do the reading */
memset(&encoded_frame, 0, sizeof(encoded_frame));
sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK);
if (sres == SWITCH_STATUS_GENERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres);
return SWITCH_STATUS_FALSE;
}
for ( ; ; ) {
sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK);
if (sres == SWITCH_STATUS_GENERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres);
return SWITCH_STATUS_FALSE;
}
if (0 == encoded_frame.datalen) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on Sangoma encoder RTP session.\n");
return SWITCH_STATUS_SUCCESS;
}
if (0 == encoded_frame.datalen) {
break;
}
if (encoded_frame.payload != codec->implementation->ianacode
&& encoded_frame.payload != IANACODE_CN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n",
encoded_frame.payload, codec->implementation->ianacode);
return SWITCH_STATUS_FALSE;
if (encoded_frame.payload != codec->implementation->ianacode
&& encoded_frame.payload != IANACODE_CN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n",
encoded_frame.payload, codec->implementation->ianacode);
break;
}
if (*encoded_data_len) {
sess->encoder.rxdiscarded++;
}
memcpy(encoded_data, encoded_frame.data, encoded_frame.datalen);
*encoded_data_len = encoded_frame.datalen;
}
memcpy(encoded_data, encoded_frame.data, encoded_frame.datalen);
*encoded_data_len = encoded_frame.datalen;
/* update encoding stats */
sess->encoder.rx++;
......@@ -513,30 +521,34 @@ static switch_status_t switch_sangoma_decode(switch_codec_t *codec, /* codec ses
sess->decoder.tx++;
/* do the reading */
memset(&ulaw_frame, 0, sizeof(ulaw_frame));
sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &ulaw_frame, SWITCH_IO_FLAG_NOBLOCK);
if (sres == SWITCH_STATUS_GENERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma decoder RTP session: %d\n", sres);
return SWITCH_STATUS_FALSE;
}
for ( ; ; ) {
sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &ulaw_frame, SWITCH_IO_FLAG_NOBLOCK);
if (sres == SWITCH_STATUS_GENERR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma decoder RTP session: %d\n", sres);
return SWITCH_STATUS_FALSE;
}
if (0 == ulaw_frame.datalen) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No output on Sangoma decoder RTP session.\n");
return SWITCH_STATUS_SUCCESS;
}
if (0 == ulaw_frame.datalen) {
break;
}
if (ulaw_frame.payload != IANA_ULAW
&& ulaw_frame.payload != IANACODE_CN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma decoder RTP session, expecting %d\n",
ulaw_frame.payload, IANA_ULAW);
return SWITCH_STATUS_FALSE;
}
if (ulaw_frame.payload != IANA_ULAW
&& ulaw_frame.payload != IANACODE_CN) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma decoder RTP session, expecting %d\n",
ulaw_frame.payload, IANA_ULAW);
break;
}
/* transcode to linear */
for (i = 0; i < ulaw_frame.datalen; i++) {
dbuf_linear[i] = ulaw_to_linear(((char *)ulaw_frame.data)[i]);
if (*decoded_data_len) {
sess->decoder.rxdiscarded++;
}
/* transcode to linear */
for (i = 0; i < ulaw_frame.datalen; i++) {
dbuf_linear[i] = ulaw_to_linear(((char *)ulaw_frame.data)[i]);
}
*decoded_data_len = i * 2;
}
*decoded_data_len = i * 2;
/* update decoding stats */
sess->decoder.rx++;
......@@ -708,6 +720,7 @@ SWITCH_STANDARD_API(sangoma_function)
if (sess->encoder.rxrtp) {
stats = switch_rtp_get_stats(sess->encoder.rxrtp, NULL);
stream->write_function(stream, "-- Encoder Inbound Stats --\n");
stream->write_function(stream, "Rx Discarded: %lu\n", sess->encoder.rxdiscarded);
sangoma_print_stats(stream, &stats->inbound);
......@@ -719,6 +732,7 @@ SWITCH_STANDARD_API(sangoma_function)
if (sess->decoder.rxrtp) {
stats = switch_rtp_get_stats(sess->decoder.rxrtp, NULL);
stream->write_function(stream, "-- Decoder Inbound Stats --\n");
stream->write_function(stream, "Rx Discarded: %lu\n", sess->decoder.rxdiscarded);
sangoma_print_stats(stream, &stats->inbound);
stats = switch_rtp_get_stats(sess->decoder.txrtp, NULL);
......
......@@ -264,6 +264,7 @@ struct private_object {
char skype_password[256];
char destination[256];
struct timeval answer_time;
struct timeval ring_time;
struct timeval transfer_time;
char transfer_callid_number[50];
......@@ -288,6 +289,10 @@ struct private_object {
int silent_mode;
int write_silence_when_idle;
int setsockopt;
char answer_id[256];
char answer_value[256];
char ring_id[256];
char ring_value[256];
};
......@@ -328,7 +333,8 @@ int skypopen_close_socket(unsigned int fd);
private_t *find_available_skypopen_interface_rr(private_t * tech_pvt_calling);
int remote_party_is_ringing(private_t * tech_pvt);
int remote_party_is_early_media(private_t * tech_pvt);
int skypopen_answer(private_t * tech_pvt, char *id, char *value);
//int skypopen_answer(private_t * tech_pvt, char *id, char *value);
int skypopen_answer(private_t * tech_pvt);
int skypopen_transfer(private_t * tech_pvt, char *id, char *value);
#ifndef WIN32
int skypopen_socket_create_and_bind(private_t * tech_pvt, int *which_port);
......@@ -337,3 +343,6 @@ int skypopen_socket_create_and_bind(private_t * tech_pvt, unsigned short *which_
#endif //WIN32
int incoming_chatmessage(private_t * tech_pvt, int which);
int next_port(void);
int skypopen_partner_handle_ring(private_t * tech_pvt);
int skypopen_answered(private_t * tech_pvt);
int inbound_channel_answered(private_t * tech_pvt);
......@@ -214,7 +214,7 @@ int skypopen_signaling_read(private_t * tech_pvt)
ERRORA("Skype got ERROR: |||%s|||, another call is active on this interface\n\n\n", SKYPOPEN_P_LOG, message);
tech_pvt->interface_state = SKYPOPEN_STATE_ERROR_DOUBLE_CALL;
} else if (!strncasecmp(message, "ERROR 592 ALTER CALL", 19)) {
ERRORA("Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n", SKYPOPEN_P_LOG, message);
NOTICA("Skype got ERROR about TRANSFERRING, no problem: |||%s|||\n", SKYPOPEN_P_LOG, message);
} else if (!strncasecmp(message, "ERROR 559 CALL", 13)) {
if (tech_pvt->interface_state == SKYPOPEN_STATE_PREANSWER) {
DEBUGA_SKYPE("Skype got ERROR about a failed action (probably TRYING to ANSWER A CALL), let's go down: |||%s|||\n", SKYPOPEN_P_LOG,
......@@ -478,8 +478,12 @@ int skypopen_signaling_read(private_t * tech_pvt)
if (!strcasecmp(prop, "PARTNER_HANDLE")) {
if (tech_pvt->interface_state != SKYPOPEN_STATE_SELECTED && (!strlen(tech_pvt->skype_call_id) || !strlen(tech_pvt->session_uuid_str))) {
/* we are NOT inside an active call */
DEBUGA_SKYPE("Call %s TRY ANSWER\n", SKYPOPEN_P_LOG, id);
skypopen_answer(tech_pvt, id, value);
DEBUGA_SKYPE("Call %s go to skypopen_partner_handle_ring\n", SKYPOPEN_P_LOG, id);
skypopen_strncpy(tech_pvt->ring_id, id, sizeof(tech_pvt->ring_id));
skypopen_strncpy(tech_pvt->ring_value, value, sizeof(tech_pvt->ring_value));
skypopen_strncpy(tech_pvt->answer_id, id, sizeof(tech_pvt->answer_id));
skypopen_strncpy(tech_pvt->answer_value, value, sizeof(tech_pvt->answer_value));
skypopen_partner_handle_ring(tech_pvt);
} else {
/* we are inside an active call */
if (!strcasecmp(tech_pvt->skype_call_id, id)) {
......@@ -553,7 +557,10 @@ int skypopen_signaling_read(private_t * tech_pvt)
&& (!strlen(tech_pvt->skype_call_id) || !strlen(tech_pvt->session_uuid_str))) {
/* we are NOT inside an active call */
DEBUGA_SKYPE("NO ACTIVE calls in this moment, skype_call %s is RINGING, to ask PARTNER_HANDLE\n", SKYPOPEN_P_LOG, id);
DEBUGA_SKYPE("NO ACTIVE calls in this moment, skype_call %s is RINGING, to ask PARTNER_DISPNAME and PARTNER_HANDLE\n", SKYPOPEN_P_LOG, id);
sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id);
skypopen_signaling_write(tech_pvt, msg_to_skype);
skypopen_sleep(100);
sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id);
skypopen_signaling_write(tech_pvt, msg_to_skype);
skypopen_sleep(10000);
......@@ -684,14 +691,7 @@ int skypopen_signaling_read(private_t * tech_pvt)
skypopen_signaling_write(tech_pvt, msg_to_skype);
}
tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS;
if (!strlen(tech_pvt->session_uuid_str)) {
DEBUGA_SKYPE("New Inbound Channel!\n\n\n\n", SKYPOPEN_P_LOG);
new_inbound_channel(tech_pvt);
} else {
tech_pvt->interface_state = SKYPOPEN_STATE_UP;
DEBUGA_SKYPE("Outbound Channel Answered! session_uuid_str=%s\n", SKYPOPEN_P_LOG, tech_pvt->session_uuid_str);
outbound_channel_answered(tech_pvt);
}
skypopen_answered(tech_pvt);
} else {
DEBUGA_SKYPE("I'm on %s, skype_call %s is NOT MY call, ignoring\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id);
}
......@@ -1752,3 +1752,61 @@ while(XPending(disp)){
}
#endif // WIN32
int inbound_channel_answered(private_t * tech_pvt)
{
int res = 0;
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
if (channel) {
switch_set_flag(tech_pvt, TFLAG_IO);
} else {
ERRORA("no channel\n", SKYPOPEN_P_LOG);
}
switch_core_session_rwunlock(session);
} else {
ERRORA("no session\n", SKYPOPEN_P_LOG);
}
return res;
}
int skypopen_answered(private_t * tech_pvt)
{
int res = 0;
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
//WARNINGA("ANSWERED tech_pvt->skype_call_id=%s, tech_pvt->skype_callflow=%d, tech_pvt->interface_state=%d, tech_pvt->skype_user=%s, tech_pvt->callid_number=%s, tech_pvt->ring_value=%s, tech_pvt->ring_id=%s, tech_pvt->answer_value=%s, tech_pvt->answer_id=%s\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, tech_pvt->skype_callflow, tech_pvt->interface_state, tech_pvt->skype_user, tech_pvt->callid_number, tech_pvt->ring_value, tech_pvt->ring_id, tech_pvt->answer_value, tech_pvt->answer_id);
session = switch_core_session_locate(tech_pvt->session_uuid_str);
if (session) {
channel = switch_core_session_get_channel(session);
if (channel) {
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
tech_pvt->interface_state = SKYPOPEN_STATE_UP;
DEBUGA_SKYPE("Outbound Channel Answered! session_uuid_str=%s\n", SKYPOPEN_P_LOG, tech_pvt->session_uuid_str);
outbound_channel_answered(tech_pvt);
} else {
DEBUGA_SKYPE("answered Inbound Channel!\n\n\n\n", SKYPOPEN_P_LOG);
inbound_channel_answered(tech_pvt);
}
} else {
ERRORA("no channel\n", SKYPOPEN_P_LOG);
}
switch_core_session_rwunlock(session);
} else {
ERRORA("no session\n", SKYPOPEN_P_LOG);
}
return res;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论