Debugged evdev.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 19 Apr 2014 05:39:41 +0000 (05:39 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Sat, 19 Apr 2014 05:39:41 +0000 (05:39 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1511 01035d8c-6547-0410-b346-abe4f91aad63

freedv-server/source/platform/linux/evdev.cpp
freedv-server/source/platform/linux/evdev.h
freedv-server/source/platform/linux/ptt_evdev.cpp
freedv-server/source/run.cpp

index c6e7974392cb281c0037c1777e29b49d99c4291d..ec38dcf244d8c33f3791bf82904dc3ba20753bb0 100644 (file)
@@ -5,6 +5,7 @@
 ///
 #include "evdev.h"
 #include <stdexcept>
+#include <iostream>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -187,24 +188,19 @@ namespace FreeDV {
       throw std::invalid_argument("poll_fds() called with zero-size array.");
   }
 
-  std::size_t
-  EvDev::ready()
-  {
-    int length = 0;
-
-    if ( ioctl(fd, FIONREAD, &length) < 0 )
-      do_throw(errno, name, special_file, "ioctl FIONREAD");
-
-    return length / sizeof(input_event);
-  }
-
   std::size_t
   EvDev::read_events(input_event * data, std::size_t count)
   {
     const int result = read(fd, data, count * sizeof(*data));
-    if ( result < 0 )
-      do_throw(errno, name, special_file, "read");
-    return result / sizeof(*data);
+    if ( result < 0 ) {
+      if ( errno == EAGAIN ) {
+        return 0;
+      }
+      else
+        do_throw(errno, name, special_file, "read");
+    }
+    else
+      return result / sizeof(*data);
   }
 
   EvDev::EvDev(const char * _name)
@@ -213,7 +209,7 @@ namespace FreeDV {
     static std::size_t         count;
     static device_enumeration *        enumeration = 0;
 
-    if ( (fd = open(name, O_RDWR) >= 0 ) ) {
+    if ( (fd = open(name, O_RDWR|O_NONBLOCK) >= 0 ) ) {
       special_file = strdup(name);
       return;
     }
@@ -226,7 +222,7 @@ namespace FreeDV {
     for ( std::size_t i = 0; i < count; i++ ) {
       if ( strncmp(name, enumeration[i].name, length) == 0 ) {
         special_file = strdup(enumeration[i].special_file);
-        fd = open(special_file, O_RDWR);
+        fd = open(special_file, O_RDWR|O_NONBLOCK);
 
         if ( fd < 0 )
           do_throw(errno, name, special_file, "open");
index 224ef26330c92df157867491884a57726f456e60..6b98c32deedc94be78b87e17733af3186d6f2703 100644 (file)
@@ -48,8 +48,6 @@ namespace FreeDV {
 
     int                        poll_fds(PollType *, int);
 
-    std::size_t                ready();
-
     std::size_t                read_events(input_event * data, std::size_t count);
 
                        EvDev(const char * name);
index 08f3c16eb08c00a755297ec113e88f4428b7f2f4..e99600114c62dc1325b863b4664dfb4445c5f9da 100644 (file)
@@ -75,7 +75,7 @@ namespace FreeDV {
 
   PTT_EvDev::PTT_EvDev(const char * _parameters)
   : PTTInput("evdev", _parameters), dev(0), button_index(0), pressed(false),
-    changed(false)
+    changed(true)
   {
     char *     p = strdup(parameters);
     char *     number = index(p, ',');
@@ -117,30 +117,29 @@ namespace FreeDV {
   void
   PTT_EvDev::process_events()
   {
-    while ( dev->ready() > 0 ) {
-      input_event      events[10];
-
-      const std::size_t count = dev->read_events(
-       events,
-       sizeof(events) / sizeof(*events));
+    int                count;
+    input_event        events[10];
 
+    while ( (count = dev->read_events(
+     events,
+     sizeof(events) / sizeof(*events)))
+     > 0 ) {
+  
       for ( std::size_t i = 0; i < count; i++ ) {
         const input_event * const event = &events[i];
         if ( event->type == EV_KEY && event->code == button_index ) {
           switch ( event->value ) {
           case 0:
-            if ( pressed )
-             changed = true;
-           pressed = false;
+           changed = true;
+           pressed = false;
             break;
           case 1:
-            if ( !pressed )
-             changed = true;
+           changed = true;
             pressed = true;
             break;
-         default:
-           ;
-         }
+         default:
+           ;
+         }
         }
       }
     }
@@ -149,13 +148,16 @@ namespace FreeDV {
   std::size_t
   PTT_EvDev::ready()
   {
-    return dev->ready();
+    process_events();
+    if ( changed )
+      return 1;
+    else
+      return 0;
   }
 
   bool
   PTT_EvDev::state()
   {
-    process_events();
     changed = false;
     return pressed;
   }
index 0604325cad64c6051a65b6c559b63962bdaae4e4..5d94066a81fb44e9cbe0d4710c7c2d14ab54d845 100644 (file)
@@ -29,15 +29,10 @@ namespace FreeDV {
   private:
     const std::size_t  FIFOSize = MaximumFrameSamples * sizeof(int16_t) * 2;
     Interfaces * const i;
-    bool               begin_receive;
-    bool               begin_transmit;
     FIFO               codec_fifo;
     FIFO               in_fifo;
     FIFO               out_fifo;
     int                        poll_fd_count;
-    bool               ptt_digital;
-    bool               ptt_ssb;
-    bool               started;
     PollType           poll_fds[100];
  
     // Disable copy constructor and operator=().
@@ -46,8 +41,6 @@ namespace FreeDV {
 
     bool               add_poll_device(IODevice * device);
     NORETURN void      do_throw(int error, const char * message);
-    void               key_down();
-    void               key_up();
     void               receive();
     void               reset();
     void               transmit_digital();
@@ -65,23 +58,11 @@ namespace FreeDV {
   };
   
   Run::Run(Interfaces * interfaces)
-  : i(interfaces), begin_receive(true), begin_transmit(false),
+  : i(interfaces),
     codec_fifo(FIFOSize), in_fifo(FIFOSize),
-    out_fifo(FIFOSize), poll_fd_count(0), ptt_digital(false), ptt_ssb(false),
-    started(false)
+    out_fifo(FIFOSize), poll_fd_count(0)
   {
     reset();
-
-    // FIX: This needs to be done at the start of the receive or transmit
-    // loop, so that only the necessary devices will be polled.
-    if ( !add_poll_device(i->receiver) )
-      add_poll_device(i->loudspeaker);
-    if ( !add_poll_device(i->microphone) )
-      add_poll_device(i->transmitter);
-    add_poll_device(i->ptt_input_digital);
-    add_poll_device(i->ptt_input_ssb);
-    add_poll_device(i->text_input);
-    add_poll_device(i->user_interface);
   }
 
   Run::~Run()
@@ -97,17 +78,9 @@ namespace FreeDV {
      &poll_fds[poll_fd_count],
      space - poll_fd_count);
 
-    if ( result >= 0 ) {
-      const int new_size = poll_fd_count + result;
-
-      if ( new_size < space ) {
-        poll_fd_count = new_size;
-        return new_size > 0;
-      }
-      else
-        do_throw(0, "Too many file descriptors for poll");
-    }
-    else {
+    if ( result > 0 )
+      poll_fd_count += result;
+    else if ( result < 0 ) {
       std::ostringstream       str;
 
       device->print(str);
@@ -134,35 +107,11 @@ namespace FreeDV {
   void
   Run::reset()
   {
-    started = false;
     in_fifo.reset();
     codec_fifo.reset();
     out_fifo.reset();
   }
 
-  void
-  Run::key_down() {
-    if ( i->keying_output->ready() ) {
-      i->keying_output->key(true);
-      begin_transmit = false;
-    }
-    else {
-      std::cerr << "Keying output is stalled." << std::endl;
-    }
-  }
-  
-  void
-  Run::key_up()
-  {
-    if ( i->keying_output->ready() ) {
-      i->keying_output->key(false);
-      begin_receive = false;
-    }
-    else {
-      std::cerr << "Keying output is stalled." << std::endl;
-    }
-  }
-
   // FIX: Parallelize the modem and codec into their own threads. Make the
   // FIFO do locking.
   void
@@ -261,10 +210,8 @@ namespace FreeDV {
                                   out_samples * 2),
                                  out_samples);
 
-      if ( result > 0 ) {
-        started = true;
+      if ( result > 0 )
         out_fifo.get_done(result * 2);
-      }
       else if ( result < 0 )
        std::cerr << "Loudspeaker I/O error: " << strerror(errno) << std::endl;
     }
@@ -273,19 +220,27 @@ namespace FreeDV {
   void
   Run::run()
   {
-    for ( ; ; ) {
-      receive();
+    add_poll_device(i->ptt_input_digital);
+    add_poll_device(i->ptt_input_ssb);
 
-      for ( int j = 0; j < poll_fd_count; j++ )
+    for ( ; ; ) {
+      for ( int j = 0; j < poll_fd_count; j++ ) {
         poll_fds[j].revents = 0;
+        poll_fds[j].events = POLLIN;
+      }
 
-      const int result = IODevice::poll(
-       poll_fds,
-       poll_fd_count,
-       AudioFrameDuration);
+      
+      const int result = IODevice::poll(poll_fds, poll_fd_count, 1000);
 
       if ( result < 0 )
         do_throw(result, "Poll");
+
+      if ( i->ptt_input_digital->ready() ) {
+        std::cerr << "Digital: " << i->ptt_input_digital->state() << std::endl;
+      }
+      if ( i->ptt_input_ssb->ready() ) {
+        std::cerr << "SSB: " << i->ptt_input_ssb->state() << std::endl;
+      }
     }
   }