[commit] r11703 - in freeswitch/branches/gmaruzz/mod_skypiax: . asterisk
Author: gmaruzz Date: Mon Feb 9 10:10:52 2009 New Revision: 11703 Log: skypiax: cleaning skypiax_protocol.c Modified: freeswitch/branches/gmaruzz/mod_skypiax/asterisk/skypiax.h freeswitch/branches/gmaruzz/mod_skypiax/skypiax.h freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c Modified: freeswitch/branches/gmaruzz/mod_skypiax/asterisk/skypiax.h ============================================================================== --- freeswitch/branches/gmaruzz/mod_skypiax/asterisk/skypiax.h (original) +++ freeswitch/branches/gmaruzz/mod_skypiax/asterisk/skypiax.h Mon Feb 9 10:10:52 2009 @@ -404,6 +404,7 @@ int new_inbound_channel(private_t *tech_pvt); int outbound_channel_answered(private_t *tech_pvt); int skypiax_skype_senddigit(struct skypiax_pvt *p, char digit); +int skypiax_skype_write(private_t * tech_pvt, char *msg_to_skype); #define SKYPIAX_STATE_DOWN AST_STATE_DOWN #define SKYPIAX_STATE_RING AST_STATE_RING #define SKYPIAX_STATE_DIALING AST_STATE_DIALING Modified: freeswitch/branches/gmaruzz/mod_skypiax/skypiax.h ============================================================================== --- freeswitch/branches/gmaruzz/mod_skypiax/skypiax.h (original) +++ freeswitch/branches/gmaruzz/mod_skypiax/skypiax.h Mon Feb 9 10:10:52 2009 @@ -258,3 +258,4 @@ int start_audio_threads(private_t *tech_pvt); int new_inbound_channel(private_t *tech_pvt); int outbound_channel_answered(private_t *tech_pvt); +int skypiax_skype_write(private_t * tech_pvt, char *msg_to_skype); Modified: freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c ============================================================================== --- freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c (original) +++ freeswitch/branches/gmaruzz/mod_skypiax/skypiax_protocol.c Mon Feb 9 10:10:52 2009 @@ -20,6 +20,8 @@ #ifndef WIN32 XErrorHandler old_handler = 0; int xerror = 0; +#else +DWORD win32_dwThreadId; #endif /* WIN32 */ /*************************************/ @@ -421,7 +423,6 @@ { unsigned int samples; - //samples = SAMPLES_PER_FRAME * sizeof(short); samples = skypiax_pipe_read(tech_pvt->audiopipe[0], tech_pvt->read_frame.data, SAMPLES_PER_FRAME * sizeof(short)); @@ -436,557 +437,564 @@ return 1; } -#ifdef WIN32 - -enum { - SKYPECONTROLAPI_ATTACH_SUCCESS = 0, /* Client is successfully - attached and API window handle can be found - in wParam parameter */ - SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1, /* Skype has acknowledged - connection request and is waiting - for confirmation from the user. */ - /* The client is not yet attached - * and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message */ - SKYPECONTROLAPI_ATTACH_REFUSED = 2, /* User has explicitly - denied access to client */ - SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE = 3, /* API is not available - at the moment. - For example, this happens when no user - is currently logged in. */ - /* Client should wait for - * SKYPECONTROLAPI_ATTACH_API_AVAILABLE - * broadcast before making any further */ - /* connection attempts. */ - SKYPECONTROLAPI_ATTACH_API_AVAILABLE = 0x8001 -}; - -char - *strsep(char **stringp, const char *delim) +int skypiax_skype_read(private_t * tech_pvt) { - char *res; - - if (!stringp || !*stringp || !**stringp) - return (char *) 0; - res = *stringp; - while (**stringp && !strchr(delim, **stringp)) - ++(*stringp); + char read_from_pipe[4096]; + char messaggio[4096]; + char messaggio_2[4096]; + char *buf, obj[512] = "", id[512] = "", prop[512] = "", value[512] = "", *where; + char **stringp = NULL; + int rt; + int a; + unsigned int howmany; + unsigned int i; +#ifndef WIN32 + int fdselect; + fd_set fs; + struct timeval to; +#endif /* WIN32 */ - if (**stringp) { - **stringp = '\0'; - ++(*stringp); + if (option_debug > 100) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); } - return res; -} - -LRESULT APIENTRY skypiax_skype_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, - LPARAM ulParam) -{ - LRESULT lReturnCode; - int fIssueDefProc; - private_t *tech_pvt = NULL; - - lReturnCode = 0; - fIssueDefProc = 0; - tech_pvt = (private_t *) GetWindowLong(hWindow, GWL_USERDATA); - switch (uiMessage) { - case WM_CREATE: - tech_pvt = (private_t *) ((LPCREATESTRUCT) ulParam)->lpCreateParams; - SetWindowLong(hWindow, GWL_USERDATA, (LONG) tech_pvt); - DEBUGA_SKYPE("got CREATE\n", SKYPIAX_P_LOG); - break; - case WM_DESTROY: - NOTICA("got DESTROY\n", SKYPIAX_P_LOG); - tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = NULL; - PostQuitMessage(0); - break; - case WM_COPYDATA: - if (tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle == (HWND) uiParam) { - unsigned int howmany; - char msg_from_skype[2048]; - - PCOPYDATASTRUCT poCopyData = (PCOPYDATASTRUCT) ulParam; + memset(read_from_pipe, 0, 4096); + memset(messaggio, 0, 4096); + memset(messaggio_2, 0, 4096); - memset(msg_from_skype, '\0', sizeof(msg_from_skype)); - strncpy(msg_from_skype, (const char *) poCopyData->lpData, - sizeof(msg_from_skype) - 2); +#ifdef WIN32 + rt = 1; +#else /* WIN32 */ + fdselect = tech_pvt->SkypiaxHandles.fdesc[0]; + FD_ZERO(&fs); + FD_SET(fdselect, &fs); + to.tv_usec = 2000000; //500 msec + to.tv_sec = 0; + rt = select(fdselect + 1, &fs, NULL, NULL, &to); +#endif /* WIN32 */ - howmany = strlen(msg_from_skype) + 1; -//#if defined(WIN32) && !defined(__CYGWIN__) + if (rt > 0) { + if (tech_pvt->SkypiaxHandles.fdesc[0]) { + howmany = sizeof(read_from_pipe); howmany = - skypiax_pipe_write(tech_pvt->SkypiaxHandles.fdesc[1], (short *) msg_from_skype, - howmany); - //NOTICA("From Skype API: %s\n", SKYPIAX_P_LOG, msg_from_skype); -//#else - //howmany = write(tech_pvt->SkypiaxHandles.fdesc[1], msg_from_skype, howmany); - //NOTICA("From Skype API: %s\n", SKYPIAX_P_LOG, msg_from_skype); -//#endif - lReturnCode = 1; - } - break; - default: - if (tech_pvt && tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) { - if (uiMessage == - tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) { - switch (ulParam) { - case SKYPECONTROLAPI_ATTACH_SUCCESS: - if (!tech_pvt->SkypiaxHandles.api_connected) { - DEBUGA_SKYPE("\n\n\tConnected to Skype API!\n", SKYPIAX_P_LOG); - tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle = (HWND) uiParam; - tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle = - tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle; - } - break; - case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: - DEBUGA_SKYPE - ("\n\n\tIf I do not (almost) immediately connect to Skype API,\n\tplease give the Skype client authorization to be connected \n\tby Asterisk and to not ask you again.\n\n", - SKYPIAX_P_LOG); - skypiax_sleep(5000); - if (!tech_pvt->SkypiaxHandles.api_connected) { - SendMessage(HWND_BROADCAST, - tech_pvt->SkypiaxHandles. - win32_uiGlobal_MsgID_SkypeControlAPIDiscover, - (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, - 0); - } - break; - case SKYPECONTROLAPI_ATTACH_REFUSED: - ERRORA("Skype client refused to be connected by Skypiax!\n", SKYPIAX_P_LOG); - break; - case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: - ERRORA("Skype API not (yet?) available\n", SKYPIAX_P_LOG); - break; - case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: - DEBUGA_SKYPE("Skype API available\n", SKYPIAX_P_LOG); - skypiax_sleep(5000); - if (!tech_pvt->SkypiaxHandles.api_connected) { - SendMessage(HWND_BROADCAST, - tech_pvt->SkypiaxHandles. - win32_uiGlobal_MsgID_SkypeControlAPIDiscover, - (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, - 0); - } - break; - default: - WARNINGA("GOT AN UNKNOWN SKYPE WINDOWS MSG\n", SKYPIAX_P_LOG); - } - lReturnCode = 1; - break; - } - } - fIssueDefProc = 1; - break; - } - if (fIssueDefProc) - lReturnCode = DefWindowProc(hWindow, uiMessage, uiParam, ulParam); - return (lReturnCode); -} + skypiax_pipe_read(tech_pvt->SkypiaxHandles.fdesc[0], (short *) read_from_pipe, + howmany); -int win32_Initialize_CreateWindowClass(private_t * tech_pvt) -{ - unsigned char *paucUUIDString; - RPC_STATUS lUUIDResult; - int fReturnStatus; - UUID oUUID; + a = 0; + for (i = 0; i < howmany; i++) { + messaggio[a] = read_from_pipe[i]; + a++; - fReturnStatus = 0; - lUUIDResult = UuidCreate(&oUUID); - tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle = - (HINSTANCE) OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId()); - if (tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle != NULL - && (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) { - if (UuidToString(&oUUID, &paucUUIDString) == RPC_S_OK) { - WNDCLASS oWindowClass; + if (read_from_pipe[i] == '\0') { - strcpy(tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, "Skype-API-Skypiax-"); - strcat(tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, - (char *) paucUUIDString); + //DEBUGA_SKYPE("read_skype: howmany=%d, i=%d, a=%d, |||%s||| \n", SKYPIAX_P_LOG, howmany, i, a, messaggio); + DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, messaggio); - oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - oWindowClass.lpfnWndProc = (WNDPROC) & skypiax_skype_present; - oWindowClass.cbClsExtra = 0; - oWindowClass.cbWndExtra = 0; - oWindowClass.hInstance = tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle; - oWindowClass.hIcon = NULL; - oWindowClass.hCursor = NULL; - oWindowClass.hbrBackground = NULL; - oWindowClass.lpszMenuName = NULL; - oWindowClass.lpszClassName = tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName; + if (!strcasecmp(messaggio, "ERROR 68")) { /* not yet protocol specified, + just authorized */ + DEBUGA_SKYPE + ("If I don't connect immediately, please give the Skype client authorization to be connected by Skypiax (and to not ask you again)\n", + SKYPIAX_P_LOG); + skypiax_sleep(1000000); + skypiax_skype_write(tech_pvt, "PROTOCOL 6"); + skypiax_sleep(10000); + return 0; + } - if (RegisterClass(&oWindowClass) != 0) - fReturnStatus = 1; + if (!strncasecmp(messaggio, "ERROR 92 CALL", 12)) { + ERRORA("Skype got ERROR: |||%s|||, the number we called was not recognized\n", + SKYPIAX_P_LOG, messaggio); + tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; + if (option_debug) + DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); + tech_pvt->skype_call_id[0] = '\0'; - RpcStringFree(&paucUUIDString); - } - } - if (fReturnStatus == 0) - CloseHandle(tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle), - tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle = NULL; - return (fReturnStatus); -} + if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + } + } -void win32_DeInitialize_DestroyWindowClass(private_t * tech_pvt) -{ - UnregisterClass(tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, - tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle); - CloseHandle(tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle), - tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle = NULL; -} + strncpy(messaggio_2, messaggio, sizeof(messaggio) - 1); -int win32_Initialize_CreateMainWindow(private_t * tech_pvt) -{ - tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = - CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, - tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, "", - WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, - 128, 128, NULL, 0, tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle, - tech_pvt); - return (tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle != NULL ? 1 : 0); -} + buf = messaggio; + stringp = &buf; + where = strsep(stringp, " "); + if (!where) { + WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, messaggio); + } -void win32_DeInitialize_DestroyMainWindow(private_t * tech_pvt) -{ - if (tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle != NULL) - DestroyWindow(tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle), - tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = NULL; -} + if (!strcasecmp(messaggio, "#333")) { + /* DEBUGA_SKYPE("Skype MSG: messaggio_2: %s, messaggio2[11]: %s\n", SKYPIAX_P_LOG, + * messaggio_2, &messaggio_2[11]); */ + memset(tech_pvt->skype_friends, 0, 4096); + strncpy(tech_pvt->skype_friends, &messaggio_2[11], 4095); + } + if (!strcasecmp(messaggio, "#222")) { + /* DEBUGA_SKYPE("Skype MSG: messaggio_2: %s, messaggio2[10]: %s\n", SKYPIAX_P_LOG, + * messaggio_2, &messaggio_2[10]); */ + memset(tech_pvt->skype_fullname, 0, 512); + strncpy(tech_pvt->skype_fullname, &messaggio_2[10], 511); + } + if (!strcasecmp(messaggio, "#765")) { + /* DEBUGA_SKYPE("Skype MSG: messaggio_2: %s, messaggio2[10]: %s\n", SKYPIAX_P_LOG, + * messaggio_2, &messaggio_2[10]); */ + memset(tech_pvt->skype_displayname, 0, 512); + strncpy(tech_pvt->skype_displayname, &messaggio_2[10], 511); + } + if (!strcasecmp(messaggio, "ERROR")) { + ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, messaggio); + tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; + if (option_debug) + DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); + tech_pvt->skype_call_id[0] = '\0'; -DWORD win32_dwThreadId; + if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + } + } + if (!strcasecmp(messaggio, "CURRENTUSERHANDLE")) { + strncpy(obj, where, sizeof(obj) - 1); -void *skypiax_do_skypeapi_thread_func(void *obj) -{ - /* create window class */ - /* create dummy/hidden window for processing messages */ - /* run message loop thread */ - /* do application control until exit */ - /* exit: send QUIT message to our own window */ - /* wait until thred terminates */ - /* destroy main window */ - /* destroy window class */ + where = strsep(stringp, " "); - private_t *tech_pvt = obj; -#if defined(WIN32) && !defined(__CYGWIN__) - switch_status_t rv; + strncpy(id, where, sizeof(id) - 1); - switch_file_pipe_create(&tech_pvt->SkypiaxHandles.fdesc[0], - &tech_pvt->SkypiaxHandles.fdesc[1], skypiax_module_pool); - rv = - switch_file_pipe_create(&tech_pvt->SkypiaxHandles.fdesc[0], - &tech_pvt->SkypiaxHandles.fdesc[1], skypiax_module_pool); -#else /* WIN32 */ - if (pipe(tech_pvt->SkypiaxHandles.fdesc)) { - fcntl(tech_pvt->SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK); - } -#endif /* WIN32 */ + if (!strcasecmp(id, tech_pvt->skype_user)) { + tech_pvt->SkypiaxHandles.api_connected = 1; + DEBUGA_SKYPE + ("Skype MSG: messaggio: %s, currentuserhandle: %s, cuh: %s, skype_user: %s!\n", + SKYPIAX_P_LOG, messaggio, obj, id, tech_pvt->skype_user); + } + } - tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach = - RegisterWindowMessage("SkypeControlAPIAttach"); - tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover = - RegisterWindowMessage("SkypeControlAPIDiscover"); + if (!strcasecmp(messaggio, "USER")) { + strncpy(obj, where, sizeof(obj) - 1); - skypiax_sleep(2000000); + where = strsep(stringp, " "); - if (tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0 - && tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { - if (win32_Initialize_CreateWindowClass(tech_pvt)) { - if (win32_Initialize_CreateMainWindow(tech_pvt)) { - if (SendMessage - (HWND_BROADCAST, - tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover, - (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, 0) != 0) { - tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = - tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle; - while (1) { - MSG oMessage; - if (!running) - break; - while (GetMessage(&oMessage, 0, 0, 0)) { - TranslateMessage(&oMessage); - DispatchMessage(&oMessage); - } - } - } - win32_DeInitialize_DestroyMainWindow(tech_pvt); - } - win32_DeInitialize_DestroyWindowClass(tech_pvt); - } - } + strncpy(id, where, sizeof(id) - 1); - return NULL; -} + where = strsep(stringp, " "); -#else /* NOT WIN32 */ + strncpy(prop, where, sizeof(prop) - 1); -int X11_errors_handler(Display * dpy, XErrorEvent * err) -{ - (void) dpy; - private_t *tech_pvt = NULL; + if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) { + char msg_to_skype[256]; + DEBUGA_SKYPE("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s!\n", + SKYPIAX_P_LOG, messaggio, obj, id, prop); - xerror = err->error_code; - ERRORA("Received error code %d from X Server\n\n", SKYPIAX_P_LOG, xerror); - return 0; /* ignore the error */ -} + //FIXME: TODO: allow authorization based on config param + sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + } + } -static void X11_errors_trap(void) -{ - xerror = 0; - old_handler = XSetErrorHandler(X11_errors_handler); -} + if (!strcasecmp(messaggio, "MESSAGE")) { + strncpy(obj, where, sizeof(obj) - 1); -static int X11_errors_untrap(void) -{ - XSetErrorHandler(old_handler); - return (xerror != BadValue) && (xerror != BadWindow); -} + where = strsep(stringp, " "); -int skypiax_skype_send_message(struct SkypiaxHandles *SkypiaxHandles, - const char *message_P) -{ + strncpy(id, where, sizeof(id) - 1); - Window w_P; - Display *disp; - Window handle_P; - int ok; - private_t *tech_pvt = NULL; + where = strsep(stringp, " "); - w_P = SkypiaxHandles->skype_win; - disp = SkypiaxHandles->disp; - handle_P = SkypiaxHandles->win; + strncpy(prop, where, sizeof(prop) - 1); - 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; + if (!strcasecmp(prop, "STATUS")) { - 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; + where = strsep(stringp, " "); - 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); + strncpy(value, where, sizeof(value) - 1); - e.xclient.message_type = atom2; /* following messages */ - pos += i; - } while (pos <= len); + if (!strcasecmp(value, "RECEIVED")) { + char msg_to_skype[256]; + DEBUGA_SKYPE + ("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s value: %s!\n", + SKYPIAX_P_LOG, messaggio, obj, id, prop, value); - XSync(disp, False); - ok = X11_errors_untrap(); + //FIXME: TODO: allow authorization based on config param + sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + } + } else if (!strcasecmp(prop, "BODY")) { + char msg_to_skype[256]; - if (!ok) - ERRORA("Sending message failed with status %d\n", SKYPIAX_P_LOG, xerror); - //XUnlockDisplay(disp); + DEBUGA_SKYPE("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s!\n", + SKYPIAX_P_LOG, messaggio, obj, id, prop); - return 1; -} + //FIXME: TODO: on config param ??? + sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + } -int skypiax_skype_present(struct SkypiaxHandles *SkypiaxHandles) -{ - Atom skype_inst = XInternAtom(SkypiaxHandles->disp, "_SKYPE_INSTANCE", True); + } - Atom type_ret; - int format_ret; - unsigned long nitems_ret; - unsigned long bytes_after_ret; - unsigned char *prop; - int status; - private_t *tech_pvt = NULL; + if (!strcasecmp(messaggio, "CALL")) { - X11_errors_trap(); - //XLockDisplay(disp); - status = - XGetWindowProperty(SkypiaxHandles->disp, DefaultRootWindow(SkypiaxHandles->disp), - skype_inst, 0, 1, False, XA_WINDOW, &type_ret, &format_ret, - &nitems_ret, &bytes_after_ret, &prop); - //XUnlockDisplay(disp); - X11_errors_untrap(); + strncpy(obj, where, sizeof(obj) - 1); - /* sanity check */ - if (status != Success || format_ret != 32 || nitems_ret != 1) { - SkypiaxHandles->skype_win = (Window) - 1; - DEBUGA_SKYPE("Skype instance not found\n", SKYPIAX_P_LOG); - return 0; - } + where = strsep(stringp, " "); - SkypiaxHandles->skype_win = *(const unsigned long *) prop & 0xffffffff; - DEBUGA_SKYPE("Skype instance found with id #%d\n", SKYPIAX_P_LOG, - (unsigned int) SkypiaxHandles->skype_win); - return 1; -} + strncpy(id, where, sizeof(id) - 1); -void skypiax_skype_clean_disp(void *data) -{ + where = strsep(stringp, " "); - int *dispptr; - int disp; - private_t *tech_pvt = NULL; + strncpy(prop, where, sizeof(prop) - 1); - dispptr = data; - disp = *dispptr; + where = strsep(stringp, " "); - 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); - skypiax_sleep(1000); -} - -void *skypiax_do_skypeapi_thread_func(void *obj) -{ - - private_t *tech_pvt = obj; - struct SkypiaxHandles *SkypiaxHandles; - char buf[512]; - Display *disp = NULL; - Window root = -1; - Window win = -1; - - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - - if (!strlen(tech_pvt->X11_display)) - strcpy(tech_pvt->X11_display, getenv("DISPLAY")); - - if (!tech_pvt->tcp_srv_port) - tech_pvt->tcp_srv_port = 10160; - - if (!tech_pvt->tcp_cli_port) - tech_pvt->tcp_cli_port = 10161; + strncpy(value, where, sizeof(value) - 1); - if (pipe(tech_pvt->SkypiaxHandles.fdesc)) { - fcntl(tech_pvt->SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK); - fcntl(tech_pvt->SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK); - } - SkypiaxHandles = &tech_pvt->SkypiaxHandles; - disp = XOpenDisplay(tech_pvt->X11_display); - if (!disp) { - ERRORA("Cannot open X Display '%s', exiting skype thread\n", SKYPIAX_P_LOG, - tech_pvt->X11_display); - running = 0; - return NULL; - } else { - DEBUGA_SKYPE("X Display '%s' opened\n", SKYPIAX_P_LOG, tech_pvt->X11_display); - } + where = strsep(stringp, " "); - int xfd; - xfd = XConnectionNumber(disp); - fcntl(xfd, F_SETFD, FD_CLOEXEC); + if (option_debug > 101) + DEBUGA_SKYPE + ("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n", + SKYPIAX_P_LOG, messaggio, obj, id, prop, value, where ? where : "NULL"); - //FIXME pthread_cleanup_push(skypiax_skype_clean_disp, &xfd); + if (!strcasecmp(prop, "PARTNER_HANDLE")) { + strncpy(tech_pvt->callid_number, value, + sizeof(tech_pvt->callid_number) - 1); + DEBUGA_SKYPE + ("the skype_call %s caller PARTNER_HANDLE (tech_pvt->callid_number) is: %s\n", + SKYPIAX_P_LOG, id, tech_pvt->callid_number); + return CALLFLOW_INCOMING_RING; + } + if (!strcasecmp(prop, "PARTNER_DISPNAME")) { + snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s", + value, where ? " " : "", where ? where : ""); + DEBUGA_SKYPE + ("the skype_call %s caller PARTNER_DISPNAME (tech_pvt->callid_name) is: %s\n", + SKYPIAX_P_LOG, id, tech_pvt->callid_name); + } + if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) { + DEBUGA_SKYPE("the skype_call %s is NOT a conference call\n", SKYPIAX_P_LOG, + id); + if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN) + tech_pvt->interface_state = SKYPIAX_STATE_PRERING; + } + if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) { + DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPIAX_P_LOG, id); + if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN) + tech_pvt->interface_state = SKYPIAX_STATE_PRERING; + } - SkypiaxHandles->disp = disp; + if (!strcasecmp(prop, "DTMF")) { - if (skypiax_skype_present(SkypiaxHandles)) { - root = DefaultRootWindow(disp); - win = - XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, - BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, - DefaultScreen - (disp))); + DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value); - SkypiaxHandles->win = win; + dtmf_received(tech_pvt, value); + } - snprintf(buf, 512, "NAME skypiax"); + if (!strcasecmp(prop, "FAILUREREASON")) { + DEBUGA_SKYPE + ("Skype has FAILED on skype_call %s. Let's wait for the FAILED message.\n", + SKYPIAX_P_LOG, id); + } + if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) { + if (strcasecmp(id, tech_pvt->skype_call_id)) { + strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + if (option_debug > 1) + DEBUGA_SKYPE + ("We called a Skype contact and he answered us on skype_call: %s.\n", + SKYPIAX_P_LOG, id); + } + } - if (!skypiax_skype_send_message(SkypiaxHandles, buf)) { - ERRORA - ("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n", - SKYPIAX_P_LOG); - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - running = 0; - return NULL; - } + if (!strcasecmp(prop, "STATUS")) { - snprintf(buf, 512, "PROTOCOL 6"); - if (!skypiax_skype_send_message(SkypiaxHandles, buf)) { - ERRORA - ("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n", - SKYPIAX_P_LOG); - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - running = 0; - return NULL; - } + if (!strcasecmp(value, "RINGING")) { + char msg_to_skype[1024]; + if (tech_pvt->interface_state != SKYPIAX_STATE_DIALING) { + /* we are not calling out */ - /* perform an events loop */ - XEvent an_event; - char buf[21]; /* can't be longer */ - char buffer[17000]; - char *b; - int i; + if (!strlen(tech_pvt->skype_call_id)) { //FIXME + /* we are not inside an active call */ + tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; + tech_pvt->interface_state = SKYPIAX_STATE_RING; + /* no owner, no active call, let's answer */ + skypiax_skype_write(tech_pvt, "SET AGC OFF"); + skypiax_sleep(10000); + skypiax_skype_write(tech_pvt, "SET AEC OFF"); + skypiax_sleep(10000); + sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + skypiax_sleep(10000); + sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + skypiax_sleep(10000); + sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + if (option_debug) + DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", + SKYPIAX_P_LOG, id); + strncpy(tech_pvt->skype_call_id, id, + sizeof(tech_pvt->skype_call_id) - 1); + } else { + /* we're owned, we're in a call, let's refuse */ + sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); + skypiax_skype_write(tech_pvt, msg_to_skype); + skypiax_sleep(10000); + DEBUGA_SKYPE + ("We have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n", + SKYPIAX_P_LOG, id); - b = buffer; + } + } else { + /* we are calling out */ + tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; + tech_pvt->interface_state = SKYPIAX_STATE_RINGING; + //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING); + 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", + SKYPIAX_P_LOG, id); + } + } else if (!strcasecmp(value, "EARLYMEDIA")) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA; + tech_pvt->interface_state = SKYPIAX_STATE_DIALING; + //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING); + DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n", + SKYPIAX_P_LOG, id); + } else if (!strcasecmp(value, "MISSED")) { + DEBUGA_SKYPE("We missed skype_call %s\n", SKYPIAX_P_LOG, id); - while (1) { - XNextEvent(disp, &an_event); - if (!running) - break; - switch (an_event.type) { - case ClientMessage: + } else if (!strcasecmp(value, "FINISHED")) { + //tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; + if (option_debug) + DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id); + tech_pvt->skype_call_id[0] = '\0'; - if (an_event.xclient.format != 8) - break; + if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + //tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + } - for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i) - buf[i] = an_event.xclient.data.b[i]; + } else if (!strcasecmp(value, "CANCELLED")) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED; + if (option_debug) + DEBUGA_SKYPE + ("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n", + SKYPIAX_P_LOG, id); + tech_pvt->skype_call_id[0] = '\0'; - buf[i] = '\0'; + if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + } + } else if (!strcasecmp(value, "FAILED")) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED; + if (option_debug) + DEBUGA_SKYPE + ("we tried to call Skype on skype_call %s and Skype has now FAILED\n", + SKYPIAX_P_LOG, id); + tech_pvt->skype_call_id[0] = '\0'; + strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return CALLFLOW_INCOMING_HANGUP; + } else if (!strcasecmp(value, "REFUSED")) { + if (!strcasecmp(id, tech_pvt->skype_call_id)) { + /* this is the id of the call we are in, probably we generated it */ + tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED; + if (option_debug) + DEBUGA_SKYPE + ("we tried to call Skype on skype_call %s and Skype has now REFUSED\n", + SKYPIAX_P_LOG, id); + strncpy(tech_pvt->skype_call_id, id, + sizeof(tech_pvt->skype_call_id) - 1); + tech_pvt->interface_state = SKYPIAX_STATE_DOWN; + tech_pvt->skype_call_id[0] = '\0'; + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return CALLFLOW_INCOMING_HANGUP; + } else { + /* we're here because were us that refused an incoming call */ + DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPIAX_P_LOG, id); - strcat(buffer, buf); + } + } else if (!strcasecmp(value, "ROUTING")) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING; + tech_pvt->interface_state = SKYPIAX_STATE_DIALING; + strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id); + } else if (!strcasecmp(value, "UNPLACED")) { + tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED; + tech_pvt->interface_state = SKYPIAX_STATE_DIALING; + strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id); + } else if (!strcasecmp(value, "INPROGRESS")) { + char msg_to_skype[1024]; + tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); + tech_pvt->interface_state = SKYPIAX_STATE_UP; + DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id); + sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, + tech_pvt->tcp_cli_port); + skypiax_skype_write(tech_pvt, msg_to_skype); + start_audio_threads(tech_pvt); + sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, + tech_pvt->tcp_srv_port); + skypiax_skype_write(tech_pvt, msg_to_skype); - if (i < 20) { /* last fragment */ - unsigned int howmany; + tech_pvt->skype_callflow = SKYPIAX_STATE_UP; - howmany = strlen(b) + 1; + if (!strlen(tech_pvt->session_uuid_str)) { + DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG); + new_inbound_channel(tech_pvt); + } else { + DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG); + outbound_channel_answered(tech_pvt); + } - howmany = write(SkypiaxHandles->fdesc[1], b, howmany); - memset(buffer, '\0', 17000); - } + } else { + WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, + id, value); + + } + } //STATUS + + } //CALL + + a = 0; + } //message end + } //read_from_pipe - break; - default: - break; - } } - } else { - ERRORA - ("Skype is not running, maybe crashed. Please run/restart Skype and relaunch Skypiax\n", - SKYPIAX_P_LOG); - running = 0; - return NULL; } - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - running = 0; - return NULL; + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + return 0; } -#endif // WIN32 -int skypiax_skype_write(private_t * tech_pvt, char *msg_to_skype) +int skypiax_skype_senddigit(private_t * tech_pvt, char digit) +{ + char msg_to_skype[1024]; + if (option_debug > 10) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + + DEBUGA_SKYPE("DIGIT received: %c\n", SKYPIAX_P_LOG, digit); + + sprintf(msg_to_skype, "SET CALL %s DTMF %c", tech_pvt->skype_call_id, digit); + + skypiax_skype_write(tech_pvt, msg_to_skype); + + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return 0; +} + +int skypiax_skype_call(private_t * tech_pvt, char *rdest, int timeout) { + char msg_to_skype[1024]; + + if (option_debug > 10) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + skypiax_sleep(5000); + DEBUGA_SKYPE("Calling Skype, rdest is: %s\n", SKYPIAX_P_LOG, rdest); + skypiax_skype_write(tech_pvt, "SET AGC OFF"); + skypiax_sleep(10000); + skypiax_skype_write(tech_pvt, "SET AEC OFF"); + skypiax_sleep(10000); + + sprintf(msg_to_skype, "CALL %s", rdest); + if (skypiax_skype_write(tech_pvt, msg_to_skype) < 0) { + + ERRORA("failed to communicate with Skype client, now exit\n", SKYPIAX_P_LOG); + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return -1; + } + return 0; +} + + + #ifdef WIN32 + +enum { + SKYPECONTROLAPI_ATTACH_SUCCESS = 0, /* Client is successfully + attached and API window handle can be found + in wParam parameter */ + SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1, /* Skype has acknowledged + connection request and is waiting + for confirmation from the user. */ + /* The client is not yet attached + * and should wait for SKYPECONTROLAPI_ATTACH_SUCCESS message */ + SKYPECONTROLAPI_ATTACH_REFUSED = 2, /* User has explicitly + denied access to client */ + SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE = 3, /* API is not available + at the moment. + For example, this happens when no user + is currently logged in. */ + /* Client should wait for + * SKYPECONTROLAPI_ATTACH_API_AVAILABLE + * broadcast before making any further */ + /* connection attempts. */ + SKYPECONTROLAPI_ATTACH_API_AVAILABLE = 0x8001 +}; + +/* Visual C do not have strsep? */ +char + *strsep(char **stringp, const char *delim) +{ + char *res; + + if (!stringp || !*stringp || !**stringp) + return (char *) 0; + + res = *stringp; + while (**stringp && !strchr(delim, **stringp)) + ++(*stringp); + + if (**stringp) { + **stringp = '\0'; + ++(*stringp); + } + + return res; +} + +int skypiax_skype_write(private_t * tech_pvt, char *msg_to_skype) +{ static char acInputRow[1024]; COPYDATASTRUCT oCopyData; -#else /* WIN32 */ - struct SkypiaxHandles *SkypiaxHandles; -#endif /* WIN32 */ DEBUGA_SKYPE("SENDING: |||%s||||\n", SKYPIAX_P_LOG, msg_to_skype); -#ifdef WIN32 - if (option_debug > 100) { DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); } @@ -1003,7 +1011,7 @@ (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, (LPARAM) & oCopyData) == FALSE) { ERRORA - ("Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypiax (Asterisk), then restart Skype from the menu, then launch Skypiax and try again.\n", + ("Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypiax, then launch Skypiax and try again.\n", SKYPIAX_P_LOG); if (option_debug > 100) { DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); @@ -1011,23 +1019,6 @@ return -1; } } -#else /* WIN32 */ - - if (option_debug > 100) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - } - SkypiaxHandles = &tech_pvt->SkypiaxHandles; - - if (!skypiax_skype_send_message(SkypiaxHandles, msg_to_skype)) { - ERRORA - ("Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypiax (Asterisk), then restart Skype from the menu, then launch Skypiax and try again.\n", - SKYPIAX_P_LOG); - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return -1; - } -#endif /* WIN32 */ if (option_debug > 100) { DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); @@ -1036,507 +1027,508 @@ } -int skypiax_skype_read(private_t * tech_pvt) +LRESULT APIENTRY skypiax_skype_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, + LPARAM ulParam) { + LRESULT lReturnCode; + int fIssueDefProc; + private_t *tech_pvt = NULL; - char read_from_pipe[4096]; - char messaggio[4096]; - char messaggio_2[4096]; - char *buf, obj[512] = "", id[512] = "", prop[512] = "", value[512] = "", *where; - char **stringp = NULL; - int rt; - int a; - unsigned int howmany; - unsigned int i; -#ifndef WIN32 - int fdselect; - fd_set fs; - struct timeval to; -#endif /* WIN32 */ - - if (option_debug > 100) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - } + lReturnCode = 0; + fIssueDefProc = 0; + tech_pvt = (private_t *) GetWindowLong(hWindow, GWL_USERDATA); + switch (uiMessage) { + case WM_CREATE: + tech_pvt = (private_t *) ((LPCREATESTRUCT) ulParam)->lpCreateParams; + SetWindowLong(hWindow, GWL_USERDATA, (LONG) tech_pvt); + DEBUGA_SKYPE("got CREATE\n", SKYPIAX_P_LOG); + break; + case WM_DESTROY: + NOTICA("got DESTROY\n", SKYPIAX_P_LOG); + tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = NULL; + PostQuitMessage(0); + break; + case WM_COPYDATA: + if (tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle == (HWND) uiParam) { + unsigned int howmany; + char msg_from_skype[2048]; - memset(read_from_pipe, 0, 4096); - memset(messaggio, 0, 4096); - memset(messaggio_2, 0, 4096); + PCOPYDATASTRUCT poCopyData = (PCOPYDATASTRUCT) ulParam; -#ifdef WIN32 - rt = 1; -#else /* WIN32 */ - fdselect = tech_pvt->SkypiaxHandles.fdesc[0]; - FD_ZERO(&fs); - FD_SET(fdselect, &fs); - to.tv_usec = 2000000; //500 msec - to.tv_sec = 0; - rt = select(fdselect + 1, &fs, NULL, NULL, &to); -#endif /* WIN32 */ + memset(msg_from_skype, '\0', sizeof(msg_from_skype)); + strncpy(msg_from_skype, (const char *) poCopyData->lpData, + sizeof(msg_from_skype) - 2); - if (rt > 0) { - if (tech_pvt->SkypiaxHandles.fdesc[0]) { - howmany = sizeof(read_from_pipe); + howmany = strlen(msg_from_skype) + 1; howmany = - skypiax_pipe_read(tech_pvt->SkypiaxHandles.fdesc[0], (short *) read_from_pipe, - howmany); - - a = 0; - for (i = 0; i < howmany; i++) { - messaggio[a] = read_from_pipe[i]; - a++; - - if (read_from_pipe[i] == '\0') { - - //DEBUGA_SKYPE("read_skype: howmany=%d, i=%d, a=%d, |||%s||| \n", SKYPIAX_P_LOG, howmany, i, a, messaggio); - DEBUGA_SKYPE("READING: |||%s||| \n", SKYPIAX_P_LOG, messaggio); - - if (!strcasecmp(messaggio, "ERROR 68")) { /* not yet protocol specified, - just authorized */ - DEBUGA_SKYPE - ("If I don't connect immediately, please give the Skype client authorization to be connected by Skypiax (and to not ask you again)\n", - SKYPIAX_P_LOG); - skypiax_sleep(1000000); - skypiax_skype_write(tech_pvt, "PROTOCOL 6"); - skypiax_sleep(10000); - return 0; - } - - if (!strncasecmp(messaggio, "ERROR 92 CALL", 12)) { - ERRORA("Skype got ERROR: |||%s|||, the number we called was not recognized\n", - SKYPIAX_P_LOG, messaggio); - tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; - if (option_debug) - DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); - tech_pvt->skype_call_id[0] = '\0'; - - if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - } - } - - strncpy(messaggio_2, messaggio, sizeof(messaggio) - 1); - - buf = messaggio; - stringp = &buf; - where = strsep(stringp, " "); - if (!where) { - WARNINGA("Skype MSG without spaces: %s\n", SKYPIAX_P_LOG, messaggio); - } - - if (!strcasecmp(messaggio, "#333")) { - /* DEBUGA_SKYPE("Skype MSG: messaggio_2: %s, messaggio2[11]: %s\n", SKYPIAX_P_LOG, - * messaggio_2, &messaggio_2[11]); */ - memset(tech_pvt->skype_friends, 0, 4096); - strncpy(tech_pvt->skype_friends, &messaggio_2[11], 4095); - } - if (!strcasecmp(messaggio, "#222")) { - /* DEBUGA_SKYPE("Skype MSG: messaggio_2: %s, messaggio2[10]: %s\n", SKYPIAX_P_LOG, - * messaggio_2, &messaggio_2[10]); */ - memset(tech_pvt->skype_fullname, 0, 512); - strncpy(tech_pvt->skype_fullname, &messaggio_2[10], 511); - } - if (!strcasecmp(messaggio, "#765")) { - /* DEBUGA_SKYPE("Skype MSG: messaggio_2: %s, messaggio2[10]: %s\n", SKYPIAX_P_LOG, - * messaggio_2, &messaggio_2[10]); */ - memset(tech_pvt->skype_displayname, 0, 512); - strncpy(tech_pvt->skype_displayname, &messaggio_2[10], 511); + skypiax_pipe_write(tech_pvt->SkypiaxHandles.fdesc[1], (short *) msg_from_skype, + howmany); + //NOTICA("From Skype API: %s\n", SKYPIAX_P_LOG, msg_from_skype); + lReturnCode = 1; + } + break; + default: + if (tech_pvt && tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) { + if (uiMessage == + tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach) { + switch (ulParam) { + case SKYPECONTROLAPI_ATTACH_SUCCESS: + if (!tech_pvt->SkypiaxHandles.api_connected) { + DEBUGA_SKYPE("\n\n\tConnected to Skype API!\n", SKYPIAX_P_LOG); + tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle = (HWND) uiParam; + tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle = + tech_pvt->SkypiaxHandles.win32_hGlobal_SkypeAPIWindowHandle; } - if (!strcasecmp(messaggio, "ERROR")) { - ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, messaggio); - tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; - if (option_debug) - DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); - tech_pvt->skype_call_id[0] = '\0'; - - if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - } + break; + case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: + DEBUGA_SKYPE + ("\n\n\tIf I do not (almost) immediately connect to Skype API,\n\tplease give the Skype client authorization to be connected \n\tby Asterisk and to not ask you again.\n\n", + SKYPIAX_P_LOG); + skypiax_sleep(5000); + if (!tech_pvt->SkypiaxHandles.api_connected) { + SendMessage(HWND_BROADCAST, + tech_pvt->SkypiaxHandles. + win32_uiGlobal_MsgID_SkypeControlAPIDiscover, + (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, + 0); } - if (!strcasecmp(messaggio, "CURRENTUSERHANDLE")) { - strncpy(obj, where, sizeof(obj) - 1); - - where = strsep(stringp, " "); - - strncpy(id, where, sizeof(id) - 1); - - if (!strcasecmp(id, tech_pvt->skype_user)) { - tech_pvt->SkypiaxHandles.api_connected = 1; - DEBUGA_SKYPE - ("Skype MSG: messaggio: %s, currentuserhandle: %s, cuh: %s, skype_user: %s!\n", - SKYPIAX_P_LOG, messaggio, obj, id, tech_pvt->skype_user); - } + break; + case SKYPECONTROLAPI_ATTACH_REFUSED: + ERRORA("Skype client refused to be connected by Skypiax!\n", SKYPIAX_P_LOG); + break; + case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: + ERRORA("Skype API not (yet?) available\n", SKYPIAX_P_LOG); + break; + case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: + DEBUGA_SKYPE("Skype API available\n", SKYPIAX_P_LOG); + skypiax_sleep(5000); + if (!tech_pvt->SkypiaxHandles.api_connected) { + SendMessage(HWND_BROADCAST, + tech_pvt->SkypiaxHandles. + win32_uiGlobal_MsgID_SkypeControlAPIDiscover, + (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, + 0); } + break; + default: + WARNINGA("GOT AN UNKNOWN SKYPE WINDOWS MSG\n", SKYPIAX_P_LOG); + } + lReturnCode = 1; + break; + } + } + fIssueDefProc = 1; + break; + } + if (fIssueDefProc) + lReturnCode = DefWindowProc(hWindow, uiMessage, uiParam, ulParam); + return (lReturnCode); +} - if (!strcasecmp(messaggio, "USER")) { - strncpy(obj, where, sizeof(obj) - 1); - - where = strsep(stringp, " "); +int win32_Initialize_CreateWindowClass(private_t * tech_pvt) +{ + unsigned char *paucUUIDString; + RPC_STATUS lUUIDResult; + int fReturnStatus; + UUID oUUID; - strncpy(id, where, sizeof(id) - 1); + fReturnStatus = 0; + lUUIDResult = UuidCreate(&oUUID); + tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle = + (HINSTANCE) OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId()); + if (tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle != NULL + && (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) { + if (UuidToString(&oUUID, &paucUUIDString) == RPC_S_OK) { + WNDCLASS oWindowClass; - where = strsep(stringp, " "); + strcpy(tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, "Skype-API-Skypiax-"); + strcat(tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, + (char *) paucUUIDString); - strncpy(prop, where, sizeof(prop) - 1); + oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + oWindowClass.lpfnWndProc = (WNDPROC) & skypiax_skype_present; + oWindowClass.cbClsExtra = 0; + oWindowClass.cbWndExtra = 0; + oWindowClass.hInstance = tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle; + oWindowClass.hIcon = NULL; + oWindowClass.hCursor = NULL; + oWindowClass.hbrBackground = NULL; + oWindowClass.lpszMenuName = NULL; + oWindowClass.lpszClassName = tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName; - if (!strcasecmp(prop, "RECEIVEDAUTHREQUEST")) { - char msg_to_skype[256]; - DEBUGA_SKYPE("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s!\n", - SKYPIAX_P_LOG, messaggio, obj, id, prop); + if (RegisterClass(&oWindowClass) != 0) + fReturnStatus = 1; - //FIXME: TODO: allow authorization based on config param - sprintf(msg_to_skype, "SET USER %s ISAUTHORIZED TRUE", id); - skypiax_skype_write(tech_pvt, msg_to_skype); - } - } + RpcStringFree(&paucUUIDString); + } + } + if (fReturnStatus == 0) + CloseHandle(tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle), + tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle = NULL; + return (fReturnStatus); +} - if (!strcasecmp(messaggio, "MESSAGE")) { - strncpy(obj, where, sizeof(obj) - 1); +void win32_DeInitialize_DestroyWindowClass(private_t * tech_pvt) +{ + UnregisterClass(tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, + tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle); + CloseHandle(tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle), + tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle = NULL; +} - where = strsep(stringp, " "); +int win32_Initialize_CreateMainWindow(private_t * tech_pvt) +{ + tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = + CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, + tech_pvt->SkypiaxHandles.win32_acInit_WindowClassName, "", + WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, + 128, 128, NULL, 0, tech_pvt->SkypiaxHandles.win32_hInit_ProcessHandle, + tech_pvt); + return (tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle != NULL ? 1 : 0); +} - strncpy(id, where, sizeof(id) - 1); +void win32_DeInitialize_DestroyMainWindow(private_t * tech_pvt) +{ + if (tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle != NULL) + DestroyWindow(tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle), + tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = NULL; +} - where = strsep(stringp, " "); - strncpy(prop, where, sizeof(prop) - 1); +void *skypiax_do_skypeapi_thread_func(void *obj) +{ + private_t *tech_pvt = obj; +#if defined(WIN32) && !defined(__CYGWIN__) + switch_status_t rv; - if (!strcasecmp(prop, "STATUS")) { + switch_file_pipe_create(&tech_pvt->SkypiaxHandles.fdesc[0], + &tech_pvt->SkypiaxHandles.fdesc[1], skypiax_module_pool); + rv = + switch_file_pipe_create(&tech_pvt->SkypiaxHandles.fdesc[0], + &tech_pvt->SkypiaxHandles.fdesc[1], skypiax_module_pool); +#else /* WIN32 */ + if (pipe(tech_pvt->SkypiaxHandles.fdesc)) { + fcntl(tech_pvt->SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK); + fcntl(tech_pvt->SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK); + } +#endif /* WIN32 */ - where = strsep(stringp, " "); + tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach = + RegisterWindowMessage("SkypeControlAPIAttach"); + tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover = + RegisterWindowMessage("SkypeControlAPIDiscover"); - strncpy(value, where, sizeof(value) - 1); + skypiax_sleep(2000000); - if (!strcasecmp(value, "RECEIVED")) { - char msg_to_skype[256]; - DEBUGA_SKYPE - ("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s value: %s!\n", - SKYPIAX_P_LOG, messaggio, obj, id, prop, value); - - //FIXME: TODO: allow authorization based on config param - sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id); - skypiax_skype_write(tech_pvt, msg_to_skype); - } - } else if (!strcasecmp(prop, "BODY")) { - char msg_to_skype[256]; - - DEBUGA_SKYPE("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s!\n", - SKYPIAX_P_LOG, messaggio, obj, id, prop); - - //FIXME: TODO: on config param ??? - sprintf(msg_to_skype, "SET MESSAGE %s SEEN", id); - skypiax_skype_write(tech_pvt, msg_to_skype); + if (tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0 + && tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { + if (win32_Initialize_CreateWindowClass(tech_pvt)) { + if (win32_Initialize_CreateMainWindow(tech_pvt)) { + if (SendMessage + (HWND_BROADCAST, + tech_pvt->SkypiaxHandles.win32_uiGlobal_MsgID_SkypeControlAPIDiscover, + (WPARAM) tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle, 0) != 0) { + tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle = + tech_pvt->SkypiaxHandles.win32_hInit_MainWindowHandle; + while (1) { + MSG oMessage; + if (!running) + break; + while (GetMessage(&oMessage, 0, 0, 0)) { + TranslateMessage(&oMessage); + DispatchMessage(&oMessage); } - } + } + win32_DeInitialize_DestroyMainWindow(tech_pvt); + } + win32_DeInitialize_DestroyWindowClass(tech_pvt); + } + } - if (!strcasecmp(messaggio, "CALL")) { - - strncpy(obj, where, sizeof(obj) - 1); - - where = strsep(stringp, " "); - - strncpy(id, where, sizeof(id) - 1); - - where = strsep(stringp, " "); - - strncpy(prop, where, sizeof(prop) - 1); - - where = strsep(stringp, " "); - - strncpy(value, where, sizeof(value) - 1); - - where = strsep(stringp, " "); - - if (option_debug > 101) - DEBUGA_SKYPE - ("Skype MSG: messaggio: %s, obj: %s, id: %s, prop: %s, value: %s,where: %s!\n", - SKYPIAX_P_LOG, messaggio, obj, id, prop, value, where ? where : "NULL"); - - if (!strcasecmp(prop, "PARTNER_HANDLE")) { - strncpy(tech_pvt->callid_number, value, - sizeof(tech_pvt->callid_number) - 1); - DEBUGA_SKYPE - ("the skype_call %s caller PARTNER_HANDLE (tech_pvt->callid_number) is: %s\n", - SKYPIAX_P_LOG, id, tech_pvt->callid_number); - return CALLFLOW_INCOMING_RING; - } - if (!strcasecmp(prop, "PARTNER_DISPNAME")) { - snprintf(tech_pvt->callid_name, sizeof(tech_pvt->callid_name) - 1, "%s%s%s", - value, where ? " " : "", where ? where : ""); - DEBUGA_SKYPE - ("the skype_call %s caller PARTNER_DISPNAME (tech_pvt->callid_name) is: %s\n", - SKYPIAX_P_LOG, id, tech_pvt->callid_name); - } - if (!strcasecmp(prop, "CONF_ID") && !strcasecmp(value, "0")) { - DEBUGA_SKYPE("the skype_call %s is NOT a conference call\n", SKYPIAX_P_LOG, - id); - if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN) - tech_pvt->interface_state = SKYPIAX_STATE_PRERING; - } - if (!strcasecmp(prop, "CONF_ID") && strcasecmp(value, "0")) { - DEBUGA_SKYPE("the skype_call %s is a conference call\n", SKYPIAX_P_LOG, id); - if (tech_pvt->interface_state == SKYPIAX_STATE_DOWN) - tech_pvt->interface_state = SKYPIAX_STATE_PRERING; - } - - if (!strcasecmp(prop, "DTMF")) { - - DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value); - - dtmf_received(tech_pvt, value); - } - - if (!strcasecmp(prop, "FAILUREREASON")) { - DEBUGA_SKYPE - ("Skype has FAILED on skype_call %s. Let's wait for the FAILED message.\n", - SKYPIAX_P_LOG, id); - } - if (!strcasecmp(prop, "DURATION") && (!strcasecmp(value, "1"))) { - if (strcasecmp(id, tech_pvt->skype_call_id)) { - strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - if (option_debug > 1) - DEBUGA_SKYPE - ("We called a Skype contact and he answered us on skype_call: %s.\n", - SKYPIAX_P_LOG, id); - } - } - - if (!strcasecmp(prop, "STATUS")) { - - if (!strcasecmp(value, "RINGING")) { - char msg_to_skype[1024]; - if (tech_pvt->interface_state != SKYPIAX_STATE_DIALING) { - /* we are not calling out */ + return NULL; +} - if (!strlen(tech_pvt->skype_call_id)) { //FIXME - /* we are not inside an active call */ - tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; - tech_pvt->interface_state = SKYPIAX_STATE_RING; - /* no owner, no active call, let's answer */ - skypiax_skype_write(tech_pvt, "SET AGC OFF"); - skypiax_sleep(10000); - skypiax_skype_write(tech_pvt, "SET AEC OFF"); - skypiax_sleep(10000); - sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); - skypiax_skype_write(tech_pvt, msg_to_skype); - skypiax_sleep(10000); - sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); - skypiax_skype_write(tech_pvt, msg_to_skype); - skypiax_sleep(10000); - sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); - skypiax_skype_write(tech_pvt, msg_to_skype); - if (option_debug) - DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", - SKYPIAX_P_LOG, id); - strncpy(tech_pvt->skype_call_id, id, - sizeof(tech_pvt->skype_call_id) - 1); - } else { - /* we're owned, we're in a call, let's refuse */ - sprintf(msg_to_skype, "ALTER CALL %s END HANGUP", id); - skypiax_skype_write(tech_pvt, msg_to_skype); - skypiax_sleep(10000); - DEBUGA_SKYPE - ("We have NOT answered a Skype RING on skype_call %s, because we are already in a skypiax call\n", - SKYPIAX_P_LOG, id); +#else /* NOT WIN32 */ +int X11_errors_handler(Display * dpy, XErrorEvent * err) +{ + (void) dpy; + private_t *tech_pvt = NULL; - } - } else { - /* we are calling out */ - tech_pvt->skype_callflow = CALLFLOW_STATUS_RINGING; - tech_pvt->interface_state = SKYPIAX_STATE_RINGING; - //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING); - 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", - SKYPIAX_P_LOG, id); - } - } else if (!strcasecmp(value, "EARLYMEDIA")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA; - tech_pvt->interface_state = SKYPIAX_STATE_DIALING; - //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING); - DEBUGA_SKYPE("Our remote party in skype_call %s is EARLYMEDIA\n", - SKYPIAX_P_LOG, id); - } else if (!strcasecmp(value, "MISSED")) { - DEBUGA_SKYPE("We missed skype_call %s\n", SKYPIAX_P_LOG, id); + xerror = err->error_code; + ERRORA("Received error code %d from X Server\n\n", SKYPIAX_P_LOG, xerror); + return 0; /* ignore the error */ +} - } else if (!strcasecmp(value, "FINISHED")) { - //tech_pvt->skype_callflow = CALLFLOW_STATUS_FINISHED; - if (option_debug) - DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id); - tech_pvt->skype_call_id[0] = '\0'; +static void X11_errors_trap(void) +{ + xerror = 0; + old_handler = XSetErrorHandler(X11_errors_handler); +} - if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - //tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - } +static int X11_errors_untrap(void) +{ + XSetErrorHandler(old_handler); + return (xerror != BadValue) && (xerror != BadWindow); +} - } else if (!strcasecmp(value, "CANCELLED")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_CANCELLED; - if (option_debug) - DEBUGA_SKYPE - ("we tried to call Skype on skype_call %s and Skype has now CANCELLED\n", - SKYPIAX_P_LOG, id); - tech_pvt->skype_call_id[0] = '\0'; +int skypiax_skype_send_message(struct SkypiaxHandles *SkypiaxHandles, + const char *message_P) +{ - if (tech_pvt->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - } - } else if (!strcasecmp(value, "FAILED")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_FAILED; - if (option_debug) - DEBUGA_SKYPE - ("we tried to call Skype on skype_call %s and Skype has now FAILED\n", - SKYPIAX_P_LOG, id); - tech_pvt->skype_call_id[0] = '\0'; - strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return CALLFLOW_INCOMING_HANGUP; - } else if (!strcasecmp(value, "REFUSED")) { - if (!strcasecmp(id, tech_pvt->skype_call_id)) { - /* this is the id of the call we are in, probably we generated it */ - tech_pvt->skype_callflow = CALLFLOW_STATUS_REFUSED; - if (option_debug) - DEBUGA_SKYPE - ("we tried to call Skype on skype_call %s and Skype has now REFUSED\n", - SKYPIAX_P_LOG, id); - strncpy(tech_pvt->skype_call_id, id, - sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPIAX_STATE_DOWN; - tech_pvt->skype_call_id[0] = '\0'; - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return CALLFLOW_INCOMING_HANGUP; - } else { - /* we're here because were us that refused an incoming call */ - DEBUGA_SKYPE("we REFUSED skype_call %s\n", SKYPIAX_P_LOG, id); + Window w_P; + Display *disp; + Window handle_P; + int ok; + private_t *tech_pvt = NULL; - } - } else if (!strcasecmp(value, "ROUTING")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_ROUTING; - tech_pvt->interface_state = SKYPIAX_STATE_DIALING; - strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id); - } else if (!strcasecmp(value, "UNPLACED")) { - tech_pvt->skype_callflow = CALLFLOW_STATUS_UNPLACED; - tech_pvt->interface_state = SKYPIAX_STATE_DIALING; - strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id); - } else if (!strcasecmp(value, "INPROGRESS")) { - char msg_to_skype[1024]; - tech_pvt->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - strncpy(tech_pvt->skype_call_id, id, sizeof(tech_pvt->skype_call_id) - 1); - tech_pvt->interface_state = SKYPIAX_STATE_UP; - DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id); - sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"%d\"", id, - tech_pvt->tcp_cli_port); - skypiax_skype_write(tech_pvt, msg_to_skype); - start_audio_threads(tech_pvt); - sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"%d\"", id, - tech_pvt->tcp_srv_port); - skypiax_skype_write(tech_pvt, msg_to_skype); + w_P = SkypiaxHandles->skype_win; + disp = SkypiaxHandles->disp; + handle_P = SkypiaxHandles->win; - tech_pvt->skype_callflow = SKYPIAX_STATE_UP; + 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; - if (!strlen(tech_pvt->session_uuid_str)) { - DEBUGA_SKYPE("New Inbound Channel!\n", SKYPIAX_P_LOG); - new_inbound_channel(tech_pvt); - } else { - DEBUGA_SKYPE("Outbound Channel Answered!\n", SKYPIAX_P_LOG); - outbound_channel_answered(tech_pvt); - } + 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; - } else { - WARNINGA("skype_call: %s, STATUS: %s is not recognized\n", SKYPIAX_P_LOG, - id, value); + 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); - } - } //STATUS + e.xclient.message_type = atom2; /* following messages */ + pos += i; + } while (pos <= len); - } //CALL + XSync(disp, False); + ok = X11_errors_untrap(); - a = 0; - } //message end - } //read_from_pipe + if (!ok) + ERRORA("Sending message failed with status %d\n", SKYPIAX_P_LOG, xerror); + //XUnlockDisplay(disp); + + return 1; +} +int skypiax_skype_write(private_t * tech_pvt, char *msg_to_skype) +{ + struct SkypiaxHandles *SkypiaxHandles; + + DEBUGA_SKYPE("SENDING: |||%s||||\n", SKYPIAX_P_LOG, msg_to_skype); + + if (option_debug > 100) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + SkypiaxHandles = &tech_pvt->SkypiaxHandles; + if (!skypiax_skype_send_message(SkypiaxHandles, msg_to_skype)) { + ERRORA + ("Sending message failed - probably Skype crashed.\n\nPlease shutdown Skypiax, then restart Skype, then launch Skypiax and try again.\n", + SKYPIAX_P_LOG); + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); } + return -1; } if (option_debug > 100) { DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); } - //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); return 0; + } -int skypiax_skype_senddigit(private_t * tech_pvt, char digit) + +int skypiax_skype_present(struct SkypiaxHandles *SkypiaxHandles) { - char msg_to_skype[1024]; - if (option_debug > 10) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + Atom skype_inst = XInternAtom(SkypiaxHandles->disp, "_SKYPE_INSTANCE", True); + + Atom type_ret; + int format_ret; + unsigned long nitems_ret; + unsigned long bytes_after_ret; + unsigned char *prop; + int status; + private_t *tech_pvt = NULL; + + X11_errors_trap(); + //XLockDisplay(disp); + status = + XGetWindowProperty(SkypiaxHandles->disp, DefaultRootWindow(SkypiaxHandles->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) { + SkypiaxHandles->skype_win = (Window) - 1; + DEBUGA_SKYPE("Skype instance not found\n", SKYPIAX_P_LOG); + return 0; } - DEBUGA_SKYPE("DIGIT received: %c\n", SKYPIAX_P_LOG, digit); + SkypiaxHandles->skype_win = *(const unsigned long *) prop & 0xffffffff; + DEBUGA_SKYPE("Skype instance found with id #%d\n", SKYPIAX_P_LOG, + (unsigned int) SkypiaxHandles->skype_win); + return 1; +} - sprintf(msg_to_skype, "SET CALL %s DTMF %c", tech_pvt->skype_call_id, digit); +void skypiax_skype_clean_disp(void *data) +{ - skypiax_skype_write(tech_pvt, msg_to_skype); + int *dispptr; + int disp; + private_t *tech_pvt = NULL; - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + 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); } - return 0; + DEBUGA_SKYPE("OUT destroyed disp\n", SKYPIAX_P_LOG); + skypiax_sleep(1000); } -int skypiax_skype_call(private_t * tech_pvt, char *rdest, int timeout) +void *skypiax_do_skypeapi_thread_func(void *obj) { - char msg_to_skype[1024]; - if (option_debug > 10) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + private_t *tech_pvt = obj; + struct SkypiaxHandles *SkypiaxHandles; + char buf[512]; + Display *disp = NULL; + Window root = -1; + Window win = -1; + + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + + if (!strlen(tech_pvt->X11_display)) + strcpy(tech_pvt->X11_display, getenv("DISPLAY")); + + if (!tech_pvt->tcp_srv_port) + tech_pvt->tcp_srv_port = 10160; + + if (!tech_pvt->tcp_cli_port) + tech_pvt->tcp_cli_port = 10161; + + if (pipe(tech_pvt->SkypiaxHandles.fdesc)) { + fcntl(tech_pvt->SkypiaxHandles.fdesc[0], F_SETFL, O_NONBLOCK); + fcntl(tech_pvt->SkypiaxHandles.fdesc[1], F_SETFL, O_NONBLOCK); + } + SkypiaxHandles = &tech_pvt->SkypiaxHandles; + disp = XOpenDisplay(tech_pvt->X11_display); + if (!disp) { + ERRORA("Cannot open X Display '%s', exiting skype thread\n", SKYPIAX_P_LOG, + tech_pvt->X11_display); + running = 0; + return NULL; + } else { + DEBUGA_SKYPE("X Display '%s' opened\n", SKYPIAX_P_LOG, tech_pvt->X11_display); } - skypiax_sleep(5000); - DEBUGA_SKYPE("Calling Skype, rdest is: %s\n", SKYPIAX_P_LOG, rdest); - skypiax_skype_write(tech_pvt, "SET AGC OFF"); - skypiax_sleep(10000); - skypiax_skype_write(tech_pvt, "SET AEC OFF"); - skypiax_sleep(10000); - sprintf(msg_to_skype, "CALL %s", rdest); - if (skypiax_skype_write(tech_pvt, msg_to_skype) < 0) { + int xfd; + xfd = XConnectionNumber(disp); + fcntl(xfd, F_SETFD, FD_CLOEXEC); - ERRORA("failed to communicate with Skype client, now exit\n", SKYPIAX_P_LOG); - if (option_debug > 10) { + SkypiaxHandles->disp = disp; + + if (skypiax_skype_present(SkypiaxHandles)) { + root = DefaultRootWindow(disp); + win = + XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, + BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, + DefaultScreen + (disp))); + + SkypiaxHandles->win = win; + + snprintf(buf, 512, "NAME skypiax"); + + if (!skypiax_skype_send_message(SkypiaxHandles, buf)) { + ERRORA + ("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n", + SKYPIAX_P_LOG); DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + running = 0; + return NULL; } - return -1; + + snprintf(buf, 512, "PROTOCOL 6"); + if (!skypiax_skype_send_message(SkypiaxHandles, buf)) { + ERRORA + ("Sending message failed - probably Skype crashed. Please run/restart Skype manually and launch Skypiax again\n", + SKYPIAX_P_LOG); + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + running = 0; + return NULL; + } + + /* perform an events loop */ + XEvent an_event; + char buf[21]; /* can't be longer */ + char buffer[17000]; + char *b; + int i; + + b = buffer; + + while (1) { + XNextEvent(disp, &an_event); + if (!running) + break; + switch (an_event.type) { + case ClientMessage: + + if (an_event.xclient.format != 8) + break; + + for (i = 0; i < 20 && an_event.xclient.data.b[i] != '\0'; ++i) + buf[i] = an_event.xclient.data.b[i]; + + buf[i] = '\0'; + + strcat(buffer, buf); + + if (i < 20) { /* last fragment */ + unsigned int howmany; + + howmany = strlen(b) + 1; + + howmany = write(SkypiaxHandles->fdesc[1], b, howmany); + memset(buffer, '\0', 17000); + } + + break; + default: + break; + } + } + } else { + ERRORA + ("Skype is not running, maybe crashed. Please run/restart Skype and relaunch Skypiax\n", + SKYPIAX_P_LOG); + running = 0; + return NULL; } - //FIXME ast_queue_control(tech_pvt->owner, SKYPIAX_CONTROL_RINGING); - return 0; + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + running = 0; + return NULL; + } +#endif // WIN32 + +
participants (1)
-
FreeSWITCH SVN