]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
skypopen: now answer a call only when directed to do it (before was trying to answer...
authorGiovanni Maruzzelli <gmaruzz@gmail.com>
Fri, 13 Aug 2010 21:19:20 +0000 (16:19 -0500)
committerGiovanni Maruzzelli <gmaruzz@gmail.com>
Fri, 13 Aug 2010 21:20:09 +0000 (16:20 -0500)
Signed-off-by: Giovanni Maruzzelli <gmaruzz@gmail.com>
src/mod/endpoints/mod_skypopen/mod_skypopen.c
src/mod/endpoints/mod_skypopen/skypopen.h
src/mod/endpoints/mod_skypopen/skypopen_protocol.c

index 3c415245506b7e851472b9f7944b4fb43bdf88a4..134e24ce32478793c1cc64e25b9619df2085aeb2 100644 (file)
@@ -179,6 +179,7 @@ static switch_status_t remove_interface(char *the_interface);
 
 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);
@@ -434,10 +435,6 @@ static switch_status_t channel_on_init(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;
@@ -645,6 +642,29 @@ static switch_status_t channel_on_soft_execute(switch_core_session_t *session)
        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)
 {
@@ -824,10 +844,14 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
        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);
@@ -865,6 +889,24 @@ static switch_status_t channel_answer_channel(switch_core_session_t *session)
        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;
@@ -991,7 +1033,7 @@ switch_state_handler_table_t skypopen_state_handlers = {
        /*.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
@@ -1184,6 +1226,12 @@ static void *SWITCH_THREAD_FUNC skypopen_signaling_thread_func(switch_thread_t *
                                *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
@@ -1949,7 +1997,6 @@ int new_inbound_channel(private_t * tech_pvt)
                }
        }
        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);
        }
@@ -2261,34 +2308,42 @@ SWITCH_STANDARD_API(skypopen_function)
        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;
                        }
                }
@@ -2303,11 +2358,115 @@ int skypopen_answer(private_t * tech_pvt, char *id, char *value)
        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);
index b978623fd5cc03fe3a8fcc11ef8756feba09ec5b..b991f0e8a7c8445af19bc86bde879b750921c944 100644 (file)
@@ -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);
index 6f4fc33b65187f25e54c30706be4b95207bff184..a15b5643aa573a658d8da71d07ec4eafa71ce4e9 100644 (file)
@@ -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;
+}