Vyacheslav V 2 дней назад
Родитель
Сommit
c00a312457
2 измененных файлов с 122 добавлено и 7 удалено
  1. 113 2
      sdr-tcp/client-gui.py
  2. 9 5
      sdr-tcp/server-simulator.py

+ 113 - 2
sdr-tcp/client-gui.py

@@ -35,7 +35,7 @@ class SDRClient(QMainWindow):
             'channel_adc_ttl': np.array([]),
             'channel_rf_ttl': np.array([])
         }
-
+        self.wavetypes = ["default"]
         # Настройка окна
         self.setWindowTitle("SDR Client")
         self.setGeometry(100, 100, 1280, 720)
@@ -87,6 +87,7 @@ class SDRClient(QMainWindow):
         self.connect_button.clicked.connect(self.connect_to_server)
         self.disconnect_button.clicked.connect(self.disconnect_from_server)
         self.add_event_button.clicked.connect(self.add_event_dialog)
+        self.add_rfwave_button.clicked.connect(self.add_wavetype_dialog)
 
     def connect_to_server(self):
         try:
@@ -118,7 +119,7 @@ class SDRClient(QMainWindow):
         for label in labels:
             if label == "Waveform Type":
                 combo = QComboBox()
-                combo.addItems(["sine", "square", "triangle"])
+                combo.addItems(self.wavetypes)
                 layout.addRow(QLabel(label), combo)
                 self.event_inputs[label] = combo
             else:
@@ -199,6 +200,116 @@ class SDRClient(QMainWindow):
                 print(f"Failed to load event list: {e}")
                 QMessageBox.critical(self, "Error", f"Failed to load event list: {e}")
 
+    def add_wavetype_dialog(self):
+        add_wave_dialog = QDialog(self)
+        add_wave_dialog.setWindowTitle("Add Waveform Type")
+        layout = QFormLayout()
+
+        name_input = QLineEdit()
+        layout.addRow(QLabel("Waveform Name"), name_input)
+
+        self.file_input = QLineEdit()
+        file_dialog_button = QPushButton("Browse")
+        file_dialog_button.clicked.connect(lambda: self.open_wave_file_dialog(self.file_input))
+        layout.addRow(QLabel("Waveform File"), self.file_input)
+        layout.addWidget(file_dialog_button)
+
+        submit_button = QPushButton("Submit")
+        layout.addWidget(submit_button)
+
+        submit_button.clicked.connect(lambda: self.submit_wavetype(name_input.text(), self.file_input.text(), add_wave_dialog))
+
+        add_wave_dialog.setLayout(layout)
+        add_wave_dialog.exec()
+
+    def open_wave_file_dialog(self, file_input):
+        file_dialog = QFileDialog(self)
+        file_dialog.setNameFilter("All Files (*);;Binary Files (*.bin)")
+        if file_dialog.exec():
+            selected_file = file_dialog.selectedFiles()[0]
+            file_input.setText(selected_file)
+
+    def submit_wavetype(self, name, file_path, dialog):
+        if not name:
+            QMessageBox.warning(self, "Input Error", "Please enter a waveform name")
+            return
+        if name in self.wavetypes:
+            QMessageBox.warning(self, "Input Error", "Waveform name already exists")
+            return
+        header_msg = {
+            "magic": 0xAA,
+            "cmd": 0x20,
+            "wavetype": name,
+            "total_length": 0,  # Placeholder, will be updated after loading the waveform data
+            "total_packets": 0,  # Placeholder, will be updated after loading the waveform data
+        }
+
+        with open(file_path, 'rb') as f:
+            # Load rows point from .bin file (first 2 bytes is Q-point, next 2 bytes is I-point)
+            total_wavedata_q = np.fromfile(f, dtype=np.int16, count=-1, offset=0)
+            total_wavedata_i = np.fromfile(f, dtype=np.int16, count=-1, offset=2)
+        if len(total_wavedata_q) != len(total_wavedata_i):
+            QMessageBox.warning(self, "Input Error", "In-phase and quadrature wave data must have the same length")
+            return
+        
+        packet_length = 512  # Define packet length for sending waveform data
+        header_msg["total_length"] = len(total_wavedata_q)
+        header_msg["total_packets"] = len(total_wavedata_q) // packet_length + (1 if len(total_wavedata_q) % packet_length > 0 else 0)
+
+        try:
+            packed_header = msgpack.packb(header_msg, use_bin_type=True)
+            self.sock.sendall(packed_header)
+            
+            raw_resp = self.sock.recv(1024)
+            if not raw_resp:
+                raise Exception("No response from server")
+            resp = msgpack.unpackb(raw_resp, raw=False)
+            if resp["cmd"] != 0xFE or resp["code"] != 0x00000001:
+                raise Exception(f"Server error: {resp['message']}")
+        except Exception as e:
+            print(f"Failed to send waveform header: {e}")
+            QMessageBox.critical(self, "Error", f"Failed to send waveform header: {e}")
+            return
+        
+        try:
+            for i in range(header_msg["total_packets"]):
+                packet_length = min(512, len(total_wavedata_q) - i * 512)
+                start_idx = i * 512
+                end_idx = min((i + 1) * 512, len(total_wavedata_q))
+
+                packet_data = {
+                    "magic": 0xAA,
+                    "cmd": 0x2C,
+                    "packet_index": i,
+                    "packet_length": packet_length,
+                    "wavedata_q": total_wavedata_q[start_idx:end_idx],
+                    "wavedata_i": total_wavedata_i[start_idx:end_idx]
+                }
+                packed_packet = msgpack.packb(packet_data, use_bin_type=True)
+                self.sock.sendall(packed_packet)
+                raw_resp = self.sock.recv(1024)
+                if not raw_resp:
+                    raise Exception("No response from server")
+                resp = msgpack.unpackb(raw_resp, raw=False)
+                if resp["cmd"] != 0xFE or resp["code"] != 0x00000002:
+                    raise Exception(f"Server error: {resp['message']}")
+                self.sock.sendall(b"ACK") # Send ACK to server to indicate ready for next packet
+            raw_resp = self.sock.recv(1024)
+            if not raw_resp:
+                raise Exception("No response from server after sending all packets")
+            resp = msgpack.unpackb(raw_resp, raw=False)
+            if resp["cmd"] != 0xFE or resp["code"] != 0x00000003:
+                raise Exception(f"Server error after sending all packets: {resp['message']}")
+        except Exception as e:
+            print(f"Failed to send waveform data: {e}")
+            QMessageBox.critical(self, "Error", f"Failed to send waveform data: {e}")
+            return
+
+        self.wavetypes.append(name)
+        print(f"Added new waveform type: {name}")
+        QMessageBox.information(self, "Success", f"Added new waveform type: {name}")
+        dialog.close()
+
 app = QApplication([])
 client = SDRClient()
 client.show()

+ 9 - 5
sdr-tcp/server-simulator.py

@@ -180,13 +180,11 @@ class ServerSimulator:
         wavetype = data["wavetype"]
         total_length = data["total_length"]
         total_packets = data["total_packets"]
-        packet_index = data["packet_index"]
-        packet_length = data["packet_length"]
 
         total_wave_q = np.array([], dtype=np.int16)
         total_wave_i = np.array([], dtype=np.int16)
 
-        self.conn.sendall(self.getStatusMsg(0x00000001, f"Ready to receive RF wave data packet {packet_index+1}/{total_packets} with length {packet_length}"))
+        self.conn.sendall(self.getStatusMsg(0x00000001, f"Ready to receive RF wave data packets"))
 
         for i in range(total_packets):
             rawdata = self.sock.recv(4096)
@@ -211,8 +209,8 @@ class ServerSimulator:
                 self.conn.sendall(self.getErrorMsg(self.errCode, "Missing wave data in RF wave packet"))
                 return False
             
-            wave_q = np.frombuffer(packet_data["wavedata_q"], dtype=np.int16)
-            wave_i = np.frombuffer(packet_data["wavedata_i"], dtype=np.int16)
+            wave_q = packet_data["wavedata_q"]
+            wave_i = packet_data["wavedata_i"]
 
             if len(wave_q) != len(wave_i):
                 print("In-phase and quadrature wave data must have the same length in RF wave packet")
@@ -223,12 +221,18 @@ class ServerSimulator:
             total_wave_i = np.concatenate([total_wave_i, wave_i])
 
             print(f"Received RF wave packet {i+1}/{total_packets} with length {len(wave_q)}")
+            self.conn.sendall(self.getStatusMsg(0x00000002, f"Received RF wave packet {i+1}/{total_packets} with length {len(wave_q)}"))
+            self.conn.recv(1024) # Wait for ACK before receiving next packet
+            return True
+
         if len(total_wave_q) != total_length or len(total_wave_i) != total_length:
             print("Total wave data length does not match expected length")
             self.errCode = 0x00000011 # Total length mismatch
             self.conn.sendall(self.getErrorMsg(self.errCode, "Total wave data length does not match expected length"))
             return False
         self.rfwaves.append({data["wavetype"]: (total_wave_q, total_wave_i)})
+        print(f"RF wave '{wavetype}' received successfully with total length {total_length}")
+        self.conn.sendall(self.getStatusMsg(0x00000003, f"RF wave '{wavetype}' received successfully with total length {total_length}"))
         return True
     
     def runEventList(self, data):