[commit] r10672 - freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax
Author: gmaruzz Date: Tue Dec 9 05:52:03 2008 New Revision: 10672 Log: skypiax: continuing files structuring Added: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax_protocol.c Modified: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.2008.vcproj freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.c freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax.h Modified: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.2008.vcproj ============================================================================== --- freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.2008.vcproj (original) +++ freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/mod_skypiax.2008.vcproj Tue Dec 9 05:52:03 2008 @@ -153,6 +153,10 @@ RelativePath=".\skypiax.h" > </File> + <File + RelativePath=".\skypiax_protocol.c" + > + </File> </Files> <Globals> </Globals> 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 Tue Dec 9 05:52:03 2008 @@ -6,26 +6,6 @@ //SWITCH_MODULE_RUNTIME_FUNCTION(mod_skypiax_runtime); SWITCH_MODULE_DEFINITION(mod_skypiax, mod_skypiax_load, mod_skypiax_shutdown, NULL); //mod_skypiax_runtime); -switch_endpoint_interface_t *skypiax_endpoint_interface; -static switch_memory_pool_t *module_pool = NULL; -static int running = 1; - -typedef enum { - TFLAG_IO = (1 << 0), - TFLAG_INBOUND = (1 << 1), - TFLAG_OUTBOUND = (1 << 2), - TFLAG_DTMF = (1 << 3), - TFLAG_VOICE = (1 << 4), - TFLAG_HANGUP = (1 << 5), - TFLAG_LINEAR = (1 << 6), - TFLAG_CODEC = (1 << 7), - TFLAG_BREAK = (1 << 8) -} TFLAGS; - -typedef enum { - GFLAG_MY_CODEC_PREFS = (1 << 0) -} GFLAGS; - static struct { int debug; char *ip; @@ -44,13 +24,18 @@ switch_mutex_t *mutex; } globals; -static skypiax_interface_t SKYPIAX_INTERFACES[SKYPIAX_MAX_INTERFACES]; - +/*************************************************/ +/*************************************************/ +/*************************************************/ int option_debug = 100; +switch_endpoint_interface_t *skypiax_endpoint_interface; +switch_memory_pool_t *skypiax_module_pool = NULL; +static int running = 1; +static skypiax_interface_t SKYPIAX_INTERFACES[SKYPIAX_MAX_INTERFACES]; switch_core_session_t *global_session = NULL; - - - +/*************************************************/ +/*************************************************/ +/*************************************************/ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); @@ -80,252 +65,6 @@ static switch_status_t channel_kill_channel(switch_core_session_t * session, int sig); -#ifdef WIN32 -#ifdef WIN32 -struct AsteriskHandles *win32_AsteriskHandlesSkype; -HWND win32_hInit_MainWindowHandle; -HINSTANCE win32_hInit_ProcessHandle; -char win32_acInit_WindowClassName[128]; -HANDLE win32_hGlobal_ThreadShutdownEvent; -UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach; -UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover; -HWND win32_hGlobal_SkypeAPIWindowHandle = NULL; -DWORD win32_ulGlobal_PromptConsoleMode = 0; -HANDLE volatile win32_hGlobal_PromptConsoleHandle = NULL; - -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) -{ - char *res; - - if (!stringp || !*stringp || !**stringp) - return (char *) 0; - - res = *stringp; - while (**stringp && !strchr(delim, **stringp)) - ++(*stringp); - - if (**stringp) { - **stringp = '\0'; - ++(*stringp); - } - - return res; -} - -LRESULT APIENTRY skypiax_skype_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, - LPARAM ulParam) -{ - LRESULT lReturnCode; - int fIssueDefProc; - struct skypiax_interface *p = NULL; - - lReturnCode = 0; - fIssueDefProc = 0; - switch (uiMessage) { - case WM_DESTROY: - win32_hInit_MainWindowHandle = NULL; - PostQuitMessage(0); - break; - case WM_COPYDATA: - if (win32_hGlobal_SkypeAPIWindowHandle == (HWND) uiParam) { - unsigned int howmany; - char msg_from_skype[2048]; - - PCOPYDATASTRUCT poCopyData = (PCOPYDATASTRUCT) ulParam; - - memset(msg_from_skype, '\0', sizeof(msg_from_skype)); - strncpy(msg_from_skype, (const char *) poCopyData->lpData, - sizeof(msg_from_skype) - 2); - - howmany = strlen(msg_from_skype) + 1; - switch_file_write(win32_AsteriskHandlesSkype->fdesc[1], msg_from_skype, &howmany); - NOTICA("From Skype API: %s\n", SKYPIAX_P_LOG, (const char *) poCopyData->lpData); - lReturnCode = 1; - } - break; - default: - if (uiMessage == win32_uiGlobal_MsgID_SkypeControlAPIAttach) { - switch (ulParam) { - case SKYPECONTROLAPI_ATTACH_SUCCESS: - NOTICA("\n\n\tConnected to Skype API!\n", SKYPIAX_P_LOG); - win32_hGlobal_SkypeAPIWindowHandle = (HWND) uiParam; - switch_sleep(5000); - win32_AsteriskHandlesSkype->win32_hGlobal_SkypeAPIWindowHandle = - win32_hGlobal_SkypeAPIWindowHandle; - break; - case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: - WARNINGA - ("\n\n\tIf I do not 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); - 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 available\n", SKYPIAX_P_LOG); - break; - case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: - DEBUGA_SKYPE("Skype API available\n", SKYPIAX_P_LOG); - 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); -} - -int win32_Initialize_CreateWindowClass(void) -{ - unsigned char *paucUUIDString; - RPC_STATUS lUUIDResult; - int fReturnStatus; - UUID oUUID; - - fReturnStatus = 0; - lUUIDResult = UuidCreate(&oUUID); - win32_hInit_ProcessHandle = - (HINSTANCE) OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId()); - if (win32_hInit_ProcessHandle != NULL - && (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) { - if (UuidToString(&oUUID, &paucUUIDString) == RPC_S_OK) { - WNDCLASS oWindowClass; - - strcpy(win32_acInit_WindowClassName, "Skype-API-Skypiax-"); - strcat(win32_acInit_WindowClassName, (char *) paucUUIDString); - - oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; - oWindowClass.lpfnWndProc = (WNDPROC) & skypiax_skype_present; - oWindowClass.cbClsExtra = 0; - oWindowClass.cbWndExtra = 0; - oWindowClass.hInstance = win32_hInit_ProcessHandle; - oWindowClass.hIcon = NULL; - oWindowClass.hCursor = NULL; - oWindowClass.hbrBackground = NULL; - oWindowClass.lpszMenuName = NULL; - oWindowClass.lpszClassName = win32_acInit_WindowClassName; - - if (RegisterClass(&oWindowClass) != 0) - fReturnStatus = 1; - - RpcStringFree(&paucUUIDString); - } - } - if (fReturnStatus == 0) - CloseHandle(win32_hInit_ProcessHandle), win32_hInit_ProcessHandle = NULL; - return (fReturnStatus); -} - -void win32_DeInitialize_DestroyWindowClass(void) -{ - UnregisterClass(win32_acInit_WindowClassName, win32_hInit_ProcessHandle); - CloseHandle(win32_hInit_ProcessHandle), win32_hInit_ProcessHandle = NULL; -} - -int win32_Initialize_CreateMainWindow(void) -{ - win32_hInit_MainWindowHandle = - CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, win32_acInit_WindowClassName, "", - WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, - 128, 128, NULL, 0, win32_hInit_ProcessHandle, 0); - return (win32_hInit_MainWindowHandle != NULL ? 1 : 0); -} - -void win32_DeInitialize_DestroyMainWindow(void) -{ - if (win32_hInit_MainWindowHandle != NULL) - DestroyWindow(win32_hInit_MainWindowHandle), win32_hInit_MainWindowHandle = NULL; -} - -DWORD win32_dwThreadId; - -static void *SWITCH_THREAD_FUNC do_skype_thread(switch_thread_t * thread, 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 */ - - struct skypiax_interface *p; - p = obj; - - switch_file_pipe_create_ex(&p->AsteriskHandlesAst.fdesc[0], - &p->AsteriskHandlesAst.fdesc[1], 2, module_pool); - - win32_AsteriskHandlesSkype = &p->AsteriskHandlesAst; - - win32_uiGlobal_MsgID_SkypeControlAPIAttach = - RegisterWindowMessage("SkypeControlAPIAttach"); - win32_uiGlobal_MsgID_SkypeControlAPIDiscover = - RegisterWindowMessage("SkypeControlAPIDiscover"); - - if (win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0 - && win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { - if (win32_Initialize_CreateWindowClass()) { - if (win32_Initialize_CreateMainWindow()) { - win32_hGlobal_ThreadShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (win32_hGlobal_ThreadShutdownEvent != NULL) { - if (SendMessage - (HWND_BROADCAST, win32_uiGlobal_MsgID_SkypeControlAPIDiscover, - (WPARAM) win32_hInit_MainWindowHandle, 0) != 0) { - win32_AsteriskHandlesSkype->win32_hInit_MainWindowHandle = - win32_hInit_MainWindowHandle; - while (1) { - MSG oMessage; - - while (GetMessage(&oMessage, 0, 0, 0) != FALSE) { - TranslateMessage(&oMessage); - DispatchMessage(&oMessage); - } - } - } - CloseHandle(win32_hGlobal_ThreadShutdownEvent); - } - win32_DeInitialize_DestroyMainWindow(); - } - win32_DeInitialize_DestroyWindowClass(); - } - } - return NULL; -} - -#endif /* WIN32 */ - -#endif //WIN32 - static switch_status_t skypiax_codec(private_t * tech_pvt, int sample_rate, int codec_ms) { if (switch_core_codec_init @@ -355,332 +94,7 @@ } -#define SKYPE_AUDIO -#ifdef SKYPE_AUDIO - -#define SAMPLES_PER_FRAME 160 -#define NN 160 -#define GG 160 -static void *SWITCH_THREAD_FUNC skypiax_do_tcp_srv_thread(switch_thread_t * thread, - void *obj) -{ - struct skypiax_interface *p = obj; - short in[GG]; - short out[GG / 2]; - int s, fd, len; - unsigned int sin_size; - struct sockaddr_in my_addr; - struct sockaddr_in remote_addr; - int exit = 0; - int a; - int i; - unsigned int kill_cli_size; - short kill_cli_buff[320]; - - if (option_debug > 10) { - WARNINGA("ENTERING FUNC\n", SKYPIAX_P_LOG); - } - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sin_family = AF_INET; - my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ - my_addr.sin_port = htons(5556); //FIXME configurable! - - if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ERRORA("socket Error\n", SKYPIAX_P_LOG); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return NULL; - } - - if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { - ERRORA("bind Error\n", SKYPIAX_P_LOG); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return NULL; - } - DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); - - listen(s, 6); - - sin_size = sizeof(remote_addr); - while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) { - DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG); - while (p->interface_state != SKYPIAX_STATE_DOWN - && (p->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || p->skype_callflow == SKYPIAX_STATE_UP)) { - - int fdselect; - int rt; - fd_set fs; - struct timeval to; - - exit = 1; - - fdselect = fd; - FD_ZERO(&fs); - FD_SET(fdselect, &fs); - to.tv_usec = 100; - to.tv_sec = 0; - rt = select(fdselect + 1, &fs, NULL, NULL, &to); - if (rt > 0) { - - len = recv(fd, in, sizeof(short) * GG, 0); - //DEBUGA_SKYPE("recv %d\n", SKYPIAX_P_LOG, len); - if (len > 0) { - a = 0; - for (i = 0; i < len / sizeof(short); i++) { - out[a] = in[i]; - i++; - a++; - } - - if (!p->audiobuf_is_loaded) { - for (i = 0; i < (len / sizeof(short)) / 2; i++) { - p->audiobuf[i] = out[i]; - } - p->audiobuf_is_loaded = 1; - } else { - unsigned int howmany; - short totalbuf[GG]; - - howmany = len / 2 / 2; - for (i = 0; i < howmany; i++) - totalbuf[i] = p->audiobuf[i]; - - howmany = len / 2 / 2; - for (a = 0; a < howmany; a++) { - totalbuf[i] = out[a]; - i++; - } - - howmany = len; - - switch_file_write(p->audiopipe[1], totalbuf, &howmany); - p->audiobuf_is_loaded = 0; - //DEBUGA_SKYPE("read=====> req=%d recv=%d to sent=%d sent=%d\n", SKYPIAX_P_LOG, sizeof(short)*GG, len, (len*sizeof(short))/2, howmany); - } - - } else if (len == 0) { - DEBUGA_SKYPE("Skype client GONE\n", SKYPIAX_P_LOG); - break; - } else { - ERRORA("len=%d\n", SKYPIAX_P_LOG, len); - exit = 1; - break; - } - } - } - - kill_cli_size = 320; - switch_file_write(p->audiopipe[1], kill_cli_buff, &kill_cli_size); - kill_cli_size = 320; - switch_file_write(p->audioskypepipe[1], kill_cli_buff, &kill_cli_size); - p->interface_state = SKYPIAX_STATE_DOWN; - kill_cli_size = 320; - switch_file_write(p->audiopipe[1], kill_cli_buff, &kill_cli_size); - kill_cli_size = 320; - switch_file_write(p->audioskypepipe[1], kill_cli_buff, &kill_cli_size); - - DEBUGA_SKYPE("Skype client GONE\n", SKYPIAX_P_LOG); - -#ifndef WIN32 - close(fd); -#else - closesocket(fd); -#endif - if (exit) - break; - } - - WARNINGA("server (I am it) GONE\n", SKYPIAX_P_LOG); -#ifndef WIN32 - close(s); -#else - closesocket(s); -#endif - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return NULL; -} -static void *SWITCH_THREAD_FUNC skypiax_do_tcp_cli_thread(switch_thread_t * thread, - void *obj) -//void *skypiax_do_tcp_cli_thread(void *data) -{ - struct skypiax_interface *p = obj; - int s, fd, len; - short in[NN / 2]; - short out[NN]; - unsigned int sin_size; - struct sockaddr_in my_addr; - struct sockaddr_in remote_addr; - int a; - int i; - unsigned int got; - - if (option_debug > 10) { - WARNINGA("ENTERING FUNC\n", SKYPIAX_P_LOG); - } - memset(&my_addr, 0, sizeof(my_addr)); - my_addr.sin_family = AF_INET; - my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ - my_addr.sin_port = htons(5558); //FIXME configurable! - - if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ERRORA("socket Error\n", SKYPIAX_P_LOG); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return NULL; - } - - if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { - ERRORA("bind Error\n", SKYPIAX_P_LOG); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } -#ifndef WIN32 - close(s); -#else - closesocket(s); -#endif - return NULL; - } - DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); - - listen(s, 6); - - sin_size = sizeof(remote_addr); - while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) { - DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG); - while (p->interface_state != SKYPIAX_STATE_DOWN - && (p->skype_callflow == CALLFLOW_STATUS_INPROGRESS - || p->skype_callflow == SKYPIAX_STATE_UP)) { - int fdselect; - int rt; - fd_set fs; - struct timeval to; - - fdselect = 1; - FD_ZERO(&fs); - FD_SET(fdselect, &fs); - to.tv_usec = 100; - to.tv_sec = 0; - rt = 1; - if (rt > 0) { - - got = (NN / 2) * sizeof(short); - switch_file_read(p->audioskypepipe[0], in, &got); - - if (got > 0) { - a = 0; - for (i = 0; i < got / sizeof(short); i++) { - out[a] = in[i]; - a++; - out[a] = in[i]; - a++; - } - - len = send(fd, out, got * 2, 0); - - if (len == 0) { - ERRORA("Skype server GONE\n", SKYPIAX_P_LOG); - break; - } - } else { - switch_sleep(1000); - //ERRORA("Audio skype pipe give us: %u\n", SKYPIAX_P_LOG, got); - } - } - - } - ERRORA("Skype server GONE\n", SKYPIAX_P_LOG); -#ifndef WIN32 - close(fd); -#else - closesocket(fd); -#endif - break; - } - - WARNINGA("client (I am it) GONE\n", SKYPIAX_P_LOG); -#ifndef WIN32 - close(s); -#else - closesocket(s); -#endif - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return NULL; -} - -int skypiax_skypeaudio_init(struct skypiax_interface *p) -{ - - switch_status_t rv; - - rv = switch_file_pipe_create_ex(&p->audiopipe[0], &p->audiopipe[1], 2, module_pool); - rv = switch_file_pipe_timeout_set(p->audiopipe[0], 100000); - -/* the pipe is our audio fd for pbx to poll on */ - p->skypiax_sound_capt_fd = p->audiopipe[0]; - - rv = - switch_file_pipe_create_ex(&p->audioskypepipe[0], &p->audioskypepipe[1], 2, - module_pool); - rv = switch_file_pipe_timeout_set(p->audioskypepipe[0], 100); - if (option_debug > 10) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return 0; -} -static switch_status_t skypiax_skypeaudio_read(private_t * tech_pvt) -{ - struct skypiax_interface *p; - short buf[640]; - unsigned int samples; - int rt; - - p = tech_pvt->p; - - //DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - - memset(buf, '\0', sizeof(buf)); - - rt = 1; - if (rt > 0) { - - samples = SAMPLES_PER_FRAME * sizeof(short); - - switch_file_read(p->audiopipe[0], tech_pvt->read_frame.data, &samples); - - //if ((samples = read(p->audiopipe[0], buf, SAMPLES_PER_FRAME * sizeof(short))) != 320) - if (samples != SAMPLES_PER_FRAME * sizeof(short)) { - if (samples) - DEBUGA_SKYPE("read=====> NOT GOOD samples=%d expected=%d\n", SKYPIAX_P_LOG, - samples, SAMPLES_PER_FRAME * sizeof(short)); - //do nothing - } else { - tech_pvt->read_frame.datalen = samples; - //DEBUGA_SKYPE("read=====> GOOD samples=%d\n", SKYPIAX_P_LOG, samples); - /* A real frame */ - } - } else { - DEBUGA_SKYPE("select returned %d\n", SKYPIAX_P_LOG, rt); - - } - - //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - - return SWITCH_STATUS_SUCCESS; -} - -#endif /* SKYPE_AUDIO */ -static void tech_init(private_t * tech_pvt, switch_core_session_t * session, - skypiax_interface_t * p) +void skypiax_tech_init(private_t * tech_pvt, switch_core_session_t * session, skypiax_interface_t * p) { DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); @@ -1028,799 +442,6 @@ /*.receive_event */ channel_receive_event }; -#define SKYPE_THREAD -#ifndef WIN32 -#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_interface *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_interface *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_interface *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_interface *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); - switch_sleep(1000); -} - -static void *SWITCH_THREAD_FUNC do_skype_thread(switch_thread_t * thread, void *obj) -{ - - struct skypiax_interface *p; - struct AsteriskHandles *AsteriskHandlesAst; - char buf[SKYPE_X11_BUF_SIZE]; - Display *disp = NULL; - Window root = -1; - Window win = -1; - - p = obj; - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - - switch_file_pipe_create_ex(&p->AsteriskHandlesAst.fdesc[0], - &p->AsteriskHandlesAst.fdesc[1], 2, module_pool); - - AsteriskHandlesAst = &p->AsteriskHandlesAst; - //disp = XOpenDisplay(getenv("DISPLAY")); - disp = XOpenDisplay(p->X11_display); - if (!disp) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - "Cannot open X Display '%s', exiting skype thread\n", - p->X11_display); - return NULL; - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "X Display '%s' opened\n", - p->X11_display); - } - - int xfd; - xfd = XConnectionNumber(disp); - fcntl(xfd, F_SETFD, FD_CLOEXEC); - - //FIXME pthread_cleanup_push(skypiax_skype_clean_disp, &xfd); - DEBUGA_SKYPE("PUSH disp %d\n", SKYPIAX_P_LOG, xfd); - - if (skypiax_skype_present(disp)) { - root = DefaultRootWindow(disp); - win = - XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, - BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, - DefaultScreen - (disp))); - - DEBUGA_SKYPE("skype_win=%d win=%d\n", SKYPIAX_P_LOG, (unsigned int) skype_win, - (unsigned int) win); - - AsteriskHandlesAst->skype_win = skype_win; - AsteriskHandlesAst->disp = disp; - AsteriskHandlesAst->win = win; - - snprintf(buf, SKYPE_X11_BUF_SIZE, "NAME 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); - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - return NULL; - } - - snprintf(buf, SKYPE_X11_BUF_SIZE, "PROTOCOL 6"); - 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); - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - 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); - 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'; - - //NOTICA("ClientMessage buf:|||%s||| buffer:|||%s||| serial=%ld|||\r\n",SKYPIAX_P_LOG,buf, buffer,an_event.xclient.serial); - //NOTICA ("SKYPE read: |||%s|||%d\n", SKYPIAX_P_LOG, buf, strlen(buf)); - //NOTICA ("SKYPE buffer: |||%s|||%d\n", SKYPIAX_P_LOG, buffer, strlen(buffer)); - - strcat(buffer, buf); - - if (i < 20) { /* last fragment */ - unsigned int howmany; - - howmany = strlen(b) + 1; - - switch_file_write(AsteriskHandlesAst->fdesc[1], b, &howmany); - //write(AsteriskHandlesAst->fdesc[1], "\0", 1); - //FIXME DEBUGA_SKYPE("SKYPE pipewrite: |||%s|||len=%d serial=%ld\n\n\n", SKYPIAX_P_LOG, b, strlen(b) + 1, an_event.xclient.serial); - //switch_sleep(1000); - 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); - return NULL; - } - //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - return NULL; - -} - -#endif /* SKYPE_THREAD */ -#else // WIN32 - -#endif // WIN32 - -#define CONTROLDEV_THREAD -#ifdef CONTROLDEV_THREAD -#if 1 - -#define WANT_SKYPE_X11 -int skypiax_skype_write(struct skypiax_interface *p, char *msg_to_skype) -{ -#ifdef WIN32 - static char acInputRow[1024]; - COPYDATASTRUCT oCopyData; - - if (option_debug > 100) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - } - sprintf(acInputRow, "%s", msg_to_skype); - if (option_debug > 1) - DEBUGA_SKYPE("acInputRow: |||%s||||\n", SKYPIAX_P_LOG, acInputRow); - /* send command to skype */ - oCopyData.dwData = 0; - oCopyData.lpData = acInputRow; - oCopyData.cbData = strlen(acInputRow) + 1; - if (oCopyData.cbData != 1) { - if (SendMessage - (p->AsteriskHandlesAst.win32_hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, - (WPARAM) p->AsteriskHandlesAst.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", - SKYPIAX_P_LOG); - p->skype = 0; - //FIXME p->skype_thread = SKYPIAX_PTHREADT_NULL; - p->skype_thread = NULL; - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return -1; - } - } -#else /* WIN32 */ -#ifdef WANT_SKYPE_X11 - struct AsteriskHandles *AsteriskHandlesAst; - - if (option_debug > 100) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - } - AsteriskHandlesAst = &p->AsteriskHandlesAst; - - if (option_debug > 101) { - DEBUGA_SKYPE("SENDING: |||%s||||\n", SKYPIAX_P_LOG, msg_to_skype); - } - - if (!skypiax_skype_send_message(AsteriskHandlesAst, 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 /* WANT_SKYPE_X11 */ -#endif /* WIN32 */ - - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - return 0; - -} -#endif //0 - -int skypiax_skype_read(struct skypiax_interface *p) -{ - - 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 fd; - int rt; - //fd_set fs; - //struct timeval to; - int i, a; - unsigned int howmany; - - if (option_debug > 100) { - DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); - } - - memset(read_from_pipe, 0, 4096); - memset(messaggio, 0, 4096); - memset(messaggio_2, 0, 4096); - - rt = 1; - if (rt > 0) { - howmany = sizeof(read_from_pipe); - switch_file_read(p->AsteriskHandlesAst.fdesc[0], 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') { - - //if (option_debug > 101) - DEBUGA_SKYPE("read_skype: howmany=%d, i=%d, a=%d, |||%s||| \n", SKYPIAX_P_LOG, - howmany, i, a, messaggio); - - if (!strncasecmp(messaggio, "ERROR 92 CALL", 12)) { - ERRORA("Skype got ERROR: |||%s|||, the number we called was not recognized\n", - SKYPIAX_P_LOG, messaggio); - p->skype_callflow = CALLFLOW_STATUS_FINISHED; - if (option_debug) - DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); - p->skype_call_id[0] = '\0'; - - if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - p->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - p->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(p->skype_friends, 0, 4096); - strncpy(p->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(p->skype_fullname, 0, 512); - strncpy(p->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(p->skype_displayname, 0, 512); - strncpy(p->skype_displayname, &messaggio_2[10], 511); - } - if (!strcasecmp(messaggio, "ERROR")) { - ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, messaggio); - p->skype_callflow = CALLFLOW_STATUS_FINISHED; - if (option_debug) - DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); - p->skype_call_id[0] = '\0'; - - if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - p->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - p->interface_state = SKYPIAX_STATE_DOWN; - } - } - 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(p->callid_number, value, sizeof(p->callid_number) - 1); - WARNINGA - ("the skype_call %s caller PARTNER_HANDLE (p->callid_number) is: %s\n", - SKYPIAX_P_LOG, id, p->callid_number); - return CALLFLOW_INCOMING_RING; - } - if (!strcasecmp(prop, "PARTNER_DISPNAME")) { - snprintf(p->callid_name, sizeof(p->callid_name) - 1, "%s%s%s", value, - where ? " " : "", where ? where : ""); - WARNINGA - ("the skype_call %s caller PARTNER_DISPNAME (p->callid_name) is: %s\n", - SKYPIAX_P_LOG, id, p->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 (p->interface_state == SKYPIAX_STATE_DOWN) - p->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 (p->interface_state == SKYPIAX_STATE_DOWN) - p->interface_state = SKYPIAX_STATE_PRERING; - } - - if (!strcasecmp(prop, "DTMF")) { - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - - DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value); - - tech_pvt = p->tech_pvt; - session = tech_pvt->session; - channel = switch_core_session_get_channel(session); - - if (channel) { - switch_dtmf_t dtmf = - { (char) value[0], switch_core_default_dtmf_duration(0) }; - if (globals.debug) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%c DTMF %s\n", - dtmf.digit, switch_channel_get_name(channel)); - } - switch_mutex_lock(tech_pvt->flag_mutex); - switch_channel_queue_dtmf(channel, &dtmf); - switch_set_flag(tech_pvt, TFLAG_DTMF); - switch_mutex_unlock(tech_pvt->flag_mutex); - } - } - - 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, p->skype_call_id)) { - strncpy(p->skype_call_id, id, sizeof(p->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 (p->interface_state != SKYPIAX_STATE_DIALING) { - /* we are not calling out */ - - if (1) { - /* we are not inside an active call */ - p->skype_callflow = CALLFLOW_STATUS_RINGING; - p->interface_state = SKYPIAX_STATE_RING; - /* no owner, no active call, let's answer */ - skypiax_skype_write(p, "SET AGC OFF"); - switch_sleep(10000); - skypiax_skype_write(p, "SET AEC OFF"); - switch_sleep(10000); - sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); - skypiax_skype_write(p, msg_to_skype); - switch_sleep(10000); - sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); - skypiax_skype_write(p, msg_to_skype); - switch_sleep(10000); - sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); - skypiax_skype_write(p, msg_to_skype); - if (option_debug) - DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", - SKYPIAX_P_LOG, id); - strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); - } else { - /* we're owned, we're in a call, let's refuse */ - sprintf(msg_to_skype, "SET CALL %s STATUS FINISHED", id); - skypiax_skype_write(p, msg_to_skype); - switch_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 { - /* we are calling out */ - p->skype_callflow = CALLFLOW_STATUS_RINGING; - p->interface_state = SKYPIAX_STATE_RINGING; - //FIXME ast_queue_control(p->owner, SKYPIAX_CONTROL_RINGING); - strncpy(p->skype_call_id, id, sizeof(p->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")) { - p->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA; - p->interface_state = SKYPIAX_STATE_DIALING; - //FIXME ast_queue_control(p->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); - - } else if (!strcasecmp(value, "FINISHED")) { - global_session = NULL; //FIXME - //p->skype_callflow = CALLFLOW_STATUS_FINISHED; - if (option_debug) - DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id); - p->skype_call_id[0] = '\0'; - - if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - //p->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - p->interface_state = SKYPIAX_STATE_DOWN; - } - - } else if (!strcasecmp(value, "CANCELLED")) { - p->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); - p->skype_call_id[0] = '\0'; - - if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { - if (option_debug > 100) { - DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); - } - p->interface_state = SKYPIAX_STATE_DOWN; - return CALLFLOW_INCOMING_HANGUP; - } else { - p->interface_state = SKYPIAX_STATE_DOWN; - } - } else if (!strcasecmp(value, "FAILED")) { - p->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); - p->skype_call_id[0] = '\0'; - strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); - p->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, p->skype_call_id)) { - /* this is the id of the call we are in, probably we generated it */ - p->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(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); - p->interface_state = SKYPIAX_STATE_DOWN; - p->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); - - } - } else if (!strcasecmp(value, "ROUTING")) { - p->skype_callflow = CALLFLOW_STATUS_ROUTING; - p->interface_state = SKYPIAX_STATE_DIALING; - strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id); - } else if (!strcasecmp(value, "UNPLACED")) { - p->skype_callflow = CALLFLOW_STATUS_UNPLACED; - p->interface_state = SKYPIAX_STATE_DIALING; - strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); - DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id); - } else if (!strcasecmp(value, "INPROGRESS")) { - p->skype_callflow = CALLFLOW_STATUS_INPROGRESS; - strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); - p->interface_state = SKYPIAX_STATE_UP; - if (option_debug > 1) - DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id); - - if (option_debug > 1) - DEBUGA_SKYPE("skype_call: %s SKYPIAX_CONTROL_ANSWER sent\n", - SKYPIAX_P_LOG, id); - - if (1) { - char msg_to_skype[1024]; - - if (1) { - switch_threadattr_t *thd_attr = NULL; - - switch_threadattr_create(&thd_attr, module_pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&p->tcp_srv_thread, thd_attr, - skypiax_do_tcp_srv_thread, p, module_pool); - DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); - - switch_threadattr_create(&thd_attr, module_pool); - switch_threadattr_detach_set(thd_attr, 1); - switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); - switch_thread_create(&p->tcp_cli_thread, thd_attr, - skypiax_do_tcp_cli_thread, p, module_pool); - DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); - } - switch_sleep(100000); - sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"5556\"", id); - skypiax_skype_write(p, msg_to_skype); - switch_sleep(100000); - sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"5558\"", id); - skypiax_skype_write(p, msg_to_skype); - switch_sleep(100000); - } - - p->skype_callflow = SKYPIAX_STATE_UP; - - /**************************/ - - //FIXME switch_core_session_t **new_session; - - //FIXME *new_session=switch_loadable_module_create_interface(skypiax_endpoint_interface, pool); - - if (!global_session) { //FIXME FIXME FIXME - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, - "New Inbound Channel!\n"); - - if ((session = - switch_core_session_request(skypiax_endpoint_interface, - NULL)) != 0) { - switch_core_session_add_stream(session, NULL); - if ((tech_pvt = - (private_t *) switch_core_session_alloc(session, - sizeof(private_t))) != 0) { - channel = switch_core_session_get_channel(session); - tech_init(tech_pvt, session, p); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "Hey where is my memory pool?\n"); - switch_core_session_destroy(&session); - break; - } - - // if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), NULL, dialplan, cid_name, cid_num, ip, NULL, NULL, NULL, modname, NULL, dest)) != 0) - - if ((tech_pvt->caller_profile = - switch_caller_profile_new(switch_core_session_get_pool(session), - "skypiax", "XML", "gmaruzz_from_skype", - "calling_number", NULL, "calling_ani", - NULL, NULL, (char *) modname, "default", - "5000")) != 0) { - char name[128]; - switch_snprintf(name, sizeof(name), "skypiax/%s-%04x", - tech_pvt->caller_profile->destination_number, - rand() & 0xffff); - switch_channel_set_name(channel, name); - switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); - } - switch_channel_set_state(channel, CS_INIT); - if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, - "Error spawning thread\n"); - switch_core_session_destroy(&session); - } - } - } else { - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - switch_channel_t *channel = NULL; - - tech_pvt = p->tech_pvt; - //session = tech_pvt->session; - session = global_session; - channel = switch_core_session_get_channel(session); - switch_channel_mark_pre_answered(channel); - - //switch_channel_set_state(channel, CS_EXECUTE); - - } - /**************************/ - - } 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 - - } - - 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_call(struct skypiax_interface *p, char *idest, int timeout, switch_core_session_t * session) { @@ -1874,7 +495,7 @@ (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) { tech_pvt->p = &SKYPIAX_INTERFACES[2]; //FIXME channel = switch_core_session_get_channel(*new_session); - tech_init(tech_pvt, *new_session, NULL); + skypiax_tech_init(tech_pvt, *new_session, NULL); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); @@ -1958,14 +579,13 @@ } -#endif // CONTROLDEV_THREAD static switch_status_t load_config(void) { char *cf = "skypiax.conf"; switch_xml_t cfg, xml, global_settings, param, interfaces, myinterface; - switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, module_pool); + switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, skypiax_module_pool); if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); return SWITCH_STATUS_TERM; @@ -2149,11 +769,11 @@ switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; - switch_threadattr_create(&thd_attr, module_pool); + switch_threadattr_create(&thd_attr, skypiax_module_pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, do_skype_thread, - &SKYPIAX_INTERFACES[interface_id], module_pool); + &SKYPIAX_INTERFACES[interface_id], skypiax_module_pool); } switch_sleep(100000); @@ -2161,11 +781,11 @@ switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; - switch_threadattr_create(&thd_attr, module_pool); + switch_threadattr_create(&thd_attr, skypiax_module_pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, skypiax_do_controldev_thread, - &SKYPIAX_INTERFACES[interface_id], module_pool); + &SKYPIAX_INTERFACES[interface_id], skypiax_module_pool); } switch_sleep(1000000); @@ -2214,7 +834,7 @@ { struct skypiax_interface *p = NULL; - module_pool = pool; + skypiax_module_pool = pool; memset(&globals, '\0', sizeof(globals)); memset(SKYPIAX_INTERFACES, '\0', sizeof(SKYPIAX_INTERFACES)); Modified: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax.h ============================================================================== --- freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax.h (original) +++ freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax.h Tue Dec 9 05:52:03 2008 @@ -47,6 +47,23 @@ #define SKYPIAX_SVN_VERSION "SVN 123456" +typedef enum { + TFLAG_IO = (1 << 0), + TFLAG_INBOUND = (1 << 1), + TFLAG_OUTBOUND = (1 << 2), + TFLAG_DTMF = (1 << 3), + TFLAG_VOICE = (1 << 4), + TFLAG_HANGUP = (1 << 5), + TFLAG_LINEAR = (1 << 6), + TFLAG_CODEC = (1 << 7), + TFLAG_BREAK = (1 << 8) +} TFLAGS; + +typedef enum { + GFLAG_MY_CODEC_PREFS = (1 << 0) +} GFLAGS; + + #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__ ); @@ -193,3 +210,9 @@ typedef struct private_object private_t; +void *SWITCH_THREAD_FUNC do_skype_thread(switch_thread_t * thread, void *obj); +void skypiax_tech_init(private_t * tech_pvt, switch_core_session_t * session, skypiax_interface_t * p); +switch_status_t skypiax_skypeaudio_read(private_t * tech_pvt); +int skypiax_skypeaudio_init(struct skypiax_interface *p); +int skypiax_skype_write(struct skypiax_interface *p, char *msg_to_skype); +int skypiax_skype_read(struct skypiax_interface *p); Added: freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax_protocol.c ============================================================================== --- (empty file) +++ freeswitch/branches/gmaruzz/src/mod/endpoints/mod_skypiax/skypiax_protocol.c Tue Dec 9 05:52:03 2008 @@ -0,0 +1,1351 @@ +#include "skypiax.h" +extern switch_memory_pool_t *skypiax_module_pool; +extern int option_debug; +extern switch_core_session_t *global_session; +extern switch_endpoint_interface_t *skypiax_endpoint_interface; + +#define SKYPE_AUDIO +#ifdef SKYPE_AUDIO + +#define SAMPLES_PER_FRAME 160 +#define NN 160 +#define GG 160 +static void *SWITCH_THREAD_FUNC skypiax_do_tcp_srv_thread(switch_thread_t * thread, + void *obj) +{ + struct skypiax_interface *p = obj; + short in[GG]; + short out[GG / 2]; + int s, fd, len; + unsigned int sin_size; + struct sockaddr_in my_addr; + struct sockaddr_in remote_addr; + int exit = 0; + int a; + int i; + unsigned int kill_cli_size; + short kill_cli_buff[320]; + + if (option_debug > 10) { + WARNINGA("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + memset(&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ + my_addr.sin_port = htons(5556); //FIXME configurable! + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + ERRORA("socket Error\n", SKYPIAX_P_LOG); + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return NULL; + } + + if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { + ERRORA("bind Error\n", SKYPIAX_P_LOG); + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return NULL; + } + DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); + + listen(s, 6); + + sin_size = sizeof(remote_addr); + while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) { + DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG); + while (p->interface_state != SKYPIAX_STATE_DOWN + && (p->skype_callflow == CALLFLOW_STATUS_INPROGRESS + || p->skype_callflow == SKYPIAX_STATE_UP)) { + + int fdselect; + int rt; + fd_set fs; + struct timeval to; + + exit = 1; + + fdselect = fd; + FD_ZERO(&fs); + FD_SET(fdselect, &fs); + to.tv_usec = 100; + to.tv_sec = 0; + rt = select(fdselect + 1, &fs, NULL, NULL, &to); + if (rt > 0) { + + len = recv(fd, in, sizeof(short) * GG, 0); + //DEBUGA_SKYPE("recv %d\n", SKYPIAX_P_LOG, len); + if (len > 0) { + a = 0; + for (i = 0; i < len / sizeof(short); i++) { + out[a] = in[i]; + i++; + a++; + } + + if (!p->audiobuf_is_loaded) { + for (i = 0; i < (len / sizeof(short)) / 2; i++) { + p->audiobuf[i] = out[i]; + } + p->audiobuf_is_loaded = 1; + } else { + unsigned int howmany; + short totalbuf[GG]; + + howmany = len / 2 / 2; + for (i = 0; i < howmany; i++) + totalbuf[i] = p->audiobuf[i]; + + howmany = len / 2 / 2; + for (a = 0; a < howmany; a++) { + totalbuf[i] = out[a]; + i++; + } + + howmany = len; + + switch_file_write(p->audiopipe[1], totalbuf, &howmany); + p->audiobuf_is_loaded = 0; + //DEBUGA_SKYPE("read=====> req=%d recv=%d to sent=%d sent=%d\n", SKYPIAX_P_LOG, sizeof(short)*GG, len, (len*sizeof(short))/2, howmany); + } + + } else if (len == 0) { + DEBUGA_SKYPE("Skype client GONE\n", SKYPIAX_P_LOG); + break; + } else { + ERRORA("len=%d\n", SKYPIAX_P_LOG, len); + exit = 1; + break; + } + } + } + + kill_cli_size = 320; + switch_file_write(p->audiopipe[1], kill_cli_buff, &kill_cli_size); + kill_cli_size = 320; + switch_file_write(p->audioskypepipe[1], kill_cli_buff, &kill_cli_size); + p->interface_state = SKYPIAX_STATE_DOWN; + kill_cli_size = 320; + switch_file_write(p->audiopipe[1], kill_cli_buff, &kill_cli_size); + kill_cli_size = 320; + switch_file_write(p->audioskypepipe[1], kill_cli_buff, &kill_cli_size); + + DEBUGA_SKYPE("Skype client GONE\n", SKYPIAX_P_LOG); + +#ifndef WIN32 + close(fd); +#else + closesocket(fd); +#endif + if (exit) + break; + } + + WARNINGA("server (I am it) GONE\n", SKYPIAX_P_LOG); +#ifndef WIN32 + close(s); +#else + closesocket(s); +#endif + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return NULL; +} +static void *SWITCH_THREAD_FUNC skypiax_do_tcp_cli_thread(switch_thread_t * thread, + void *obj) +//void *skypiax_do_tcp_cli_thread(void *data) +{ + struct skypiax_interface *p = obj; + int s, fd, len; + short in[NN / 2]; + short out[NN]; + unsigned int sin_size; + struct sockaddr_in my_addr; + struct sockaddr_in remote_addr; + int a; + int i; + unsigned int got; + + if (option_debug > 10) { + WARNINGA("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + memset(&my_addr, 0, sizeof(my_addr)); + my_addr.sin_family = AF_INET; + my_addr.sin_addr.s_addr = htonl(0x7f000001); /* use the localhost */ + my_addr.sin_port = htons(5558); //FIXME configurable! + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + ERRORA("socket Error\n", SKYPIAX_P_LOG); + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return NULL; + } + + if (bind(s, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) < 0) { + ERRORA("bind Error\n", SKYPIAX_P_LOG); + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } +#ifndef WIN32 + close(s); +#else + closesocket(s); +#endif + return NULL; + } + DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); + + listen(s, 6); + + sin_size = sizeof(remote_addr); + while ((fd = accept(s, (struct sockaddr *) &remote_addr, &sin_size)) > 0) { + DEBUGA_SKYPE("ACCEPTED\n", SKYPIAX_P_LOG); + while (p->interface_state != SKYPIAX_STATE_DOWN + && (p->skype_callflow == CALLFLOW_STATUS_INPROGRESS + || p->skype_callflow == SKYPIAX_STATE_UP)) { + int fdselect; + int rt; + fd_set fs; + struct timeval to; + + fdselect = 1; + FD_ZERO(&fs); + FD_SET(fdselect, &fs); + to.tv_usec = 100; + to.tv_sec = 0; + rt = 1; + if (rt > 0) { + + got = (NN / 2) * sizeof(short); + switch_file_read(p->audioskypepipe[0], in, &got); + + if (got > 0) { + a = 0; + for (i = 0; i < got / sizeof(short); i++) { + out[a] = in[i]; + a++; + out[a] = in[i]; + a++; + } + + len = send(fd, out, got * 2, 0); + + if (len == 0) { + ERRORA("Skype server GONE\n", SKYPIAX_P_LOG); + break; + } + } else { + switch_sleep(1000); + //ERRORA("Audio skype pipe give us: %u\n", SKYPIAX_P_LOG, got); + } + } + + } + ERRORA("Skype server GONE\n", SKYPIAX_P_LOG); +#ifndef WIN32 + close(fd); +#else + closesocket(fd); +#endif + break; + } + + WARNINGA("client (I am it) GONE\n", SKYPIAX_P_LOG); +#ifndef WIN32 + close(s); +#else + closesocket(s); +#endif + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return NULL; +} + +int skypiax_skypeaudio_init(struct skypiax_interface *p) +{ + + switch_status_t rv; + + rv = switch_file_pipe_create_ex(&p->audiopipe[0], &p->audiopipe[1], 2, skypiax_module_pool); + rv = switch_file_pipe_timeout_set(p->audiopipe[0], 100000); + +/* the pipe is our audio fd for pbx to poll on */ + p->skypiax_sound_capt_fd = p->audiopipe[0]; + + rv = + switch_file_pipe_create_ex(&p->audioskypepipe[0], &p->audioskypepipe[1], 2, + skypiax_module_pool); + rv = switch_file_pipe_timeout_set(p->audioskypepipe[0], 100); + if (option_debug > 10) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return 0; +} +switch_status_t skypiax_skypeaudio_read(private_t * tech_pvt) +{ + struct skypiax_interface *p; + short buf[640]; + unsigned int samples; + int rt; + + p = tech_pvt->p; + + //DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + + memset(buf, '\0', sizeof(buf)); + + rt = 1; + if (rt > 0) { + + samples = SAMPLES_PER_FRAME * sizeof(short); + + switch_file_read(p->audiopipe[0], tech_pvt->read_frame.data, &samples); + + //if ((samples = read(p->audiopipe[0], buf, SAMPLES_PER_FRAME * sizeof(short))) != 320) + if (samples != SAMPLES_PER_FRAME * sizeof(short)) { + if (samples) + DEBUGA_SKYPE("read=====> NOT GOOD samples=%d expected=%d\n", SKYPIAX_P_LOG, + samples, SAMPLES_PER_FRAME * sizeof(short)); + //do nothing + } else { + tech_pvt->read_frame.datalen = samples; + //DEBUGA_SKYPE("read=====> GOOD samples=%d\n", SKYPIAX_P_LOG, samples); + /* A real frame */ + } + } else { + DEBUGA_SKYPE("select returned %d\n", SKYPIAX_P_LOG, rt); + + } + + //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + + return SWITCH_STATUS_SUCCESS; +} + +#endif /* SKYPE_AUDIO */ + +#ifdef WIN32 +struct AsteriskHandles *win32_AsteriskHandlesSkype; +HWND win32_hInit_MainWindowHandle; +HINSTANCE win32_hInit_ProcessHandle; +char win32_acInit_WindowClassName[128]; +HANDLE win32_hGlobal_ThreadShutdownEvent; +UINT win32_uiGlobal_MsgID_SkypeControlAPIAttach; +UINT win32_uiGlobal_MsgID_SkypeControlAPIDiscover; +HWND win32_hGlobal_SkypeAPIWindowHandle = NULL; +DWORD win32_ulGlobal_PromptConsoleMode = 0; +HANDLE volatile win32_hGlobal_PromptConsoleHandle = NULL; + +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) +{ + char *res; + + if (!stringp || !*stringp || !**stringp) + return (char *) 0; + + res = *stringp; + while (**stringp && !strchr(delim, **stringp)) + ++(*stringp); + + if (**stringp) { + **stringp = '\0'; + ++(*stringp); + } + + return res; +} + +LRESULT APIENTRY skypiax_skype_present(HWND hWindow, UINT uiMessage, WPARAM uiParam, + LPARAM ulParam) +{ + LRESULT lReturnCode; + int fIssueDefProc; + struct skypiax_interface *p = NULL; + + lReturnCode = 0; + fIssueDefProc = 0; + switch (uiMessage) { + case WM_DESTROY: + win32_hInit_MainWindowHandle = NULL; + PostQuitMessage(0); + break; + case WM_COPYDATA: + if (win32_hGlobal_SkypeAPIWindowHandle == (HWND) uiParam) { + unsigned int howmany; + char msg_from_skype[2048]; + + PCOPYDATASTRUCT poCopyData = (PCOPYDATASTRUCT) ulParam; + + memset(msg_from_skype, '\0', sizeof(msg_from_skype)); + strncpy(msg_from_skype, (const char *) poCopyData->lpData, + sizeof(msg_from_skype) - 2); + + howmany = strlen(msg_from_skype) + 1; + switch_file_write(win32_AsteriskHandlesSkype->fdesc[1], msg_from_skype, &howmany); + //NOTICA("From Skype API: %s\n", SKYPIAX_P_LOG, (const char *) poCopyData->lpData); + lReturnCode = 1; + } + break; + default: + if (uiMessage == win32_uiGlobal_MsgID_SkypeControlAPIAttach) { + switch (ulParam) { + case SKYPECONTROLAPI_ATTACH_SUCCESS: + NOTICA("\n\n\tConnected to Skype API!\n", SKYPIAX_P_LOG); + win32_hGlobal_SkypeAPIWindowHandle = (HWND) uiParam; + switch_sleep(5000); + win32_AsteriskHandlesSkype->win32_hGlobal_SkypeAPIWindowHandle = + win32_hGlobal_SkypeAPIWindowHandle; + break; + case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: + WARNINGA + ("\n\n\tIf I do not 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); + 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 available\n", SKYPIAX_P_LOG); + break; + case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: + DEBUGA_SKYPE("Skype API available\n", SKYPIAX_P_LOG); + 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); +} + +int win32_Initialize_CreateWindowClass(void) +{ + unsigned char *paucUUIDString; + RPC_STATUS lUUIDResult; + int fReturnStatus; + UUID oUUID; + + fReturnStatus = 0; + lUUIDResult = UuidCreate(&oUUID); + win32_hInit_ProcessHandle = + (HINSTANCE) OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId()); + if (win32_hInit_ProcessHandle != NULL + && (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) { + if (UuidToString(&oUUID, &paucUUIDString) == RPC_S_OK) { + WNDCLASS oWindowClass; + + strcpy(win32_acInit_WindowClassName, "Skype-API-Skypiax-"); + strcat(win32_acInit_WindowClassName, (char *) paucUUIDString); + + oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + oWindowClass.lpfnWndProc = (WNDPROC) & skypiax_skype_present; + oWindowClass.cbClsExtra = 0; + oWindowClass.cbWndExtra = 0; + oWindowClass.hInstance = win32_hInit_ProcessHandle; + oWindowClass.hIcon = NULL; + oWindowClass.hCursor = NULL; + oWindowClass.hbrBackground = NULL; + oWindowClass.lpszMenuName = NULL; + oWindowClass.lpszClassName = win32_acInit_WindowClassName; + + if (RegisterClass(&oWindowClass) != 0) + fReturnStatus = 1; + + RpcStringFree(&paucUUIDString); + } + } + if (fReturnStatus == 0) + CloseHandle(win32_hInit_ProcessHandle), win32_hInit_ProcessHandle = NULL; + return (fReturnStatus); +} + +void win32_DeInitialize_DestroyWindowClass(void) +{ + UnregisterClass(win32_acInit_WindowClassName, win32_hInit_ProcessHandle); + CloseHandle(win32_hInit_ProcessHandle), win32_hInit_ProcessHandle = NULL; +} + +int win32_Initialize_CreateMainWindow(void) +{ + win32_hInit_MainWindowHandle = + CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, win32_acInit_WindowClassName, "", + WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, + 128, 128, NULL, 0, win32_hInit_ProcessHandle, 0); + return (win32_hInit_MainWindowHandle != NULL ? 1 : 0); +} + +void win32_DeInitialize_DestroyMainWindow(void) +{ + if (win32_hInit_MainWindowHandle != NULL) + DestroyWindow(win32_hInit_MainWindowHandle), win32_hInit_MainWindowHandle = NULL; +} + +DWORD win32_dwThreadId; + +void *SWITCH_THREAD_FUNC do_skype_thread(switch_thread_t * thread, 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 */ + + struct skypiax_interface *p; + p = obj; + + switch_file_pipe_create_ex(&p->AsteriskHandlesAst.fdesc[0], + &p->AsteriskHandlesAst.fdesc[1], 2, skypiax_module_pool); + + win32_AsteriskHandlesSkype = &p->AsteriskHandlesAst; + + win32_uiGlobal_MsgID_SkypeControlAPIAttach = + RegisterWindowMessage("SkypeControlAPIAttach"); + win32_uiGlobal_MsgID_SkypeControlAPIDiscover = + RegisterWindowMessage("SkypeControlAPIDiscover"); + + if (win32_uiGlobal_MsgID_SkypeControlAPIAttach != 0 + && win32_uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { + if (win32_Initialize_CreateWindowClass()) { + if (win32_Initialize_CreateMainWindow()) { + win32_hGlobal_ThreadShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (win32_hGlobal_ThreadShutdownEvent != NULL) { + if (SendMessage + (HWND_BROADCAST, win32_uiGlobal_MsgID_SkypeControlAPIDiscover, + (WPARAM) win32_hInit_MainWindowHandle, 0) != 0) { + win32_AsteriskHandlesSkype->win32_hInit_MainWindowHandle = + win32_hInit_MainWindowHandle; + while (1) { + MSG oMessage; + + while (GetMessage(&oMessage, 0, 0, 0) != FALSE) { + TranslateMessage(&oMessage); + DispatchMessage(&oMessage); + } + } + } + CloseHandle(win32_hGlobal_ThreadShutdownEvent); + } + win32_DeInitialize_DestroyMainWindow(); + } + win32_DeInitialize_DestroyWindowClass(); + } + } + return NULL; +} + +#else /* NOT WIN32 */ + +#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_interface *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_interface *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_interface *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_interface *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); + switch_sleep(1000); +} + +static void *SWITCH_THREAD_FUNC do_skype_thread(switch_thread_t * thread, void *obj) +{ + + struct skypiax_interface *p; + struct AsteriskHandles *AsteriskHandlesAst; + char buf[SKYPE_X11_BUF_SIZE]; + Display *disp = NULL; + Window root = -1; + Window win = -1; + + p = obj; + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + + switch_file_pipe_create_ex(&p->AsteriskHandlesAst.fdesc[0], + &p->AsteriskHandlesAst.fdesc[1], 2, skypiax_module_pool); + + AsteriskHandlesAst = &p->AsteriskHandlesAst; + //disp = XOpenDisplay(getenv("DISPLAY")); + disp = XOpenDisplay(p->X11_display); + if (!disp) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Cannot open X Display '%s', exiting skype thread\n", + p->X11_display); + return NULL; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "X Display '%s' opened\n", + p->X11_display); + } + + int xfd; + xfd = XConnectionNumber(disp); + fcntl(xfd, F_SETFD, FD_CLOEXEC); + + //FIXME pthread_cleanup_push(skypiax_skype_clean_disp, &xfd); + DEBUGA_SKYPE("PUSH disp %d\n", SKYPIAX_P_LOG, xfd); + + if (skypiax_skype_present(disp)) { + root = DefaultRootWindow(disp); + win = + XCreateSimpleWindow(disp, root, 0, 0, 1, 1, 0, + BlackPixel(disp, DefaultScreen(disp)), BlackPixel(disp, + DefaultScreen + (disp))); + + DEBUGA_SKYPE("skype_win=%d win=%d\n", SKYPIAX_P_LOG, (unsigned int) skype_win, + (unsigned int) win); + + AsteriskHandlesAst->skype_win = skype_win; + AsteriskHandlesAst->disp = disp; + AsteriskHandlesAst->win = win; + + snprintf(buf, SKYPE_X11_BUF_SIZE, "NAME 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); + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + return NULL; + } + + snprintf(buf, SKYPE_X11_BUF_SIZE, "PROTOCOL 6"); + 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); + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + 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); + 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'; + + //NOTICA("ClientMessage buf:|||%s||| buffer:|||%s||| serial=%ld|||\r\n",SKYPIAX_P_LOG,buf, buffer,an_event.xclient.serial); + //NOTICA ("SKYPE read: |||%s|||%d\n", SKYPIAX_P_LOG, buf, strlen(buf)); + //NOTICA ("SKYPE buffer: |||%s|||%d\n", SKYPIAX_P_LOG, buffer, strlen(buffer)); + + strcat(buffer, buf); + + if (i < 20) { /* last fragment */ + unsigned int howmany; + + howmany = strlen(b) + 1; + + switch_file_write(AsteriskHandlesAst->fdesc[1], b, &howmany); + //write(AsteriskHandlesAst->fdesc[1], "\0", 1); + //FIXME DEBUGA_SKYPE("SKYPE pipewrite: |||%s|||len=%d serial=%ld\n\n\n", SKYPIAX_P_LOG, b, strlen(b) + 1, an_event.xclient.serial); + //switch_sleep(1000); + 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); + return NULL; + } + //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + return NULL; + +} +#endif // WIN32 + + +int skypiax_skype_write(struct skypiax_interface *p, char *msg_to_skype) +{ +#ifdef WIN32 + static char acInputRow[1024]; + COPYDATASTRUCT oCopyData; + + if (option_debug > 100) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + sprintf(acInputRow, "%s", msg_to_skype); + if (option_debug > 1) + DEBUGA_SKYPE("acInputRow: |||%s||||\n", SKYPIAX_P_LOG, acInputRow); + /* send command to skype */ + oCopyData.dwData = 0; + oCopyData.lpData = acInputRow; + oCopyData.cbData = strlen(acInputRow) + 1; + if (oCopyData.cbData != 1) { + if (SendMessage + (p->AsteriskHandlesAst.win32_hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, + (WPARAM) p->AsteriskHandlesAst.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", + SKYPIAX_P_LOG); + p->skype = 0; + //FIXME p->skype_thread = SKYPIAX_PTHREADT_NULL; + p->skype_thread = NULL; + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + return -1; + } + } +#else /* WIN32 */ + struct AsteriskHandles *AsteriskHandlesAst; + + if (option_debug > 100) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + AsteriskHandlesAst = &p->AsteriskHandlesAst; + + if (option_debug > 101) { + DEBUGA_SKYPE("SENDING: |||%s||||\n", SKYPIAX_P_LOG, msg_to_skype); + } + + if (!skypiax_skype_send_message(AsteriskHandlesAst, 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); + } + return 0; + +} + +int skypiax_skype_read(struct skypiax_interface *p) +{ + + 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 fd; + int rt; + //fd_set fs; + //struct timeval to; + int i, a; + unsigned int howmany; + + if (option_debug > 100) { + DEBUGA_PBX("ENTERING FUNC\n", SKYPIAX_P_LOG); + } + + memset(read_from_pipe, 0, 4096); + memset(messaggio, 0, 4096); + memset(messaggio_2, 0, 4096); + + rt = 1; + if (rt > 0) { + howmany = sizeof(read_from_pipe); + switch_file_read(p->AsteriskHandlesAst.fdesc[0], 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') { + + //if (option_debug > 101) + DEBUGA_SKYPE("read_skype: howmany=%d, i=%d, a=%d, |||%s||| \n", SKYPIAX_P_LOG, + howmany, i, a, messaggio); + + if (!strncasecmp(messaggio, "ERROR 92 CALL", 12)) { + ERRORA("Skype got ERROR: |||%s|||, the number we called was not recognized\n", + SKYPIAX_P_LOG, messaggio); + p->skype_callflow = CALLFLOW_STATUS_FINISHED; + if (option_debug) + DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); + p->skype_call_id[0] = '\0'; + + if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + p->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + p->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(p->skype_friends, 0, 4096); + strncpy(p->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(p->skype_fullname, 0, 512); + strncpy(p->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(p->skype_displayname, 0, 512); + strncpy(p->skype_displayname, &messaggio_2[10], 511); + } + if (!strcasecmp(messaggio, "ERROR")) { + ERRORA("Skype got ERROR: |||%s|||\n", SKYPIAX_P_LOG, messaggio); + p->skype_callflow = CALLFLOW_STATUS_FINISHED; + if (option_debug) + DEBUGA_SKYPE("skype_call now is DOWN\n", SKYPIAX_P_LOG); + p->skype_call_id[0] = '\0'; + + if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + p->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + p->interface_state = SKYPIAX_STATE_DOWN; + } + } + 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(p->callid_number, value, sizeof(p->callid_number) - 1); + WARNINGA + ("the skype_call %s caller PARTNER_HANDLE (p->callid_number) is: %s\n", + SKYPIAX_P_LOG, id, p->callid_number); + return CALLFLOW_INCOMING_RING; + } + if (!strcasecmp(prop, "PARTNER_DISPNAME")) { + snprintf(p->callid_name, sizeof(p->callid_name) - 1, "%s%s%s", value, + where ? " " : "", where ? where : ""); + WARNINGA + ("the skype_call %s caller PARTNER_DISPNAME (p->callid_name) is: %s\n", + SKYPIAX_P_LOG, id, p->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 (p->interface_state == SKYPIAX_STATE_DOWN) + p->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 (p->interface_state == SKYPIAX_STATE_DOWN) + p->interface_state = SKYPIAX_STATE_PRERING; + } + + if (!strcasecmp(prop, "DTMF")) { + switch_core_session_t *session = NULL; + private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + + DEBUGA_SKYPE("Call %s received a DTMF: %s\n", SKYPIAX_P_LOG, id, value); + + tech_pvt = p->tech_pvt; + session = tech_pvt->session; + channel = switch_core_session_get_channel(session); + + if (channel) { + switch_dtmf_t dtmf = + { (char) value[0], switch_core_default_dtmf_duration(0) }; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%c DTMF %s\n", + dtmf.digit, switch_channel_get_name(channel)); + switch_mutex_lock(tech_pvt->flag_mutex); + switch_channel_queue_dtmf(channel, &dtmf); + switch_set_flag(tech_pvt, TFLAG_DTMF); + switch_mutex_unlock(tech_pvt->flag_mutex); + } + } + + 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, p->skype_call_id)) { + strncpy(p->skype_call_id, id, sizeof(p->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 (p->interface_state != SKYPIAX_STATE_DIALING) { + /* we are not calling out */ + + if (1) { + /* we are not inside an active call */ + p->skype_callflow = CALLFLOW_STATUS_RINGING; + p->interface_state = SKYPIAX_STATE_RING; + /* no owner, no active call, let's answer */ + skypiax_skype_write(p, "SET AGC OFF"); + switch_sleep(10000); + skypiax_skype_write(p, "SET AEC OFF"); + switch_sleep(10000); + sprintf(msg_to_skype, "GET CALL %s PARTNER_DISPNAME", id); + skypiax_skype_write(p, msg_to_skype); + switch_sleep(10000); + sprintf(msg_to_skype, "GET CALL %s PARTNER_HANDLE", id); + skypiax_skype_write(p, msg_to_skype); + switch_sleep(10000); + sprintf(msg_to_skype, "ALTER CALL %s ANSWER", id); + skypiax_skype_write(p, msg_to_skype); + if (option_debug) + DEBUGA_SKYPE("We answered a Skype RING on skype_call %s\n", + SKYPIAX_P_LOG, id); + strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); + } else { + /* we're owned, we're in a call, let's refuse */ + sprintf(msg_to_skype, "SET CALL %s STATUS FINISHED", id); + skypiax_skype_write(p, msg_to_skype); + switch_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 { + /* we are calling out */ + p->skype_callflow = CALLFLOW_STATUS_RINGING; + p->interface_state = SKYPIAX_STATE_RINGING; + //FIXME ast_queue_control(p->owner, SKYPIAX_CONTROL_RINGING); + strncpy(p->skype_call_id, id, sizeof(p->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")) { + p->skype_callflow = CALLFLOW_STATUS_EARLYMEDIA; + p->interface_state = SKYPIAX_STATE_DIALING; + //FIXME ast_queue_control(p->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); + + } else if (!strcasecmp(value, "FINISHED")) { + global_session = NULL; //FIXME + //p->skype_callflow = CALLFLOW_STATUS_FINISHED; + if (option_debug) + DEBUGA_SKYPE("skype_call %s now is DOWN\n", SKYPIAX_P_LOG, id); + p->skype_call_id[0] = '\0'; + + if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + //p->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + p->interface_state = SKYPIAX_STATE_DOWN; + } + + } else if (!strcasecmp(value, "CANCELLED")) { + p->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); + p->skype_call_id[0] = '\0'; + + if (p->interface_state != SKYPIAX_STATE_HANGUP_REQUESTED) { + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + p->interface_state = SKYPIAX_STATE_DOWN; + return CALLFLOW_INCOMING_HANGUP; + } else { + p->interface_state = SKYPIAX_STATE_DOWN; + } + } else if (!strcasecmp(value, "FAILED")) { + p->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); + p->skype_call_id[0] = '\0'; + strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); + p->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, p->skype_call_id)) { + /* this is the id of the call we are in, probably we generated it */ + p->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(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); + p->interface_state = SKYPIAX_STATE_DOWN; + p->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); + + } + } else if (!strcasecmp(value, "ROUTING")) { + p->skype_callflow = CALLFLOW_STATUS_ROUTING; + p->interface_state = SKYPIAX_STATE_DIALING; + strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); + DEBUGA_SKYPE("skype_call: %s is now ROUTING\n", SKYPIAX_P_LOG, id); + } else if (!strcasecmp(value, "UNPLACED")) { + p->skype_callflow = CALLFLOW_STATUS_UNPLACED; + p->interface_state = SKYPIAX_STATE_DIALING; + strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); + DEBUGA_SKYPE("skype_call: %s is now UNPLACED\n", SKYPIAX_P_LOG, id); + } else if (!strcasecmp(value, "INPROGRESS")) { + p->skype_callflow = CALLFLOW_STATUS_INPROGRESS; + strncpy(p->skype_call_id, id, sizeof(p->skype_call_id) - 1); + p->interface_state = SKYPIAX_STATE_UP; + if (option_debug > 1) + DEBUGA_SKYPE("skype_call: %s is now active\n", SKYPIAX_P_LOG, id); + + if (option_debug > 1) + DEBUGA_SKYPE("skype_call: %s SKYPIAX_CONTROL_ANSWER sent\n", + SKYPIAX_P_LOG, id); + + if (1) { + char msg_to_skype[1024]; + + if (1) { + switch_threadattr_t *thd_attr = NULL; + + switch_threadattr_create(&thd_attr, skypiax_module_pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&p->tcp_srv_thread, thd_attr, + skypiax_do_tcp_srv_thread, p, skypiax_module_pool); + DEBUGA_SKYPE("started tcp_srv_thread thread.\n", SKYPIAX_P_LOG); + + switch_threadattr_create(&thd_attr, skypiax_module_pool); + switch_threadattr_detach_set(thd_attr, 1); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_thread_create(&p->tcp_cli_thread, thd_attr, + skypiax_do_tcp_cli_thread, p, skypiax_module_pool); + DEBUGA_SKYPE("started tcp_cli_thread thread.\n", SKYPIAX_P_LOG); + } + switch_sleep(100000); + sprintf(msg_to_skype, "ALTER CALL %s SET_OUTPUT PORT=\"5556\"", id); + skypiax_skype_write(p, msg_to_skype); + switch_sleep(100000); + sprintf(msg_to_skype, "ALTER CALL %s SET_INPUT PORT=\"5558\"", id); + skypiax_skype_write(p, msg_to_skype); + switch_sleep(100000); + } + + p->skype_callflow = SKYPIAX_STATE_UP; + + /**************************/ + + //FIXME switch_core_session_t **new_session; + + //FIXME *new_session=switch_loadable_module_create_interface(skypiax_endpoint_interface, pool); + + if (!global_session) { //FIXME FIXME FIXME + switch_core_session_t *session = NULL; + private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, + "New Inbound Channel!\n"); + + if ((session = + switch_core_session_request(skypiax_endpoint_interface, + NULL)) != 0) { + switch_core_session_add_stream(session, NULL); + if ((tech_pvt = + (private_t *) switch_core_session_alloc(session, + sizeof(private_t))) != 0) { + channel = switch_core_session_get_channel(session); + skypiax_tech_init(tech_pvt, session, p); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "Hey where is my memory pool?\n"); + switch_core_session_destroy(&session); + break; + } + + // if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), NULL, dialplan, cid_name, cid_num, ip, NULL, NULL, NULL, modname, NULL, dest)) != 0) + + if ((tech_pvt->caller_profile = + switch_caller_profile_new(switch_core_session_get_pool(session), + "skypiax", "XML", "gmaruzz_from_skype", + "calling_number", NULL, "calling_ani", + NULL, NULL, "mod_skypiax", "default", + "5000")) != 0) { + char name[128]; + switch_snprintf(name, sizeof(name), "skypiax/%s-%04x", + tech_pvt->caller_profile->destination_number, + rand() & 0xffff); + switch_channel_set_name(channel, name); + switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); + } + switch_channel_set_state(channel, CS_INIT); + if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, + "Error spawning thread\n"); + switch_core_session_destroy(&session); + } + } + } else { + switch_core_session_t *session = NULL; + private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + + tech_pvt = p->tech_pvt; + //session = tech_pvt->session; + session = global_session; + channel = switch_core_session_get_channel(session); + switch_channel_mark_pre_answered(channel); + + //switch_channel_set_state(channel, CS_EXECUTE); + + } + /**************************/ + + } 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 + + } + + if (option_debug > 100) { + DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + } + //DEBUGA_PBX("EXITING FUNC\n", SKYPIAX_P_LOG); + return 0; +} + +
participants (1)
-
FreeSWITCH SVN