[commit] r10275 - freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax
Author: gmaruzz Date: Thu Nov 6 17:55:42 2008 New Revision: 10275 Modified: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c Log: skypiax: ask the Skype client for API connection Modified: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c ============================================================================== --- freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c (original) +++ freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c Thu Nov 6 17:55:42 2008 @@ -2210,6 +2210,53 @@ #include <X11/Xatom.h> #include <switch.h> +#define SKYPIAX_SVN_VERSION "SVN 123456" + +#define DEBUGA_SKYPE(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SKYPE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_CALL(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_PBX(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define ERRORA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][ERRORA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define WARNINGA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][WARNINGA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define NOTICA(...) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][NOTICA %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); + + +#define SKYPIAX_P_LOG NULL, (unsigned long)55, __LINE__, "none", -1, -2, -3 + +#ifdef ASTER +/* debugging bitmask */ +#define DEBUG_SOUND 1 +#define DEBUG_SERIAL 2 +#define DEBUG_SKYPE 4 +#define DEBUG_AT 8 +#define DEBUG_FBUS2 16 +#define DEBUG_CALL 32 +#define DEBUG_LOCKS 64 +#define DEBUG_PBX 128 +#define DEBUG_MONITORLOCKS 256 +#define DEBUG_ALL DEBUG_SOUND|DEBUG_SERIAL|DEBUG_SKYPE|DEBUG_AT|DEBUG_FBUS2|DEBUG_CALL|DEBUG_PBX|DEBUG_LOCKS|DEBUG_MONITORLOCKS +/* wrappers for ast_log */ +#define DEBUGA_SOUND(...) if (skypiax_debug & DEBUG_SOUND) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SOUND %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_SERIAL(...) if (skypiax_debug & DEBUG_SERIAL) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SERIAL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_SKYPE(...) if (skypiax_debug & DEBUG_SKYPE) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_SKYPE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_AT(...) if (skypiax_debug & DEBUG_AT) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_AT %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_FBUS2(...) if (skypiax_debug & DEBUG_FBUS2) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_FBUS2 %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_CALL(...) if (skypiax_debug & DEBUG_CALL) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_CALL %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define DEBUGA_PBX(...) if (skypiax_debug & DEBUG_PBX) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_PBX %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define ERRORA(...) ast_log(LOG_ERROR, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][ERROR %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define NOTICA(...) ast_log(LOG_NOTICE, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][NOTICE %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +#define WARNINGA(...) ast_log(LOG_WARNING, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][WARNING %-5d][%-10s][%2d,%2d,%2d] " __VA_ARGS__ ); +/* macros for logging */ +#define SKYPIAX_P_LOG p ? p->owner : NULL, (unsigned long)pthread_self(), __LINE__, p ? p->name ? p->name : "none" : "none", p ? p->owner ? p->owner->_state : -1 : -1, p ? p->interface_state : -1, p ? p->skype_callflow : -1 +#define SKYPIAX_TMP_LOG tmp ? tmp->owner : NULL, (unsigned long)pthread_self(), __LINE__, tmp ? tmp->name ? tmp->name : "none" : "none", tmp ? tmp->owner ? tmp->owner->_state : -1 : -1, tmp ? tmp->interface_state : -1, tmp ? tmp->skype_callflow : -1 +/* logging wrappers for ast_mutex_lock and ast_mutex_unlock */ +#define LOKKA(x) if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); +#define UNLOCKA(x) if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_LOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_LOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); +#define PUSHA_UNLOCKA(x) pthread_cleanup_push(skypiax_unlocka_log, (void *) x); +#define POPPA_UNLOCKA(x) pthread_cleanup_pop(0); +#define MONITORLOKKA(x) if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to lock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_lock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] locked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); +#define MONITORUNLOCKA(x) if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] going to unlock %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); if (ast_mutex_unlock(x)) ast_log(LOG_ERROR, "ast_mutex_lock failed, BAD\n"); if (skypiax_debug & DEBUG_MONITORLOCKS) ast_log(LOG_DEBUG, "rev "SKYPIAX_SVN_VERSION "[%p|%-7lx][DEBUG_MONITORLOCKS %-5d][%-10s][%2d,%2d,%2d] unlocked %p (%s)\n", SKYPIAX_P_LOG, x, x == &skypiax_monlock ? "MONLOCK" : x == &skypiax_iflock ? "IFLOCK" : x == &skypiax_usecnt_lock ? "USECNT_LOCK" : "?????"); +#endif /* ASTER */ + #define SKYPIAX_MAX_INTERFACES 64 SWITCH_MODULE_LOAD_FUNCTION(mod_skypiax_load); @@ -2222,6 +2269,13 @@ static switch_memory_pool_t *module_pool = NULL; static int running = 1; +struct AsteriskHandles { + Window skype_win; + Display *disp; + Window win; + int fdesc[2]; +}; + typedef enum { TFLAG_IO = (1 << 0), @@ -2676,16 +2730,147 @@ /*.receive_event */ channel_receive_event }; #define SKYPE_THREAD + struct AsteriskHandles ciapa; #ifdef SKYPE_THREAD +#define SKYPE_X11_BUF_SIZE 512 +Window skype_win = (Window) - 1; +static XErrorHandler old_handler = 0; +static int xerror = 0; + +int X11_errors_handler(Display * dpy, XErrorEvent * err) +{ + (void) dpy; + //struct skypiax_pvt *p = NULL; + + xerror = err->error_code; + DEBUGA_SKYPE("Received error code %d from X Server\n", SKYPIAX_P_LOG, xerror); + 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 skypiax_skype_send_message(struct AsteriskHandles *AsteriskHandlesAst, + const char *message_P) +{ + + Window w_P; + Display *disp; + Window handle_P; + //struct skypiax_pvt *p = NULL; + + w_P = AsteriskHandlesAst->skype_win; + disp = AsteriskHandlesAst->disp; + handle_P = AsteriskHandlesAst->win; + + Atom atom1 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE_BEGIN", False); + Atom atom2 = XInternAtom(disp, "SKYPECONTROLAPI_MESSAGE", False); + unsigned int pos = 0; + unsigned int len = strlen(message_P); + XEvent e; + int ok; + + memset(&e, 0, sizeof(e)); + e.xclient.type = ClientMessage; + e.xclient.message_type = atom1; /* leading message */ + e.xclient.display = disp; + e.xclient.window = handle_P; + e.xclient.format = 8; + + X11_errors_trap(); + //XLockDisplay(disp); + do { + unsigned int i; + for (i = 0; i < 20 && i + pos <= len; ++i) + e.xclient.data.b[i] = message_P[i + pos]; + XSendEvent(disp, w_P, False, 0, &e); + + e.xclient.message_type = atom2; /* following messages */ + pos += i; + } while (pos <= len); + + XSync(disp, False); + //XUnlockDisplay(disp); + ok = X11_errors_untrap(); + + if (!ok) + DEBUGA_SKYPE("Sending message failed with status %d\n", SKYPIAX_P_LOG, xerror); + + return ok; +} + +int skypiax_skype_present(Display * disp) +{ + Atom skype_inst = XInternAtom(disp, "_SKYPE_INSTANCE", True); + + Atom type_ret; + int format_ret; + unsigned long nitems_ret; + unsigned long bytes_after_ret; + unsigned char *prop; + int status; + //struct skypiax_pvt *p = NULL; + + X11_errors_trap(); + //XLockDisplay(disp); + status = + XGetWindowProperty(disp, DefaultRootWindow(disp), skype_inst, 0, 1, False, XA_WINDOW, + &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, &prop); + //XUnlockDisplay(disp); + X11_errors_untrap(); + + /* sanity check */ + if (status != Success || format_ret != 32 || nitems_ret != 1) { + skype_win = (Window) - 1; + DEBUGA_SKYPE("Skype instance not found\n", SKYPIAX_P_LOG); + return 0; + } + + skype_win = *(const unsigned long *) prop & 0xffffffff; + //DEBUGA_SKYPE("Skype instance found with id #%x\n", SKYPIAX_P_LOG, + DEBUGA_SKYPE("Skype instance found with id #%d\n", SKYPIAX_P_LOG, + (unsigned int) skype_win); + return 1; +} + +void skypiax_skype_clean_disp(void *data) +{ + + int *dispptr; + int disp; + //struct skypiax_pvt *p = NULL; + + dispptr = data; + disp = *dispptr; + + if (disp) { + DEBUGA_SKYPE("to be destroyed disp %d\n", SKYPIAX_P_LOG, disp); + close(disp); + DEBUGA_SKYPE("destroyed disp\n", SKYPIAX_P_LOG); + } else { + DEBUGA_SKYPE("NOT destroyed disp\n", SKYPIAX_P_LOG); + } + DEBUGA_SKYPE("OUT destroyed disp\n", SKYPIAX_P_LOG); + usleep(1000); +} void *do_skype_thread(void *data) { // struct skypiax_pvt *p; - // struct AsteriskHandles *AsteriskHandlesAst; - //FIXME char buf[SKYPE_X11_BUF_SIZE]; + struct AsteriskHandles *AsteriskHandlesAst; + char buf[SKYPE_X11_BUF_SIZE]; Display *disp = NULL; - //FIXME Window root = -1; - //FIXME Window win = -1; + Window root = -1; + Window win = -1; /* p = data; @@ -2703,6 +2888,7 @@ AsteriskHandlesAst = &p->AsteriskHandlesAst; */ + AsteriskHandlesAst = &ciapa; disp = XOpenDisplay(getenv("DISPLAY")); if (!disp) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot open X Display, exiting skype thread\n"); @@ -2715,8 +2901,8 @@ xfd = XConnectionNumber(disp); fcntl(xfd, F_SETFD, FD_CLOEXEC); -#ifdef NOTDEF - pthread_cleanup_push(skypiax_skype_clean_disp, &xfd); +#ifndef NOTDEF + //FIXME pthread_cleanup_push(skypiax_skype_clean_disp, &xfd); DEBUGA_SKYPE("PUSH disp %d\n", SKYPIAX_P_LOG, xfd); if (skypiax_skype_present(disp)) { @@ -2734,17 +2920,15 @@ AsteriskHandlesAst->disp = disp; AsteriskHandlesAst->win = win; - snprintf(buf, SKYPE_X11_BUF_SIZE, "NAME skypiax"); + snprintf(buf, SKYPE_X11_BUF_SIZE, "NAME FS_skypiax"); if (!skypiax_skype_send_message(AsteriskHandlesAst, buf)) { ERRORA ("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n", SKYPIAX_P_LOG); - p->skype = 0; - p->skype_thread = AST_PTHREADT_NULL; - if (option_debug > 10) { + //p->skype = 0; + //p->skype_thread = AST_PTHREADT_NULL; DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } return NULL; } @@ -2753,23 +2937,22 @@ ERRORA ("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n", SKYPIAX_P_LOG); - p->skype = 0; - p->skype_thread = AST_PTHREADT_NULL; - if (option_debug > 10) { + //p->skype = 0; + //p->skype_thread = AST_PTHREADT_NULL; DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } return NULL; } /* perform an events loop */ - XEvent an_event; - char buf[21]; /* can't be longer */ + //FIXME XEvent an_event; + //FIXME char buf[21]; /* can't be longer */ char buffer[17000]; char *b; - int i; + //FIXME int i; b = buffer; +#ifdef LOOPI while (1) { pthread_testcancel(); XNextEvent(disp, &an_event); @@ -2804,20 +2987,19 @@ break; } } +#endif // LOOPI } else { ERRORA ("Skype is not running, maybe crashed. Please run/restart Skype and relaunch Skypiax\n", SKYPIAX_P_LOG); - p->skype = 0; - p->skype_thread = AST_PTHREADT_NULL; + //p->skype = 0; + //p->skype_thread = AST_PTHREADT_NULL; return NULL; } - p->skype = 0; - p->skype_thread = AST_PTHREADT_NULL; - pthread_cleanup_pop(1); - if (option_debug > 10) { + //p->skype = 0; + //p->skype_thread = AST_PTHREADT_NULL; + //pthread_cleanup_pop(1); DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } #endif /* NOTDEF */ return NULL; @@ -3011,8 +3193,11 @@ #endif /* _WINDOWS_ */ + load_config(); + DEBUGA_PBX("CIAPALO FUNC\n", SKYPIAX_P_LOG); + *module_interface = switch_loadable_module_create_module_interface(pool, modname); skypiax_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE); skypiax_endpoint_interface->interface_name = "skypiax";
participants (1)
-
Freeswitch SVN