skypopen: CLOUDTREE patch with some modifications

This commit is contained in:
Giovanni Maruzzelli 2010-10-25 15:36:12 -05:00
parent 7fce3995df
commit f04322e9bb
3 changed files with 401 additions and 42 deletions

View File

@ -159,12 +159,23 @@ static struct {
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);
@ -175,7 +186,7 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_write_silence_when_idle, globals.wr
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);
@ -298,7 +309,7 @@ static switch_status_t interface_exists(char *the_interface)
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;
@ -338,7 +349,7 @@ static switch_status_t remove_interface(char *the_interface)
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;
}
@ -743,7 +754,7 @@ read:
|| 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;
}
@ -1232,6 +1243,7 @@ static void *SWITCH_THREAD_FUNC skypopen_signaling_thread_func(switch_thread_t *
private_t *tech_pvt = obj;
int res;
int forever = 1;
switch_event_t *event;
if (!tech_pvt)
return NULL;
@ -1242,6 +1254,14 @@ static void *SWITCH_THREAD_FUNC skypopen_signaling_thread_func(switch_thread_t *
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;
@ -1266,6 +1286,7 @@ static void *SWITCH_THREAD_FUNC skypopen_signaling_thread_func(switch_thread_t *
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';
@ -1299,6 +1320,9 @@ static switch_status_t load_config(int reload_type)
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);
@ -1769,18 +1793,36 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load)
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);
if (load_config(FULL_RELOAD) != SWITCH_STATUS_SUCCESS) {
memset(&global_handles_list, 0, sizeof(global_handles_list));
switch_mutex_init(&globals.list_mutex, SWITCH_MUTEX_NESTED, skypopen_module_pool);
#endif
// 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";
@ -1794,7 +1836,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_skypopen_load)
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
@ -1814,6 +1855,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypopen_shutdown)
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
@ -1888,6 +1930,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_skypopen_shutdown)
}
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);
@ -2058,14 +2101,14 @@ int remote_party_is_ringing(private_t * tech_pvt)
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);
@ -2076,7 +2119,8 @@ int remote_party_is_ringing(private_t * tech_pvt)
switch_core_session_rwunlock(session);
done:
return 1;
bad:
return 0;
}
@ -2088,7 +2132,7 @@ int remote_party_is_early_media(private_t * tech_pvt)
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) {
@ -2276,7 +2320,7 @@ SWITCH_STANDARD_API(sk_function)
}
} 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 {
@ -2399,7 +2443,9 @@ int skypopen_partner_handle_ring(private_t * tech_pvt)
}
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;
@ -2508,7 +2554,9 @@ int skypopen_answer(private_t * tech_pvt)
}
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++;
@ -2853,6 +2901,151 @@ int next_port(void)
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:

View File

@ -41,6 +41,20 @@
#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
@ -58,6 +72,7 @@
#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
@ -99,6 +114,11 @@ typedef enum {
#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
@ -154,7 +174,35 @@ struct SkypopenHandles {
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 {
@ -218,6 +266,9 @@ struct private_object {
#endif
struct SkypopenHandles SkypopenHandles;
// CLOUDTREE (Thomas Hazel)
char ringing_state;
int interface_state;
char language[80];
char exten[80];
@ -294,6 +345,7 @@ struct private_object {
char ring_id[256];
char ring_value[256];
char message[4096];
};
typedef struct private_object private_t;

View File

@ -21,8 +21,12 @@ extern int running;
#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
@ -174,6 +178,8 @@ int skypopen_signaling_read(private_t * tech_pvt)
//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) {
@ -559,8 +565,10 @@ int skypopen_signaling_read(private_t * tech_pvt)
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);
@ -571,12 +579,28 @@ int skypopen_signaling_read(private_t * tech_pvt)
} 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",
@ -606,9 +630,12 @@ int skypopen_signaling_read(private_t * tech_pvt)
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) {
@ -1425,35 +1452,46 @@ void *skypopen_do_skypeapi_thread_func(void *obj)
}
#else /* NOT WIN32 */
// CLOUDTREE (Thomas Hazel)
int xio_error_handler(Display *dpy)
{
private_t *tech_pvt = NULL;
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
}
ERRORA("Fatal display error for %p, %s - failed to siglongjmp\n", SKYPOPEN_P_LOG, (void*) handle, dpy->display_name);
return 0;
}
int X11_errors_handler(Display * dpy, XErrorEvent * err)
{
private_t *tech_pvt = NULL;
(void) dpy;
xerror = err->error_code;
ERRORA("Received error code %d from X Server\n\n", SKYPOPEN_P_LOG, xerror);
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 */
}
static void X11_errors_trap(void)
{
xerror = 0;
old_handler = XSetErrorHandler(X11_errors_handler);
}
static int X11_errors_untrap(void)
{
XSetErrorHandler(old_handler);
return (xerror != BadValue) && (xerror != BadWindow);
}
int skypopen_send_message(private_t * tech_pvt, const char *message_P)
{
struct SkypopenHandles *SkypopenHandles = &tech_pvt->SkypopenHandles;
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);
@ -1472,7 +1510,9 @@ skypopen_sleep(1000);//giovanni
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)
@ -1485,10 +1525,10 @@ skypopen_sleep(1000);//giovanni
//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;
}
@ -1525,11 +1565,9 @@ int skypopen_present(struct SkypopenHandles *SkypopenHandles)
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) {
@ -1597,11 +1635,65 @@ void *skypopen_do_skypeapi_thread_func(void *obj)
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);
@ -1617,6 +1709,13 @@ void *skypopen_do_skypeapi_thread_func(void *obj)
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;
}
@ -1624,6 +1723,13 @@ void *skypopen_do_skypeapi_thread_func(void *obj)
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;
}
@ -1750,8 +1856,16 @@ while(XPending(disp)){
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;
}