static switch_status_t channel_on_init(switch_core_session_t *session);
static switch_status_t channel_on_hangup(switch_core_session_t *session);
+static switch_status_t channel_on_reset(switch_core_session_t *session);
static switch_status_t channel_on_destroy(switch_core_session_t *session);
static switch_status_t channel_on_routing(switch_core_session_t *session);
static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
where a destination has been identified. If the channel is simply
left in the initial state, nothing will happen. */
switch_channel_set_state(channel, CS_ROUTING);
- switch_mutex_lock(globals.mutex);
- globals.calls++;
-
- switch_mutex_unlock(globals.mutex);
DEBUGA_SKYPE("%s CHANNEL INIT %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session));
return SWITCH_STATUS_SUCCESS;
DEBUGA_SKYPE("%s CHANNEL SOFT_EXECUTE\n", SKYPOPEN_P_LOG, tech_pvt->name);
return SWITCH_STATUS_SUCCESS;
}
+static switch_status_t channel_on_reset(switch_core_session_t *session)
+{
+ private_t *tech_pvt = NULL;
+ switch_channel_t *channel = NULL;
+ tech_pvt = switch_core_session_get_private(session);
+ DEBUGA_SKYPE("%s CHANNEL RESET\n", SKYPOPEN_P_LOG, tech_pvt->name);
+
+
+ if (session) {
+ channel = switch_core_session_get_channel(session);
+ } else {
+ ERRORA("No session???\n", SKYPOPEN_P_LOG);
+ }
+ if (channel) {
+ switch_channel_set_state(channel, CS_HANGUP);
+ } else {
+ ERRORA("No channel???\n", SKYPOPEN_P_LOG);
+ }
+
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
{
tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL);
- if (!switch_channel_ready(channel) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
+ if (!switch_channel_ready(channel)) {
ERRORA("channel not ready \n", SKYPOPEN_P_LOG);
return SWITCH_STATUS_FALSE;
}
+ if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
+ DEBUGA_SKYPE("channel not in TFLAG_IO \n", SKYPOPEN_P_LOG);
+ 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);
tech_pvt = switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL);
+ switch_clear_flag(tech_pvt, TFLAG_IO);
+ skypopen_answer(tech_pvt);
+
+ while(!switch_test_flag(tech_pvt, TFLAG_IO)){ //FIXME that would be better with a timeout
+ if(switch_channel_get_state(channel) == CS_RESET){
+ return SWITCH_STATUS_FALSE;
+ }
+ switch_sleep(5000);
+ }
+ switch_mutex_lock(globals.mutex);
+ globals.calls++;
+
+ switch_mutex_unlock(globals.mutex);
+ DEBUGA_SKYPE("%s CHANNEL ANSWER %s\n", SKYPOPEN_P_LOG, tech_pvt->name, switch_core_session_get_uuid(session));
+
+
+
+
DEBUGA_SKYPE("ANSWERED! \n", SKYPOPEN_P_LOG);
return SWITCH_STATUS_SUCCESS;
/*.on_soft_execute */ channel_on_soft_execute,
/*.on_consume_media */ channel_on_consume_media,
/*.on_hibernate */ NULL,
- /*.on_reset */ NULL,
+ /*.on_reset */ channel_on_reset,
/*.on_park */ NULL,
/*.on_reporting */ NULL,
/*.on_destroy */ channel_on_destroy
*tech_pvt->session_uuid_str = '\0';
*tech_pvt->skype_call_id = '\0';
*tech_pvt->initial_skype_user = '\0';
+ *tech_pvt->answer_id = '\0';
+ *tech_pvt->answer_value = '\0';
+ *tech_pvt->ring_id = '\0';
+ *tech_pvt->ring_value = '\0';
+ *tech_pvt->callid_number = '\0';
+ *tech_pvt->callid_name = '\0';
switch_mutex_unlock(globals.mutex);
switch_sleep(300000); //0.3 sec
}
}
if (channel) {
- switch_channel_mark_answered(channel);
switch_channel_set_variable(channel, "skype_user", tech_pvt->skype_user);
switch_channel_set_variable(channel, "initial_skype_user", tech_pvt->initial_skype_user);
}
return SWITCH_STATUS_SUCCESS;
}
-int skypopen_answer(private_t * tech_pvt, char *id, char *value)
+
+int skypopen_partner_handle_ring(private_t * tech_pvt)
{
char msg_to_skype[1024];
int i;
int found = 0;
private_t *giovatech;
struct timeval timenow;
+ char *id = tech_pvt->ring_id;
+ char *value = tech_pvt->ring_value;
+ switch_core_session_t *session = NULL;
+ switch_channel_t *channel = NULL;
switch_mutex_lock(globals.mutex);
+ //WARNINGA("PARTNER_HANDLE 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);
+
gettimeofday(&timenow, NULL);
for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) {
if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) {
giovatech = &globals.SKYPOPEN_INTERFACES[i];
- if (strlen(giovatech->skype_call_id) && (giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 1000000)) { //XXX 1.5sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.5 seconds
+ if ((giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->ring_value, value)) && ((((timenow.tv_sec - giovatech->ring_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->ring_time.tv_usec)) < 1000000)) { //XXX 1.0sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.0 seconds
found = 1;
- DEBUGA_SKYPE
- ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n",
- SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state,
- giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, value)
- if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) {
+ DEBUGA_SKYPE ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, value);
+ if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) {
tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
} else if (tech_pvt->interface_state != 0 && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN) {
WARNINGA("Why an interface_state %d HERE?\n", SKYPOPEN_P_LOG, tech_pvt->interface_state);
tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
}
+ *tech_pvt->answer_id = '\0';
+ *tech_pvt->answer_value = '\0';
+ *tech_pvt->ring_id = '\0';
+ *tech_pvt->ring_value = '\0';
break;
}
}
if (tech_pvt && tech_pvt->skype_call_id && !strlen(tech_pvt->skype_call_id)) {
/* we are not inside an active call */
- tech_pvt->ib_calls++;
+ tech_pvt->interface_state = SKYPOPEN_STATE_PRERING;
+ gettimeofday(&tech_pvt->ring_time, NULL);
+ switch_copy_string(tech_pvt->callid_number, value, sizeof(tech_pvt->callid_number) - 1);
+
+
+ //WARNINGA("PARTNER_HANDLE_RING 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) {
+ switch_core_session_rwunlock(session);
+ return 0;
+ }
+
+ new_inbound_channel(tech_pvt);
+
+ session = switch_core_session_locate(tech_pvt->session_uuid_str);
+ if (session) {
+ channel = switch_core_session_get_channel(session);
+
+ switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
+ if (channel) {
+ switch_channel_mark_ring_ready(channel);
+ } else {
+ ERRORA("no channel\n", SKYPOPEN_P_LOG);
+ }
+ switch_core_session_rwunlock(session);
+ } else {
+ ERRORA("no session\n", SKYPOPEN_P_LOG);
- sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id);
+ }
+
+ } else if (!tech_pvt || !tech_pvt->skype_call_id) {
+ ERRORA("No Call ID?\n", SKYPOPEN_P_LOG);
+ } else {
+ DEBUGA_SKYPE("We're in a call now (%s), let's refuse this one (%s)\n", SKYPOPEN_P_LOG, tech_pvt->skype_call_id, id);
+ sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id);
skypopen_signaling_write(tech_pvt, msg_to_skype);
- switch_sleep(10000);
+ }
+
+ switch_mutex_unlock(globals.mutex);
+ return 0;
+}
+
+int skypopen_answer(private_t * tech_pvt)
+{
+ char msg_to_skype[1024];
+ int i;
+ int found = 0;
+ private_t *giovatech;
+ struct timeval timenow;
+ char *id = tech_pvt->answer_id;
+ char *value = tech_pvt->answer_value;
+ switch_core_session_t *session = NULL;
+ switch_channel_t *channel = NULL;
+
+ switch_mutex_lock(globals.mutex);
+
+ //WARNINGA("ANSWER 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);
+
+ gettimeofday(&timenow, NULL);
+ for (i = 0; !found && i < SKYPOPEN_MAX_INTERFACES; i++) {
+ if (strlen(globals.SKYPOPEN_INTERFACES[i].name)) {
+
+ giovatech = &globals.SKYPOPEN_INTERFACES[i];
+ if (strlen(giovatech->skype_call_id) && (giovatech->interface_state != SKYPOPEN_STATE_DOWN) && (!strcmp(giovatech->skype_user, tech_pvt->skype_user)) && (!strcmp(giovatech->callid_number, value)) && ((((timenow.tv_sec - giovatech->answer_time.tv_sec) * 1000000) + (timenow.tv_usec - giovatech->answer_time.tv_usec)) < 1000000)) { //XXX 1.0sec - can have a max of 1 call coming from the same skypename to the same skypename each 1.0 seconds
+ found = 1;
+ DEBUGA_SKYPE ("FOUND (name=%s, giovatech->interface_state=%d != SKYPOPEN_STATE_DOWN) && (giovatech->skype_user=%s == tech_pvt->skype_user=%s) && (giovatech->callid_number=%s == value=%s)\n", SKYPOPEN_P_LOG, giovatech->name, giovatech->interface_state, giovatech->skype_user, tech_pvt->skype_user, giovatech->callid_number, value);
+ if (tech_pvt->interface_state == SKYPOPEN_STATE_PRERING) {
+ tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
+ } else if (tech_pvt->interface_state != 0 && tech_pvt->interface_state != SKYPOPEN_STATE_DOWN) {
+ WARNINGA("Why an interface_state %d HERE?\n", SKYPOPEN_P_LOG, tech_pvt->interface_state);
+ tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
+ }
+
+
+ if (!zstr(tech_pvt->session_uuid_str)) {
+ session = switch_core_session_locate(tech_pvt->session_uuid_str);
+ } else {
+ ERRORA("No session???\n", SKYPOPEN_P_LOG);
+ }
+ if (session) {
+ channel = switch_core_session_get_channel(session);
+ } else {
+ ERRORA("No session???\n", SKYPOPEN_P_LOG);
+ }
+ if (channel) {
+ switch_channel_set_state(channel, CS_RESET);
+ } else {
+ ERRORA("No channel???\n", SKYPOPEN_P_LOG);
+ }
+
+ switch_core_session_rwunlock(session);
+
+ break;
+ }
+ }
+ }
+
+ if (found) {
+ switch_mutex_unlock(globals.mutex);
+ return 0;
+ }
+ DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG);
+
+ if (tech_pvt && tech_pvt->skype_call_id && !strlen(tech_pvt->skype_call_id)) {
+ /* we are not inside an active call */
+
+ tech_pvt->ib_calls++;
+
tech_pvt->interface_state = SKYPOPEN_STATE_PREANSWER;
sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id);
skypopen_signaling_write(tech_pvt, msg_to_skype);
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,
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)) {
&& (!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);
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);
}
}
#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;
+}