Implement event reading.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 18 Apr 2014 22:52:14 +0000 (22:52 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 18 Apr 2014 22:52:14 +0000 (22:52 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1507 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

index ad4e3f35d752c72e43844886db481e43406c8e2b..429cd3c8b8e8c9b6019e3a4f3b36dec9c47ce31e 100644 (file)
@@ -1,4 +1,5 @@
 #include "evdev.h"
+#include <stdexcept>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sstream>
-
-static bool
-bit_set(unsigned int bit, const uint8_t * field)
-{
-  return ((field[bit / 8] & (1 << (bit % 8))) != 0);
-}
+#include <assert.h>
 
 namespace FreeDV {
+  static bool
+  bit_set(unsigned int bit, const uint8_t * field)
+  {
+    return ((field[bit / 8] & (1 << (bit % 8))) != 0);
+  }
+
+  NORETURN static void
+  do_throw(
+   const int error,
+   const char * name,
+   const char * special_file,
+   const char * message = 0)
+  {
+    std::ostringstream str;
+
+    str << "EVDEV ";
+
+    str << '\"' << name << "\" device \"" << special_file
+     << "\" set-up error: ";
+    if ( message ) {
+      str << message;
+      if ( error )
+        str << ": ";
+    }
+    if ( error )
+      str << strerror(error);
+
+    str << '.';
+    throw std::runtime_error(str.str().c_str());
+  }
+
   // Remove extra spaces from string, in place.
-  char *
+  static char *
   clean_string(char * string)
   {
     char * s = string;
@@ -121,11 +148,68 @@ namespace FreeDV {
     return true;
   }
   
-  EvDev::EvDev(const char *)
+  int
+  EvDev::poll_fds(PollType * array, int length)
+  {
+    if ( length >= 0 ) {
+      array[0].fd = fd;
+      return 1;
+    }
+    else
+      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;
+  }
+
+  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);
+  }
+
+  EvDev::EvDev(const char * _name)
+  : fd(-1), name(strdup(_name)), special_file(0)
+  {
+    static std::size_t         count;
+    static device_enumeration *        enumeration = 0;
+
+    if ( (fd = open(name, O_RDWR) >= 0 ) ) {
+      special_file = strdup(name);
+      return;
+    }
+
+    if ( enumeration == 0 )
+      enumeration = enumerate(count);
+
+    std::size_t length = strlen(name);
+
+    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);
+
+        if ( fd < 0 )
+          do_throw(errno, name, special_file, "open");
+      }
+    } 
   }
   
   EvDev::~EvDev()
   {
+    close(fd);
+    delete name;
+    delete special_file;
   }
 }
index 794cb4ac83ef1bfe31110be3dbf000663906a10e..d8d3589b7155d6d08db5278b9432201067d09dc1 100644 (file)
@@ -1,5 +1,6 @@
 #include <cstdint>
 #include <linux/input.h>
+#include "drivers.h"
 
 namespace FreeDV {
   class EvDev {
@@ -12,6 +13,9 @@ namespace FreeDV {
     };
   
   private:
+    int                        fd;
+    const char *       name;
+    const char *       special_file;
   
                        EvDev(const EvDev &);
     EvDev &            operator =(const EvDev &);
@@ -29,6 +33,12 @@ namespace FreeDV {
     static device_enumeration *
                        enumerate(std::size_t & count);
   
+    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);
                        ~EvDev();
   };
index 17de634e019cdfa07933ac973f2c0f6dced8d57f..0263329f4c03da2777de83052584587b9a5ace99 100644 (file)
@@ -5,7 +5,6 @@
 ///
 
 #include "evdev.h"
-#include "drivers.h"
 #include <iostream>
 #include <stdexcept>