]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
windows T.31
authorJeff Lenk <jeff@jefflenk.com>
Fri, 9 Dec 2011 21:10:55 +0000 (15:10 -0600)
committerJeff Lenk <jeff@jefflenk.com>
Fri, 9 Dec 2011 21:10:55 +0000 (15:10 -0600)
src/mod/applications/mod_spandsp/mod_spandsp_modem.c

index 02459b13f78921665bdc4f829e7dbd41ae1edad6..a3c959da3172a159fcaeb1a9391c424129fe3dde 100644 (file)
@@ -76,7 +76,23 @@ static int t31_at_tx_handler(at_state_t *s, void *user_data, const uint8_t *buf,
        modem_t *modem = user_data;
     switch_size_t wrote;
 
+#ifndef WIN32
        wrote = write(modem->master, buf, len);
+#else
+               OVERLAPPED o;
+               o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+               /* Initialize the rest of the OVERLAPPED structure to zero. */
+               o.Internal = 0;
+               o.InternalHigh = 0;
+               o.Offset = 0;
+               o.OffsetHigh = 0;
+               assert(o.hEvent);
+               if (!WriteFile((HANDLE)modem->master, buf, len, (LPDWORD)&wrote, &o)) {
+                       GetOverlappedResult((HANDLE)modem->master,&o,(LPDWORD)&wrote,TRUE);
+               }
+               CloseHandle (o.hEvent);
+#endif
 
     if (wrote != len) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to pass the full buffer onto the device file. " 
@@ -152,8 +168,13 @@ int modem_close(modem_t *modem)
        switch_clear_flag(modem, MODEM_FLAG_RUNNING);
 
        if (modem->master > -1) {
+#ifndef WIN32
                shutdown(modem->master, 2);
                close(modem->master);
+#else
+               SetCommMask((HANDLE)modem->master, 0);
+               CloseHandle((HANDLE)modem->master);
+#endif
                modem->master = -1;
                r++;
        }
@@ -184,7 +205,7 @@ int modem_close(modem_t *modem)
 int modem_init(modem_t *modem, modem_control_handler_t control_handler)
 {
 #ifdef WIN32
-       u_long arg = 1;
+       COMMTIMEOUTS timeouts={0};
 #endif
        
        memset(modem, 0, sizeof(*modem));
@@ -207,19 +228,37 @@ int modem_init(modem_t *modem, modem_control_handler_t control_handler)
 
        modem->stty = ttyname(modem->slave);
 #else
-
-#if !defined(HAVE_POSIX_OPENPT)
+#if WIN32
+       modem->slot = 4+globals.NEXT_ID++; /* need work here we start at COM4 for now*/
+       snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot);
+
+       modem->master = (int)CreateFile(modem->devlink,
+       GENERIC_READ | GENERIC_WRITE,
+       0,
+       0,
+       OPEN_EXISTING,
+       FILE_FLAG_OVERLAPPED,
+       0);
+       if(modem->master==(int)INVALID_HANDLE_VALUE) {
+               if(GetLastError()==ERROR_FILE_NOT_FOUND) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port does not exist\n");
+                       return -1;
+               }
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port open error\n");
+               return -1;
+       }
+#elif !defined(HAVE_POSIX_OPENPT)
     modem->master = open("/dev/ptmx", O_RDWR);
 #else
     modem->master = posix_openpt(O_RDWR | O_NOCTTY);
 #endif
 
+#ifndef WIN32
     if (modem->master < 0) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize UNIX98 master pty\n");
                
     }
 
-#ifndef WIN32
     if (grantpt(modem->master) < 0) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to grant access to slave pty\n");
                
@@ -231,7 +270,6 @@ int modem_init(modem_t *modem, modem_control_handler_t control_handler)
     }
 
     modem->stty = ptsname(modem->master);
-#endif
 
     if (modem->stty == NULL) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to obtain slave pty filename\n");
@@ -243,6 +281,7 @@ int modem_init(modem_t *modem, modem_control_handler_t control_handler)
     if (modem->slave < 0) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to open slave pty %s\n", modem->stty);
     }
+#endif
 
 #ifdef SOLARIS
     ioctl(modem->slave, I_PUSH, "ptem");  /* push ptem */
@@ -250,12 +289,12 @@ int modem_init(modem_t *modem, modem_control_handler_t control_handler)
 #endif
 #endif
 
+#ifndef WIN32
        modem->slot = globals.NEXT_ID++;
        snprintf(modem->devlink, sizeof(modem->devlink), "/dev/FS%d", modem->slot);
        
     unlink(modem->devlink);
 
-#ifndef WIN32
     if (symlink(modem->stty, modem->devlink)) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to create %s symbolic link\n", modem->devlink);
                modem_close(modem);
@@ -268,8 +307,15 @@ int modem_init(modem_t *modem, modem_control_handler_t control_handler)
         return -1;
     }
 #else
-       if (ioctlsocket(modem->master, FIONBIO, &arg) == SOCKET_ERROR) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", "Unknown"); /* need ttyname(modem->master)); */
+       timeouts.ReadIntervalTimeout=50;
+       timeouts.ReadTotalTimeoutConstant=50;
+       timeouts.ReadTotalTimeoutMultiplier=10;
+
+       timeouts.WriteTotalTimeoutConstant=50;
+       timeouts.WriteTotalTimeoutMultiplier=10;
+
+       if(!SetCommTimeouts((HANDLE)modem->master, &timeouts)){
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", modem->devlink);
                modem_close(modem);
                return -1;
        }
@@ -365,7 +411,9 @@ static switch_status_t channel_on_init(switch_core_session_t *session)
        switch_assert(channel != NULL);
 
        if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
+#ifndef WIN32
                int tioflags;
+#endif
                char call_time[16];
                char call_date[16];
                switch_size_t retsize;
@@ -1118,75 +1166,62 @@ static int modem_wait_sock(int sock, uint32_t ms, modem_poll_t flags)
 
 }
 #else
-#pragma warning( push )
-#pragma warning( disable : 6262 ) /* warning C6262: Function uses '98348' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap */
-static int modem_wait_sock(int sock, uint32_t ms, modem_poll_t flags)
+static int modem_wait_sock(int handle, int ms, modem_poll_t flags)
 {
-       int s = 0, r = 0;
-       fd_set rfds;
-       fd_set wfds;
-       fd_set efds;
-       struct timeval tv;
-
-       FD_ZERO(&rfds);
-       FD_ZERO(&wfds);
-       FD_ZERO(&efds);
-
-       /* Wouldn't you rather know?? */
-       assert(sock <= FD_SETSIZE);
-
-       
-       if ((flags & MODEM_POLL_READ)) {
-#pragma warning( push )
-#pragma warning( disable : 4127 )
-       FD_SET(sock, &rfds);
-       }
+/* this method ignores ms and waits infinitely */
+       DWORD dwEvtMask;
+       OVERLAPPED o;
+       BOOL result;
 
-       if ((flags & MODEM_POLL_WRITE)) {
-#pragma warning( push )
-#pragma warning( disable : 4127 )
-       FD_SET(sock, &wfds);
-#pragma warning( pop ) 
-       }
+       result = SetCommMask((HANDLE)handle, EV_RXCHAR);
 
-       if ((flags & MODEM_POLL_ERROR)) {
-#pragma warning( push )
-#pragma warning( disable : 4127 )
-       FD_SET(sock, &efds);
-#pragma warning( pop ) 
+       if (!result) 
+       {
+               /* failed */
+               return 0;
        }
 
-       tv.tv_sec = ms / 1000;
-       tv.tv_usec = (ms % 1000) * ms;
-       
-       s = select(sock + 1, (flags & MODEM_POLL_READ) ? &rfds : NULL, (flags & MODEM_POLL_WRITE) ? &wfds : NULL, (flags & MODEM_POLL_ERROR) ? &efds : NULL, &tv);
-
-       if (s < 0) {
-               r = s;
-       } else if (s > 0) {
-               if ((flags & MODEM_POLL_READ) && FD_ISSET(sock, &rfds)) {
-                       r |= MODEM_POLL_READ;
-               }
-
-               if ((flags & MODEM_POLL_WRITE) && FD_ISSET(sock, &wfds)) {
-                       r |= MODEM_POLL_WRITE;
-               }
-
-               if ((flags & MODEM_POLL_ERROR) && FD_ISSET(sock, &efds)) {
-                       r |= MODEM_POLL_ERROR;
+       o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+       /* Initialize the rest of the OVERLAPPED structure to zero. */
+       o.Internal = 0;
+       o.InternalHigh = 0;
+       o.Offset = 0;
+       o.OffsetHigh = 0;
+       assert(o.hEvent);
+
+       result = WaitCommEvent((HANDLE)handle, &dwEvtMask, &o);
+
+       if (result == 0)
+       {
+               if (GetLastError() != ERROR_IO_PENDING) {
+                       /* something went horribly wrong with WaitCommEvent(), so 
+                       clear all errors and try again */
+                       DWORD comerrors;
+                       ClearCommError((HANDLE)handle,&comerrors,0);
+                       CloseHandle (o.hEvent);
+               } else {
+                       /* IO is pending, wait for it to finish */
+                       WaitForSingleObject(o.hEvent,INFINITE);
+                       CloseHandle (o.hEvent);
+                       return MODEM_POLL_READ;
                }
+               return 0;
        }
 
-       return r;
-
+       CloseHandle (o.hEvent);
+       return MODEM_POLL_READ;
 }
-#pragma warning( pop ) 
 #endif
 
 static void *SWITCH_THREAD_FUNC modem_thread(switch_thread_t *thread, void *obj)
 {
        modem_t *modem = obj;
        int r, avail;
+#ifdef WIN32
+       DWORD readBytes;
+       OVERLAPPED o;
+#endif
        char buf[T31_TX_BUF_LEN], tmp[80];
 
        switch_mutex_lock(globals.mutex);
@@ -1224,7 +1259,23 @@ static void *SWITCH_THREAD_FUNC modem_thread(switch_thread_t *thread, void *obj)
                        continue;
                }
                
+#ifndef WIN32          
                r = read(modem->master, buf, avail);
+#else
+               o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+               /* Initialize the rest of the OVERLAPPED structure to zero. */
+               o.Internal = 0;
+               o.InternalHigh = 0;
+               o.Offset = 0;
+               o.OffsetHigh = 0;
+               assert(o.hEvent);
+               if (!ReadFile((HANDLE)modem->master, buf, avail, &readBytes, &o)) {
+                       GetOverlappedResult((HANDLE)modem->master,&o,&readBytes,TRUE);
+               }
+               CloseHandle (o.hEvent);
+               r = readBytes;
+#endif
 
                t31_at_rx(modem->t31_state, buf, r);