]> git.rkrishnan.org Git - pihpsdr.git/commitdiff
Protect sending of ozy buffers with a MUTEX, since this is needed
authorc vw <dl1ycf@darc.de>
Sun, 16 Jan 2022 11:54:37 +0000 (12:54 +0100)
committerc vw <dl1ycf@darc.de>
Sun, 16 Jan 2022 11:54:37 +0000 (12:54 +0100)
for TCP and USB traffic.

old_protocol.c

index 2e7d22c0c71f04e02bd8aa660bf86c5c679d164d..fb5327decb13d3ff20891bfc6a76a61e37c0bcee 100644 (file)
@@ -139,7 +139,6 @@ static int running;
 static long ep4_sequence;
 
 static uint32_t last_seq_num=-0xffffffff;
-static int suppress_ozy_packet = 0;
 static int tx_fifo_flag = 0;
 
 static int current_rx=0;
@@ -210,6 +209,21 @@ static unsigned char usb_buffer_block = 0;
 
 static GMutex dump_mutex;
 
+//
+// To avoid race conditions, we need a mutex covering the next three functions
+// that are called both by the RX and TX thread, and are filling and sending the
+// output buffer.
+//
+static pthread_mutex_t send_audio_mutex   = PTHREAD_MUTEX_INITIALIZER;
+
+//
+// This mutex "protects" ozy_send_buffer. This is necessary only for
+// TCP and USB-OZY connections.
+//
+static pthread_mutex_t send_ozy_mutex   = PTHREAD_MUTEX_INITIALIZER;
+
+
+
 //
 // Ring buffer for outgoing samples.
 // Samples going to the radio are produces in big chunks.
@@ -268,6 +282,11 @@ void dump_buffer(unsigned char *buffer,int length,const char *who) {
 }
 
 void old_protocol_stop() {
+  //
+  // Mutex is needed since in the TCP case, sending TX IQ packets
+  // must not occur while the "stop" packet is sent.
+  //
+  pthread_mutex_lock(&send_ozy_mutex);
 #ifdef USBOZY
   if(device!=DEVICE_OZY) {
 #endif
@@ -276,15 +295,14 @@ void old_protocol_stop() {
 #ifdef USBOZY
   }
 #endif
+  pthread_mutex_unlock(&send_ozy_mutex);
 }
 
 void old_protocol_run() {
-    //
-    // Several things done in metis_restart are also needed for
-    // USBOZY
-    //
     g_print("%s\n",__FUNCTION__);
+    pthread_mutex_lock(&send_ozy_mutex);
     metis_restart();
+    pthread_mutex_unlock(&send_ozy_mutex);
 }
 
 void old_protocol_set_mic_sample_rate(int rate) {
@@ -294,6 +312,7 @@ void old_protocol_set_mic_sample_rate(int rate) {
 void old_protocol_init(int rx,int pixels,int rate) {
   int i;
   g_print("old_protocol_init: num_hpsdr_receivers=%d\n",how_many_receivers());
+  pthread_mutex_lock(&send_ozy_mutex);
 
   old_protocol_set_mic_sample_rate(rate);
 
@@ -339,6 +358,7 @@ void old_protocol_init(int rx,int pixels,int rate) {
   }
 
   metis_restart();
+  pthread_mutex_unlock(&send_ozy_mutex);
 
 }
 
@@ -533,8 +553,6 @@ static gpointer receive_thread(gpointer arg) {
   g_print( "old_protocol: receive_thread\n");
   running=1;
 
-  //metis_restart();
-
   length=sizeof(addr);
   while(running) {
 
@@ -1195,38 +1213,43 @@ static void process_ozy_input_buffer(unsigned char  *buffer) {
         // ship out two buffers with 2*63 samples
         // the k-loop could be done with 1-2 memcpy
         //
-        for (int j=0; j<2; j++) {
-          unsigned char *p=output_buffer+8;
-          for (int k=0; k<63; k++) {
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            *p++ = TXRINGBUF[txring_outptr++];
-            if (txring_outptr >= TXRINGBUFLEN) txring_outptr=0;
+        if (pthread_mutex_trylock(&send_ozy_mutex)) {
+         //
+         // This can only happen if the GUI thread initiates
+         // a protocol stop/start sequence, as it does e.g.
+         // when changing the number of receivers, changing
+         // the sample rate, en/dis-abling PURESIGNAL or
+         // DIVERSITY, or executing the RESTART button.
+         // In these cases, the TX ring buffer is reset anywas
+         // so we do not have to do anything here.
+         //
+        } else {
+          for (int j=0; j<2; j++) {
+            unsigned char *p=output_buffer+8;
+            for (int k=0; k<63; k++) {
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              *p++ = TXRINGBUF[txring_outptr++];
+              if (txring_outptr >= TXRINGBUFLEN) txring_outptr=0;
+            }
+            ozy_send_buffer();
           }
-          ozy_send_buffer();
-        }
-        micsamplecount=0;
+          micsamplecount=0;
+         pthread_mutex_unlock(&send_ozy_mutex);
+       }
       }
     }
   }
 }
 
-//
-// To avoid race conditions, we need a mutex covering the next three functions
-// that are called both by the RX and TX thread, and are filling and sending the
-// output buffer.
-//
-
-static pthread_mutex_t send_buffer_mutex   = PTHREAD_MUTEX_INITIALIZER;
-
 void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right_audio_sample) {
   if(!isTransmitting()) {
-    pthread_mutex_lock(&send_buffer_mutex);
+    pthread_mutex_lock(&send_audio_mutex);
     if (txring_flag) {
       //
       // First time we arrive here after a TX->RX transition:
@@ -1259,7 +1282,7 @@ void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right
     TXRINGBUF[txring_inptr++]=0;
     TXRINGBUF[txring_inptr++]=0;
     if (txring_inptr >= TXRINGBUFLEN) txring_inptr=0;
-    pthread_mutex_unlock(&send_buffer_mutex);
+    pthread_mutex_unlock(&send_audio_mutex);
   }
 }
 
@@ -1272,7 +1295,7 @@ void old_protocol_audio_samples(RECEIVER *rx,short left_audio_sample,short right
 //
 void old_protocol_iq_samples_with_sidetone(int isample, int qsample, int side) {
   if(isTransmitting()) {
-    pthread_mutex_lock(&send_buffer_mutex);
+    pthread_mutex_lock(&send_audio_mutex);
     if (!txring_flag) {
       //
       // First time we arrive here after a RX->TX transition:
@@ -1298,13 +1321,13 @@ void old_protocol_iq_samples_with_sidetone(int isample, int qsample, int side) {
     TXRINGBUF[txring_inptr++]=qsample >> 8;
     TXRINGBUF[txring_inptr++]=qsample;
     if (txring_inptr >= TXRINGBUFLEN) txring_inptr=0;
-    pthread_mutex_unlock(&send_buffer_mutex);
+    pthread_mutex_unlock(&send_audio_mutex);
   }
 }
 
 void old_protocol_iq_samples(int isample,int qsample) {
   if(isTransmitting()) {
-    pthread_mutex_lock(&send_buffer_mutex);
+    pthread_mutex_lock(&send_audio_mutex);
     if (!txring_flag) {
       //
       // First time we arrive here after a RX->TX transition:
@@ -1323,7 +1346,7 @@ void old_protocol_iq_samples(int isample,int qsample) {
     TXRINGBUF[txring_inptr++]=qsample >> 8;
     TXRINGBUF[txring_inptr++]=qsample;
     if (txring_inptr >= TXRINGBUFLEN) txring_inptr=0;
-    pthread_mutex_unlock(&send_buffer_mutex);
+    pthread_mutex_unlock(&send_audio_mutex);
   }
 }
 
@@ -2065,17 +2088,6 @@ static void ozyusb_write(unsigned char* buffer,int length)
       break;
   }
 */
-  //
-  // DL1YCF:
-  // Although the METIS offset is not used for OZY, we have to maintain it
-  // since it triggers the "alternating" sending of C0=0 and C0!=0 
-  // C+C packets in ozy_send_buffer().
-  //
-  if (metis_offset == 8) {
-    metis_offset = 520;
-  } else {
-    metis_offset = 8;
-  }
 }
 #endif
 
@@ -2099,19 +2111,9 @@ static int metis_write(unsigned char ep,unsigned char* buffer,int length) {
     metis_buffer[6]=(send_sequence>>8)&0xFF;
     metis_buffer[7]=(send_sequence)&0xFF;
 
-    //
-    // When using UDP, the buffer will ALWAYS be sent. However, when using TCP,
-    // we must be able to suppress sending buffers HERE asynchronously
-    // when we want to sent a METIS start or stop packet. This is so because TCP
-    // is a byte stream, and data from two sources might end up interleaved
-    // In order not to confuse the SDR, we increase the sequence number only
-    // for packets actually sent.
-    //
-    if (!suppress_ozy_packet) {
-      // send the buffer
-      send_sequence++;
-      metis_send_buffer(&metis_buffer[0],1032);
-    }
+    send_sequence++;
+    metis_send_buffer(&metis_buffer[0],1032);
+
     metis_offset=8;
 
   }
@@ -2161,14 +2163,15 @@ static void metis_restart() {
   for (i=0; i<8; i++) {
     ozy_send_buffer();
   }
-
-  usleep(250000);
+  usleep(100000);
 
   // start the data flowing
+  // No mutex here, since metis_restart() is mutex protected
 #ifdef USBOZY
   if(device!=DEVICE_OZY) {
 #endif
     metis_start_stop(1);
+    usleep(100000);
 #ifdef USBOZY
   }
 #endif
@@ -2180,6 +2183,11 @@ static void metis_start_stop(int command) {
   unsigned char buffer[1032];
     
   g_print("%s: %d\n",__FUNCTION__,command);
+  //
+  // Clear TX IQ ring buffer
+  //
+  txring_inptr = 0;
+  txring_outptr = 0;
 #ifdef USBOZY
   if(device!=DEVICE_OZY)
   {
@@ -2202,7 +2210,6 @@ static void metis_start_stop(int command) {
     // Stop the sending of TX/audio packets (1032-byte-length) and wait a while
     // Then, send the start/stop buffer with a length of 1032
     //
-    suppress_ozy_packet=1;
     usleep(100000);
     for(i=4;i<1032;i++) {
       buffer[i]=0x00;
@@ -2213,7 +2220,6 @@ static void metis_start_stop(int command) {
     // This prevents mangling of data from TX/audio and Start/Stop packets.
     //
     usleep(100000);
-    suppress_ozy_packet=0;
   }
   if (command == 0 && tcp_socket >= 0) {
     // We just have sent a METIS stop in TCP