switch_mutex_t *mutex;
private_t *sk_console;
int start_port;
+
+ // CLOUDTREE (THomas Hazel)
+ switch_mutex_t *list_mutex;
+
} globals;
switch_endpoint_interface_t *skypopen_endpoint_interface;
switch_memory_pool_t *skypopen_module_pool = NULL;
int running = 0;
+// CLOUDTREE (THomas Hazel)
+#ifndef WIN32
+struct SkypopenList global_handles_list;
+extern int xio_error_handler(Display *dpy);
+extern int X11_errors_handler(Display * dpy, XErrorEvent * err);
+#endif
+
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_context, globals.context);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_destination, globals.destination);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_setsockopt, globals.setsockopt);
static switch_status_t interface_exists(char *the_interface);
-static switch_status_t remove_interface(char *the_interface);
+/* CLOUDTREE (Thomas Hazel) static*/ switch_status_t remove_interface(char *the_interface, /* CLOUDTREE (Thomas Hazel */ switch_bool_t force);
static switch_status_t channel_on_init(switch_core_session_t *session);
static switch_status_t channel_on_hangup(switch_core_session_t *session);
return SWITCH_STATUS_FALSE;
}
-static switch_status_t remove_interface(char *the_interface)
+/* CLOUDTREE (Thomas Hazel) static */ switch_status_t remove_interface(char *the_interface, /* CLOUDTREE (Thomas Hazel) */ switch_bool_t force)
{
int x = 10;
unsigned int howmany = 8;
goto end;
}
- if (strlen(globals.SKYPOPEN_INTERFACES[interface_id].session_uuid_str)) {
+ if (/* CLOUDTREE (Thomas Hazel) */ (force == FALSE) && strlen(globals.SKYPOPEN_INTERFACES[interface_id].session_uuid_str)) {
DEBUGA_SKYPE("interface '%s' is busy\n", SKYPOPEN_P_LOG, the_interface);
goto end;
}
|| tech_pvt->skype_callflow == CALLFLOW_STATUS_EARLYMEDIA
|| tech_pvt->skype_callflow == CALLFLOW_STATUS_REMOTEHOLD || tech_pvt->skype_callflow == SKYPOPEN_STATE_UP)) {
switch_mutex_lock(tech_pvt->mutex_audio_srv);
- if (switch_buffer_inuse(tech_pvt->read_buffer)) {
+ if (tech_pvt->read_buffer && switch_buffer_inuse(tech_pvt->read_buffer)) {
bytes_read = switch_buffer_read(tech_pvt->read_buffer, tech_pvt->read_frame.data, 640);
tech_pvt->read_frame.datalen = bytes_read;
}
private_t *tech_pvt = obj;
int res;
int forever = 1;
+ switch_event_t *event;
if (!tech_pvt)
return NULL;
if (!(running && tech_pvt->running))
break;
res = skypopen_signaling_read(tech_pvt);
+
+ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_INCOMING_RAW) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "X-Skype-Response-Code", "%d", res);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "X-Skype-Interface", "%s", tech_pvt->interface_id);
+ switch_event_add_body(event, "%s", tech_pvt->message);
+ switch_event_fire(&event);
+ }
+
if (res == CALLFLOW_INCOMING_HANGUP || tech_pvt->skype_callflow == CALLFLOW_INCOMING_HANGUP) {
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
DEBUGA_SKYPE("no session\n", SKYPOPEN_P_LOG);
}
switch_mutex_lock(globals.mutex);
+ tech_pvt->ringing_state = SKYPOPEN_RINGING_INIT;
tech_pvt->interface_state = SKYPOPEN_STATE_DOWN;
*tech_pvt->session_uuid_str = '\0';
*tech_pvt->skype_call_id = '\0';
switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface;
private_t *tech_pvt = NULL;
+ // CLOUDTREE (Thomas Hazel) - always try to load configuration
+ running = 1;
+
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, skypopen_module_pool);
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
ERRORA("open of %s failed\n", SKYPOPEN_P_LOG, cf);
skypopen_module_pool = pool;
memset(&globals, '\0', sizeof(globals));
- running = 1;
+ // CLOUDTREE (Thomas Hazel)
+ #ifndef WIN32
+ // XXX: these assumes no one will override
+ XSetErrorHandler(X11_errors_handler);
+ XSetIOErrorHandler(xio_error_handler);
+
+ memset(&global_handles_list, 0, sizeof(global_handles_list));
+ switch_mutex_init(&globals.list_mutex, SWITCH_MUTEX_NESTED, skypopen_module_pool);
+ #endif
- if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) {
+ // CLOUDTREE (Thomas Hazel) - load_configs no longer locks things up, no need to fail load
+ /*if (*/ load_config(FULL_RELOAD); /* != SWITCH_STATUS_SUCCESS) {
running = 0;
return SWITCH_STATUS_FALSE;
}
+ */
+
+ // CLOUDTREE (Thomas Hazel) - setting "running = 1;" use to be located before "load_config"
+ running = 1;
if (switch_event_reserve_subclass(MY_EVENT_INCOMING_CHATMESSAGE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
return SWITCH_STATUS_GENERR;
}
+ if (switch_event_reserve_subclass(MY_EVENT_INCOMING_RAW) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
+ return SWITCH_STATUS_GENERR;
+ }
+
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
skypopen_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
skypopen_endpoint_interface->interface_name = "skypopen";
SWITCH_ADD_API(commands_api_interface, "skypopen_chat", "Skypopen_chat interface remote_skypename TEXT", skypopen_chat_function, SKYPOPEN_CHAT_SYNTAX);
SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
-
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
} else
for (interface_id = 0; interface_id < SKYPOPEN_MAX_INTERFACES; interface_id++) {
tech_pvt = &globals.SKYPOPEN_INTERFACES[interface_id];
+
if (strlen(globals.SKYPOPEN_INTERFACES[interface_id].name)) {
if (globals.SKYPOPEN_INTERFACES[interface_id].skypopen_signaling_thread) {
#ifdef WIN32
}
switch_event_free_subclass(MY_EVENT_INCOMING_CHATMESSAGE);
+ switch_event_free_subclass(MY_EVENT_INCOMING_RAW);
switch_safe_free(globals.context);
switch_safe_free(globals.dialplan);
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);
- goto done;
+ ERRORA("No session_uuid_str???\n", SKYPOPEN_P_LOG);
+ goto bad;
}
if (session) {
channel = switch_core_session_get_channel(session);
} else {
ERRORA("No session???\n", SKYPOPEN_P_LOG);
- goto done;
+ goto bad;
}
if (channel) {
switch_channel_mark_ring_ready(channel);
switch_core_session_rwunlock(session);
- done:
+ return 1;
+ bad:
return 0;
}
if (!zstr(tech_pvt->session_uuid_str)) {
session = switch_core_session_locate(tech_pvt->session_uuid_str);
} else {
- ERRORA("No session???\n\n\n", SKYPOPEN_P_LOG);
+ ERRORA("No session_uuid_str???\n\n\n", SKYPOPEN_P_LOG);
goto done;
}
if (session) {
}
} else if (!strcasecmp(argv[0], "remove")) {
if (argc == 2) {
- if (remove_interface(argv[1]) == SWITCH_STATUS_SUCCESS) {
+ if (remove_interface(argv[1], FALSE) == SWITCH_STATUS_SUCCESS) {
if (interface_exists(argv[1]) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "sk remove '%s' failed\n", argv[1]);
} else {
}
DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG);
- if (tech_pvt && tech_pvt->skype_call_id && !strlen(tech_pvt->skype_call_id)) {
+ // CLOUDTREE (Thomas Hazel)
+ //if (tech_pvt && tech_pvt->skype_call_id && !strlen(tech_pvt->skype_call_id)) {
+ if (tech_pvt && tech_pvt->ringing_state == SKYPOPEN_RINGING_INIT) {
/* we are not inside an active call */
tech_pvt->interface_state = SKYPOPEN_STATE_PRERING;
}
DEBUGA_SKYPE("NOT FOUND\n", SKYPOPEN_P_LOG);
- if (tech_pvt && tech_pvt->skype_call_id && !strlen(tech_pvt->skype_call_id)) {
+ // CLOUDTREE (Thomas Hazel)
+ //if (tech_pvt && tech_pvt->skype_call_id && !strlen(tech_pvt->skype_call_id)) {
+ if (tech_pvt && tech_pvt->ringing_state == SKYPOPEN_RINGING_INIT) {
/* we are not inside an active call */
tech_pvt->ib_calls++;
return (globals.start_port - 1);
}
+#ifndef WIN32
+// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list?
+struct SkypopenHandles* skypopen_list_add(struct SkypopenList* list, struct SkypopenHandles* handle)
+{
+ switch_mutex_lock(globals.list_mutex);
+
+ if (handle->managed == SWITCH_TRUE) {
+ // already added
+ switch_mutex_unlock(globals.list_mutex);
+ return 0;
+ }
+
+ if (list->head == 0) {
+ list->head = handle;
+ handle->prev = 0;
+
+ } else {
+ ((struct SkypopenHandles*) list->tail)->next = handle;
+ ((struct SkypopenHandles*) handle)->prev = list->tail;
+ }
+
+ list->tail = handle;
+ handle->next = 0;
+
+ handle->managed = SWITCH_TRUE;
+
+ list->entries++;
+
+ switch_mutex_unlock(globals.list_mutex);
+
+ return handle;
+}
+
+// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list?
+struct SkypopenHandles* skypopen_list_remove_by_value(struct SkypopenList* list, Display* display)
+{
+ struct SkypopenHandles* iter;
+ struct SkypopenHandles* handle = 0;
+
+ switch_mutex_lock(globals.list_mutex);
+
+ iter = (struct SkypopenHandles*) list->head;
+ while (iter != 0) {
+ if (iter->disp == display) {
+ handle = iter;
+ break;
+ }
+
+ iter = (struct SkypopenHandles*) iter->next;
+ }
+
+ if ((handle != 0) && (handle->managed == SWITCH_TRUE)) {
+ if (handle->prev == 0) {
+ list->head = ((struct SkypopenHandles*) handle)->next;
+
+ } else {
+ ((struct SkypopenHandles*) handle->prev)->next = ((struct SkypopenHandles*) handle)->next;
+ }
+
+ if (handle->next == 0) {
+ list->tail = ((struct SkypopenHandles*) handle)->prev;
+
+ } else {
+ ((struct SkypopenHandles*) handle->next)->prev = ((struct SkypopenHandles*) handle)->prev;
+ }
+
+ handle->managed = SWITCH_FALSE;
+ handle->next = 0;
+ handle->prev = 0;
+
+ list->entries--;
+ }
+
+ switch_mutex_unlock(globals.list_mutex);
+
+ return handle;
+}
+
+// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list?
+struct SkypopenHandles* skypopen_list_remove_by_reference(struct SkypopenList* list, struct SkypopenHandles* handle)
+{
+ switch_mutex_lock(globals.list_mutex);
+
+ if (handle->managed == SWITCH_FALSE) {
+ // already removed
+ switch_mutex_unlock(globals.list_mutex);
+ return 0;
+ }
+
+ if (handle->prev == 0) {
+ list->head = ((struct SkypopenHandles*) handle)->next;
+
+ } else {
+ ((struct SkypopenHandles*) handle->prev)->next = ((struct SkypopenHandles*) handle)->next;
+ }
+
+ if (handle->next == 0) {
+ list->tail = ((struct SkypopenHandles*) handle)->prev;
+
+ } else {
+ ((struct SkypopenHandles*) handle->next)->prev = ((struct SkypopenHandles*) handle)->prev;
+ }
+
+ handle->managed = SWITCH_FALSE;
+ handle->next = 0;
+ handle->prev = 0;
+
+ list->entries--;
+
+ switch_mutex_unlock(globals.list_mutex);
+
+ return handle;
+}
+
+// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list?
+#ifdef XIO_ERROR_BY_UCONTEXT
+struct SkypopenHandles* skypopen_list_find(struct SkypopenList* list, struct SkypopenHandles* find)
+{
+ struct SkypopenHandles* iter;
+ struct SkypopenHandles* handle = NULL;
+
+ switch_mutex_lock(globals.list_mutex);
+
+ iter = (struct SkypopenHandles*) list->head;
+ while (iter != NULL) {
+ if (iter == find) {
+ handle = iter;
+ break;
+ }
+
+ iter = (struct SkypopenHandles*) iter->next;
+ }
+
+ switch_mutex_unlock(globals.list_mutex);
+
+ return handle;
+}
+#endif
+
+// CLOUDTREE (THomas Hazel) - is there a capable freeswitch list?
+int skypopen_list_size(struct SkypopenList* list)
+{
+ return list->entries;
+}
+#endif /* NOT WIN32 */
/* For Emacs:
* Local Variables:
#include <X11/Xlib.h>
#include <X11/Xlibint.h>
#include <X11/Xatom.h>
+
+// CLOUDTREE (Thomas Hazel)
+#define XIO_ERROR_BY_SETJMP
+//#define XIO_ERROR_BY_UCONTEXT
+
+// CLOUDTREE (Thomas Hazel)
+#ifdef XIO_ERROR_BY_SETJMP
+ #include "setjmp.h"
+#endif
+// CLOUDTREE (Thomas Hazel)
+#ifdef XIO_ERROR_BY_UCONTEXT
+ #include "ucontext.h"
+#endif
+
#endif //WIN32
#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
#endif
#define MY_EVENT_INCOMING_CHATMESSAGE "skypopen::incoming_chatmessage"
+#define MY_EVENT_INCOMING_RAW "skypopen::incoming_raw"
#define SAMPLERATE_SKYPOPEN 16000
#define SAMPLES_PER_FRAME SAMPLERATE_SKYPOPEN/50
#define SKYPOPEN_CONTROL_RINGING 1
#define SKYPOPEN_CONTROL_ANSWER 2
+/*********************************/
+// CLOUDTREE (Thomas Hazel)
+#define SKYPOPEN_RINGING_INIT 0
+#define SKYPOPEN_RINGING_PRE 1
+
/*********************************/
#define SKYPOPEN_STATE_IDLE 0
#define SKYPOPEN_STATE_DOWN 1
int currentuserhandle;
int api_connected;
int fdesc[2];
+
+ // CLOUDTREE (Thomas Hazel)
+ #ifdef XIO_ERROR_BY_SETJMP
+ jmp_buf ioerror_context;
+ #endif
+ #ifdef XIO_ERROR_BY_UCONTEXT
+ ucontext_t ioerror_context;
+ #endif
+
+ // CLOUDTREE (Thomas Hazel) - is there a capable freeswitch list?
+ switch_bool_t managed;
+ void* prev;
+ void* next;
+};
+
+// CLOUDTREE (Thomas Hazel) - is there a capable freeswitch list?
+struct SkypopenList {
+ int entries;
+ void* head;
+ void* tail;
};
+
+// CLOUDTREE (Thomas Hazel) - is there a capable freeswitch list?
+struct SkypopenHandles* skypopen_list_add(struct SkypopenList* list, struct SkypopenHandles* x);
+struct SkypopenHandles* skypopen_list_find(struct SkypopenList* list, struct SkypopenHandles* x);
+struct SkypopenHandles* skypopen_list_remove_by_value(struct SkypopenList* list, Display* display);
+struct SkypopenHandles* skypopen_list_remove_by_reference(struct SkypopenList* list, struct SkypopenHandles* x);
+int skypopen_list_size(struct SkypopenList* list);
+
#else //WIN32
struct SkypopenHandles {
#endif
struct SkypopenHandles SkypopenHandles;
+ // CLOUDTREE (Thomas Hazel)
+ char ringing_state;
+
int interface_state;
char language[80];
char exten[80];
char ring_id[256];
char ring_value[256];
+ char message[4096];
};
typedef struct private_object private_t;
#ifdef WIN32
DWORD win32_dwThreadId;
#else
-XErrorHandler old_handler = 0;
-int xerror = 0;
+
+// CLOUDTREE (Thomas Hazel)
+static int global_x_error = Success;
+extern struct SkypopenList global_handles_list;
+extern switch_status_t remove_interface(char *the_interface, switch_bool_t force);
+
#endif /* WIN32 */
/*************************************/
#ifndef WIN32
//if (!strstr(message, "DURATION")) {
DEBUGA_SKYPE("READING: |||%s||| \n", SKYPOPEN_P_LOG, message);
+ strncpy( tech_pvt->message, message, sizeof(tech_pvt->message) );
+
//}
if (!strcasecmp(message, "SILENT_MODE OFF")) {
if (tech_pvt->silent_mode) {
char msg_to_skype[1024];
if ((tech_pvt->interface_state != SKYPOPEN_STATE_SELECTED && tech_pvt->interface_state != SKYPOPEN_STATE_DIALING)
&& (!strlen(tech_pvt->skype_call_id) || !strlen(tech_pvt->session_uuid_str))) {
- /* we are NOT inside an active call */
+ // CLOUDTREE (Thomas Hazel)
+ skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
+ /* we are NOT inside an active call */
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);
} else {
/* we are inside an active call */
if (!strcasecmp(tech_pvt->skype_call_id, id)) {
+ // CLOUDTREE (Thomas Hazel)
+ tech_pvt->ringing_state = SKYPOPEN_RINGING_PRE;
+
/* this is the call in which we are calling out */
tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING;
tech_pvt->interface_state = SKYPOPEN_STATE_RINGING;
skypopen_strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1);
DEBUGA_SKYPE("Our remote party in skype_call %s is RINGING\n", SKYPOPEN_P_LOG, id);
- remote_party_is_ringing(tech_pvt);
+ if( !remote_party_is_ringing(tech_pvt)){
+
+ WARNINGA("We are getting the RINGING from a call we canceled, trying to get out hanging up call id: %s.\n", SKYPOPEN_P_LOG, id);
+ sprintf(msg_to_skype, "ALTER CALL %s HANGUP", id);
+ skypopen_signaling_write(tech_pvt, msg_to_skype);
+ tech_pvt->skype_call_id[0] = '\0';
+ // CLOUDTREE (Thomas Hazel)
+ tech_pvt->ringing_state = SKYPOPEN_RINGING_INIT;
+ tech_pvt->skype_callflow = CALLFLOW_CALL_IDLE;
+ tech_pvt->interface_state = SKYPOPEN_STATE_IDLE;
+ ERRORA("we're back to IDLE\n", SKYPOPEN_P_LOG, id);
+ skypopen_sleep(10000);
+
+ }
} else {
DEBUGA_SKYPE
("We are in another call, but skype_call %s is RINGING on us, let's ask PARTNER_HANDLE, so maybe we'll TRANSFER\n",
skypopen_signaling_write(tech_pvt, msg_to_skype);
remote_party_is_early_media(tech_pvt);
+ /* CLOUDTREE (Thomas Hazel)
} else if (!strcasecmp(value, "MISSED")) {
DEBUGA_SKYPE("We missed skype_call %s\n", SKYPOPEN_P_LOG, id);
- } else if (!strcasecmp(value, "FINISHED")) {
+ */
+ // CLOUDTREE (Thomas Hazel)
+ } else if (!strcasecmp(value, "MISSED") || !strcasecmp(value, "FINISHED")) {
if (!strcasecmp(tech_pvt->skype_call_id, id)) {
DEBUGA_SKYPE("skype_call %s is MY call, now I'm going DOWN\n", SKYPOPEN_P_LOG, id);
if (tech_pvt->interface_state != SKYPOPEN_STATE_HANGUP_REQUESTED) {
}
#else /* NOT WIN32 */
-int X11_errors_handler(Display * dpy, XErrorEvent * err)
+
+// CLOUDTREE (Thomas Hazel)
+int xio_error_handler(Display *dpy)
{
private_t *tech_pvt = NULL;
- (void) dpy;
+ struct SkypopenHandles* handle;
+
+ ERRORA("Fatal display error for %d, %s\n", SKYPOPEN_P_LOG, skypopen_list_size(&global_handles_list), dpy->display_name);
+
+ handle = skypopen_list_remove_by_value(&global_handles_list, dpy);
+ if (handle != NULL) {
+ #ifdef XIO_ERROR_BY_SETJMP
+ siglongjmp(handle->ioerror_context, 1);
+ #endif
+ #ifdef XIO_ERROR_BY_UCONTEXT
+ setcontext(&handle->ioerror_context);
+ #endif
+ }
- xerror = err->error_code;
- ERRORA("Received error code %d from X Server\n\n", SKYPOPEN_P_LOG, xerror);
- return 0; /* ignore the error */
-}
+ ERRORA("Fatal display error for %p, %s - failed to siglongjmp\n", SKYPOPEN_P_LOG, (void*) handle, dpy->display_name);
-static void X11_errors_trap(void)
-{
- xerror = 0;
- old_handler = XSetErrorHandler(X11_errors_handler);
+ return 0;
}
-static int X11_errors_untrap(void)
+int X11_errors_handler(Display * dpy, XErrorEvent * err)
{
- XSetErrorHandler(old_handler);
- return (xerror != BadValue) && (xerror != BadWindow);
+ private_t *tech_pvt = NULL;
+ (void) dpy;
+
+ global_x_error = err->error_code;
+ ERRORA("Received error code %d from X Server\n\n", SKYPOPEN_P_LOG, global_x_error);
+ return 0; /* ignore the error */
}
int skypopen_send_message(private_t * tech_pvt, const char *message_P)
Window w_P = SkypopenHandles->skype_win;
Display *disp = SkypopenHandles->disp;
Window handle_P = SkypopenHandles->win;
- int ok;
Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False);
e.xclient.window = handle_P;
e.xclient.format = 8;
- X11_errors_trap();
+ // CLOUDTREE (Thomas Hazel)
+ global_x_error = Success;
+
do {
unsigned int i;
for (i = 0; i < 20 && i + pos <= len; ++i)
//giovanni XSync(disp, False);
XFlush(disp);
- ok = X11_errors_untrap();
- if (!ok) {
- ERRORA("Sending message failed with status %d\n", SKYPOPEN_P_LOG, xerror);
+ // CLOUDTREE (Thomas Hazel)
+ if (global_x_error != Success) {
+ ERRORA("Sending message failed with status %d\n", SKYPOPEN_P_LOG, global_x_error);
tech_pvt->running = 0;
return 0;
}
int status;
private_t *tech_pvt = NULL;
- X11_errors_trap();
status =
XGetWindowProperty(SkypopenHandles->disp, DefaultRootWindow(SkypopenHandles->disp),
skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, &prop);
- X11_errors_untrap();
/* sanity check */
if (status != Success || format_ret != 32 || nitems_ret != 1) {
if (!disp) {
ERRORA("Cannot open X Display '%s', exiting skype thread\n", SKYPOPEN_P_LOG, tech_pvt->X11_display);
running = 0;
+
+ // CLOUDTREE (Thomas Hazel)
+ tech_pvt->skypopen_api_thread = NULL;
+ remove_interface(tech_pvt->skype_user, FALSE);
return NULL;
} else {
DEBUGA_SKYPE("X Display '%s' opened\n", SKYPOPEN_P_LOG, tech_pvt->X11_display);
}
+ // CLOUDTREE (Thomas Hazel)
+ #ifndef WIN32
+ {
+ skypopen_list_add(&global_handles_list, SkypopenHandles);
+
+ #ifdef XIO_ERROR_BY_SETJMP
+ if (sigsetjmp(SkypopenHandles->ioerror_context, 1) != 0) {
+ switch_core_session_t *session = NULL;
+ ERRORA("Fatal display error for %s - successed to jump\n", SKYPOPEN_P_LOG, tech_pvt->X11_display);
+
+ session = switch_core_session_locate(tech_pvt->session_uuid_str);
+ if (session) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ WARNINGA("Closing session %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
+ switch_channel_hangup(channel, SWITCH_CAUSE_CRASH);
+ switch_core_session_rwunlock(session);
+ }
+
+ WARNINGA("Removing skype user %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
+ tech_pvt->skypopen_api_thread = NULL;
+ remove_interface(tech_pvt->skype_user, TRUE);
+ XCloseDisplay(disp);
+ return NULL;
+ }
+ #endif
+ #ifdef XIO_ERROR_BY_UCONTEXT
+ getcontext(&SkypopenHandles->ioerror_context);
+
+ if (skypopen_list_find(&global_handles_list, SkypopenHandles) == NULL) {
+ switch_core_session_t *session = NULL;
+ ERRORA("Fatal display error for %s - successed to jump\n", SKYPOPEN_P_LOG, tech_pvt->X11_display);
+
+ session = switch_core_session_locate(tech_pvt->session_uuid_str);
+ if (session) {
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ WARNINGA("Closing session %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
+ switch_channel_hangup(channel, SWITCH_CAUSE_CRASH);
+ switch_core_session_rwunlock(session);
+ }
+
+ WARNINGA("Removing skype user %s\n", SKYPOPEN_P_LOG, tech_pvt->skype_user);
+ tech_pvt->skypopen_api_thread = NULL;
+ remove_interface(tech_pvt->skype_user, TRUE);
+ XCloseDisplay(disp);
+ return NULL;
+ }
+ #endif
+ }
+ #endif /* NOT WIN32 */
+
xfd = XConnectionNumber(disp);
fcntl(xfd, F_SETFD, FD_CLOEXEC);
if (!skypopen_send_message(tech_pvt, buf)) {
ERRORA("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypopen again\n", SKYPOPEN_P_LOG);
+
+ // CLOUDTREE (Thomas Hazel)
+ #ifndef WIN32
+ skypopen_list_remove_by_reference(&global_handles_list, SkypopenHandles);
+ #endif
+
+ XCloseDisplay(disp);
running = 0;
return NULL;
}
snprintf(buf, 512, "PROTOCOL 7");
if (!skypopen_send_message(tech_pvt, buf)) {
ERRORA("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypopen again\n", SKYPOPEN_P_LOG);
+
+ // CLOUDTREE (Thomas Hazel)
+ #ifndef WIN32
+ skypopen_list_remove_by_reference(&global_handles_list, SkypopenHandles);
+ #endif
+
+ XCloseDisplay(disp);
running = 0;
return NULL;
}
ERRORA("Skype is not running, maybe crashed. Please run/restart Skype and relaunch Skypopen\n", SKYPOPEN_P_LOG);
running = 0;
}
- tech_pvt->skypopen_api_thread=NULL;
+
NOTICA("EXITING\n", SKYPOPEN_P_LOG);
+
+ // CLOUDTREE (Thomas Hazel)
+ #ifndef WIN32
+ skypopen_list_remove_by_reference(&global_handles_list, SkypopenHandles);
+ #endif
+
+ tech_pvt->skypopen_api_thread=NULL;
+ XCloseDisplay(disp);
return NULL;
}