Write PTT logic.
authorbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 22 Apr 2014 00:17:58 +0000 (00:17 +0000)
committerbruceperens <bruceperens@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 22 Apr 2014 00:17:58 +0000 (00:17 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1537 01035d8c-6547-0410-b346-abe4f91aad63

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

index ec38dcf244d8c33f3791bf82904dc3ba20753bb0..39dafda678c6e23bb289899a0029c9b3c10fcc9c 100644 (file)
@@ -50,12 +50,15 @@ namespace FreeDV {
     throw std::runtime_error(str.str().c_str());
   }
 
-  // Remove extra spaces from string, in place.
+  // Remove redundant elements from string.
   static char *
   clean_string(char * string)
   {
-    char * s = string;
+    // Remove trailing space.
+    std::size_t        length = strlen(string);
+    char *     s = string;
   
+    // Remove extra spaces from string, in place.
     while ( *s != 0 ) {
       if ( *s == ' ' && s[1] == ' ' ) {
         s++;
@@ -67,11 +70,25 @@ namespace FreeDV {
       s++;
     }
   
-    const std::size_t length = strlen(string);
-  
+    // Remove trailing space.
+    length = strlen(string);
     if ( length > 1 && string[length - 1] == ' ' )
       string[length - 1] = '\0';
   
+    // If a segment of a string ending with a space or tab is repeated
+    // immediately afterward, as with the Manufacturer field and the
+    // Product field containing the same initial string, remove the
+    // initial part. This gets rid of repeated manufacturer names.
+    for ( unsigned int i = 1; i < length; i++ ) {
+      if ( string[i] == ' ' || string[i] == '\t' && string[i+1] != '\0' ) {
+        if ( strncmp(string, &string[i + 1], i + 1) == 0 ) {
+          memmove(string, &string[i + 1], length - i);
+          length = (length - i) - 1;
+          i = 0;
+        }
+      }
+    }
+
     return string;
   }
   
index 864ac16c8a2c0ee3492b796b220522e6e01a5e43..9c1ce91756e2f6d3ef854847b366e2f7fa4904a0 100644 (file)
@@ -127,6 +127,9 @@ namespace FreeDV {
   
       for ( std::size_t i = 0; i < count; i++ ) {
         const input_event * const event = &events[i];
+        if ( event->type == EV_KEY ) {
+          std::cerr << event->code << std::endl;
+        }
         if ( event->type == EV_KEY && event->code == button_index ) {
           switch ( event->value ) {
           case 0:
index 5d94066a81fb44e9cbe0d4710c7c2d14ab54d845..7a029e0c6512b3459c860bb844779900568571de 100644 (file)
@@ -41,10 +41,19 @@ namespace FreeDV {
 
     bool               add_poll_device(IODevice * device);
     NORETURN void      do_throw(int error, const char * message);
-    void               receive();
     void               reset();
+
+    bool               drain_digital();
+    bool               drain_ssb();
+    void               key();
+    void               receive();
+    void               start_receive();
+    void               start_transmit_digital();
+    void               start_transmit_ssb();
+    void               stop_receive();
     void               transmit_digital();
     void               transmit_ssb();
+    void               un_key();
   public:
     /// Construct the context for the main loop of FreeDV.
     /// \param interfaces the address of an Interfaces instance containing
@@ -78,14 +87,17 @@ namespace FreeDV {
      &poll_fds[poll_fd_count],
      space - poll_fd_count);
 
-    if ( result > 0 )
+    if ( result > 0 ) {
       poll_fd_count += result;
+      return true;
+    }
     else if ( result < 0 ) {
       std::ostringstream       str;
 
       device->print(str);
       do_throw(result, str.str().c_str());
     }
+    return false;
   }
 
   NORETURN void
@@ -112,11 +124,46 @@ namespace FreeDV {
     out_fifo.reset();
   }
 
+  bool
+  Run::drain_digital()
+  {
+    static bool        done = false;
+    if ( !done ) {
+      done = true;
+      return false;
+    }
+    else {
+      done = false;
+      return true;
+    }
+  }
+
+  bool
+  Run::drain_ssb()
+  {
+    static bool        done = false;
+    if ( !done ) {
+      done = true;
+      return false;
+    }
+    else {
+      done = false;
+      return true;
+    }
+  }
+
+  void
+  Run::key()
+  {
+  }
+
   // FIX: Parallelize the modem and codec into their own threads. Make the
   // FIFO do locking.
   void
   Run::receive()
   {
+    return;
+
     // Fill any data that the receiver can provide.
     const std::size_t  in_samples = min(
                         i->receiver->ready(),
@@ -220,6 +267,20 @@ namespace FreeDV {
   void
   Run::run()
   {
+    enum TRState {
+      DrainDigital,
+      DrainSSB,
+      Receive,
+      StartReceive,
+      TransmitDigital,
+      TransmitSSB,
+      UnKey
+    };
+
+    TRState    state = StartReceive;
+    bool       ptt_digital = false;
+    bool       ptt_ssb = false;
+
     add_poll_device(i->ptt_input_digital);
     add_poll_device(i->ptt_input_ssb);
 
@@ -228,22 +289,107 @@ namespace FreeDV {
         poll_fds[j].revents = 0;
         poll_fds[j].events = POLLIN;
       }
-
       
       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;
+      if ( i->ptt_input_digital->ready() )
+        ptt_digital = i->ptt_input_digital->state();
+      if ( i->ptt_input_ssb->ready() )
+        ptt_ssb = i->ptt_input_ssb->state();
+
+      switch ( state ) {
+      case DrainDigital:
+        if ( drain_digital() )
+          state = UnKey;
+        break;
+      case DrainSSB:
+        if ( drain_ssb() )
+          state = UnKey;
+        break;
+      case Receive:
+      case StartReceive:
+        if ( ptt_digital || ptt_ssb ) {
+          if ( state == Receive )
+            stop_receive();
+
+          key();
+          if ( ptt_digital ) {
+            state = TransmitDigital;
+            start_transmit_digital();
+         }
+          else {
+            state = TransmitSSB;
+            start_transmit_ssb();
+          }
+        }
+        else {
+          switch ( state ) {
+          case StartReceive:
+            start_receive();
+            state = Receive;
+            break;
+          case Receive:
+            receive();
+            break;
+          default:
+            throw std::runtime_error("Bad case in switch.");
+          }
+        }
+        break;
+      case TransmitDigital:
+        if ( ptt_digital == false )
+          state = DrainDigital;
+        else
+          transmit_digital();
+        break;
+      case TransmitSSB:
+        if ( ptt_ssb == false )
+          state = DrainSSB;
+        else
+          transmit_ssb();
+        break;
+      case UnKey:
+        if ( ptt_digital || ptt_ssb ) {
+          if ( ptt_digital ) {
+            state = TransmitDigital;
+            start_transmit_digital();
+         }
+          else {
+            state = TransmitSSB;
+            start_transmit_ssb();
+          }
+        }
+        else {
+          un_key();
+          state = StartReceive;
+        }
       }
     }
   }
 
+  void 
+  Run::start_receive()
+  {
+  }
+
+  void
+  Run::start_transmit_digital()
+  {
+  }
+
+  void
+  Run::start_transmit_ssb()
+  {
+  }
+
+  void
+  Run::stop_receive()
+  {
+  }
+
   void
   Run::transmit_digital()
   {
@@ -254,6 +400,11 @@ namespace FreeDV {
   {
   }
 
+  void
+  Run::un_key()
+  {
+  }
+
   int
   run(Interfaces * i)
   {