diff --git a/protocol_prototype/DryBox/UI/gsm_settings_dialog.py b/protocol_prototype/DryBox/UI/gsm_settings_dialog.py new file mode 100644 index 0000000..ec1b589 --- /dev/null +++ b/protocol_prototype/DryBox/UI/gsm_settings_dialog.py @@ -0,0 +1,275 @@ +from PyQt5.QtWidgets import ( + QDialog, QVBoxLayout, QHBoxLayout, QLabel, QSlider, QSpinBox, + QPushButton, QGroupBox, QGridLayout, QComboBox, QCheckBox, + QDialogButtonBox +) +from PyQt5.QtCore import Qt, pyqtSignal +from PyQt5.QtGui import QFont + +class GSMSettingsDialog(QDialog): + settings_changed = pyqtSignal(dict) + + def __init__(self, parent=None): + super().__init__(parent) + self.setWindowTitle("GSM Simulation Settings") + self.setModal(True) + self.setMinimumWidth(500) + + # Default settings + self.settings = { + 'signal_strength': -70, # dBm + 'signal_quality': 75, # percentage + 'noise_level': 10, # percentage + 'codec_mode': 'AMR-NB', + 'bitrate': 12.2, # kbps + 'packet_loss': 0, # percentage + 'jitter': 20, # ms + 'latency': 100, # ms + 'fading_enabled': False, + 'fading_speed': 'slow', + 'interference_enabled': False, + 'handover_enabled': False + } + + self.init_ui() + + def init_ui(self): + layout = QVBoxLayout() + + # Title + title = QLabel("GSM Network Simulation Parameters") + title.setFont(QFont("Arial", 14, QFont.Bold)) + title.setAlignment(Qt.AlignCenter) + layout.addWidget(title) + + # Signal Quality Group + signal_group = QGroupBox("Signal Quality") + signal_layout = QGridLayout() + + # Signal Strength + signal_layout.addWidget(QLabel("Signal Strength (dBm):"), 0, 0) + self.signal_strength_slider = QSlider(Qt.Horizontal) + self.signal_strength_slider.setRange(-120, -40) + self.signal_strength_slider.setValue(self.settings['signal_strength']) + self.signal_strength_slider.setTickPosition(QSlider.TicksBelow) + self.signal_strength_slider.setTickInterval(10) + signal_layout.addWidget(self.signal_strength_slider, 0, 1) + + self.signal_strength_label = QLabel(f"{self.settings['signal_strength']} dBm") + signal_layout.addWidget(self.signal_strength_label, 0, 2) + + # Signal Quality + signal_layout.addWidget(QLabel("Signal Quality (%):"), 1, 0) + self.signal_quality_slider = QSlider(Qt.Horizontal) + self.signal_quality_slider.setRange(0, 100) + self.signal_quality_slider.setValue(self.settings['signal_quality']) + self.signal_quality_slider.setTickPosition(QSlider.TicksBelow) + self.signal_quality_slider.setTickInterval(10) + signal_layout.addWidget(self.signal_quality_slider, 1, 1) + + self.signal_quality_label = QLabel(f"{self.settings['signal_quality']}%") + signal_layout.addWidget(self.signal_quality_label, 1, 2) + + # Noise Level + signal_layout.addWidget(QLabel("Noise Level (%):"), 2, 0) + self.noise_slider = QSlider(Qt.Horizontal) + self.noise_slider.setRange(0, 50) + self.noise_slider.setValue(self.settings['noise_level']) + self.noise_slider.setTickPosition(QSlider.TicksBelow) + self.noise_slider.setTickInterval(5) + signal_layout.addWidget(self.noise_slider, 2, 1) + + self.noise_label = QLabel(f"{self.settings['noise_level']}%") + signal_layout.addWidget(self.noise_label, 2, 2) + + signal_group.setLayout(signal_layout) + layout.addWidget(signal_group) + + # Codec Settings Group + codec_group = QGroupBox("Voice Codec Settings") + codec_layout = QGridLayout() + + # Codec Type + codec_layout.addWidget(QLabel("Codec Type:"), 0, 0) + self.codec_combo = QComboBox() + self.codec_combo.addItems(['AMR-NB', 'AMR-WB', 'EVS', 'GSM-FR', 'GSM-EFR']) + self.codec_combo.setCurrentText(self.settings['codec_mode']) + codec_layout.addWidget(self.codec_combo, 0, 1) + + # Bitrate + codec_layout.addWidget(QLabel("Bitrate (kbps):"), 1, 0) + self.bitrate_spin = QSpinBox() + self.bitrate_spin.setRange(4, 24) + self.bitrate_spin.setSingleStep(1) + self.bitrate_spin.setValue(int(self.settings['bitrate'])) + self.bitrate_spin.setSuffix(" kbps") + codec_layout.addWidget(self.bitrate_spin, 1, 1) + + codec_group.setLayout(codec_layout) + layout.addWidget(codec_group) + + # Network Conditions Group + network_group = QGroupBox("Network Conditions") + network_layout = QGridLayout() + + # Packet Loss + network_layout.addWidget(QLabel("Packet Loss (%):"), 0, 0) + self.packet_loss_spin = QSpinBox() + self.packet_loss_spin.setRange(0, 20) + self.packet_loss_spin.setValue(self.settings['packet_loss']) + self.packet_loss_spin.setSuffix("%") + network_layout.addWidget(self.packet_loss_spin, 0, 1) + + # Jitter + network_layout.addWidget(QLabel("Jitter (ms):"), 1, 0) + self.jitter_spin = QSpinBox() + self.jitter_spin.setRange(0, 200) + self.jitter_spin.setValue(self.settings['jitter']) + self.jitter_spin.setSuffix(" ms") + network_layout.addWidget(self.jitter_spin, 1, 1) + + # Latency + network_layout.addWidget(QLabel("Latency (ms):"), 2, 0) + self.latency_spin = QSpinBox() + self.latency_spin.setRange(20, 500) + self.latency_spin.setValue(self.settings['latency']) + self.latency_spin.setSuffix(" ms") + network_layout.addWidget(self.latency_spin, 2, 1) + + network_group.setLayout(network_layout) + layout.addWidget(network_group) + + # Advanced Features Group + advanced_group = QGroupBox("Advanced Features") + advanced_layout = QGridLayout() + + # Fading + self.fading_check = QCheckBox("Enable Fading") + self.fading_check.setChecked(self.settings['fading_enabled']) + advanced_layout.addWidget(self.fading_check, 0, 0) + + self.fading_combo = QComboBox() + self.fading_combo.addItems(['slow', 'medium', 'fast']) + self.fading_combo.setCurrentText(self.settings['fading_speed']) + self.fading_combo.setEnabled(self.settings['fading_enabled']) + advanced_layout.addWidget(self.fading_combo, 0, 1) + + # Interference + self.interference_check = QCheckBox("Enable Interference") + self.interference_check.setChecked(self.settings['interference_enabled']) + advanced_layout.addWidget(self.interference_check, 1, 0) + + # Handover + self.handover_check = QCheckBox("Enable Handover Simulation") + self.handover_check.setChecked(self.settings['handover_enabled']) + advanced_layout.addWidget(self.handover_check, 2, 0) + + advanced_group.setLayout(advanced_layout) + layout.addWidget(advanced_group) + + # Preset buttons + preset_layout = QHBoxLayout() + preset_layout.addWidget(QLabel("Presets:")) + + excellent_btn = QPushButton("Excellent") + excellent_btn.clicked.connect(self.set_excellent_preset) + preset_layout.addWidget(excellent_btn) + + good_btn = QPushButton("Good") + good_btn.clicked.connect(self.set_good_preset) + preset_layout.addWidget(good_btn) + + fair_btn = QPushButton("Fair") + fair_btn.clicked.connect(self.set_fair_preset) + preset_layout.addWidget(fair_btn) + + poor_btn = QPushButton("Poor") + poor_btn.clicked.connect(self.set_poor_preset) + preset_layout.addWidget(poor_btn) + + layout.addLayout(preset_layout) + + # Dialog buttons + buttons = QDialogButtonBox( + QDialogButtonBox.Ok | QDialogButtonBox.Cancel, + Qt.Horizontal, self + ) + buttons.accepted.connect(self.accept) + buttons.rejected.connect(self.reject) + layout.addWidget(buttons) + + self.setLayout(layout) + + # Connect signals + self.signal_strength_slider.valueChanged.connect( + lambda v: self.signal_strength_label.setText(f"{v} dBm") + ) + self.signal_quality_slider.valueChanged.connect( + lambda v: self.signal_quality_label.setText(f"{v}%") + ) + self.noise_slider.valueChanged.connect( + lambda v: self.noise_label.setText(f"{v}%") + ) + self.fading_check.toggled.connect(self.fading_combo.setEnabled) + + def get_settings(self): + """Get current settings""" + self.settings['signal_strength'] = self.signal_strength_slider.value() + self.settings['signal_quality'] = self.signal_quality_slider.value() + self.settings['noise_level'] = self.noise_slider.value() + self.settings['codec_mode'] = self.codec_combo.currentText() + self.settings['bitrate'] = self.bitrate_spin.value() + self.settings['packet_loss'] = self.packet_loss_spin.value() + self.settings['jitter'] = self.jitter_spin.value() + self.settings['latency'] = self.latency_spin.value() + self.settings['fading_enabled'] = self.fading_check.isChecked() + self.settings['fading_speed'] = self.fading_combo.currentText() + self.settings['interference_enabled'] = self.interference_check.isChecked() + self.settings['handover_enabled'] = self.handover_check.isChecked() + return self.settings + + def set_excellent_preset(self): + """Set excellent signal conditions""" + self.signal_strength_slider.setValue(-50) + self.signal_quality_slider.setValue(95) + self.noise_slider.setValue(5) + self.packet_loss_spin.setValue(0) + self.jitter_spin.setValue(10) + self.latency_spin.setValue(50) + self.fading_check.setChecked(False) + self.interference_check.setChecked(False) + + def set_good_preset(self): + """Set good signal conditions""" + self.signal_strength_slider.setValue(-70) + self.signal_quality_slider.setValue(75) + self.noise_slider.setValue(10) + self.packet_loss_spin.setValue(1) + self.jitter_spin.setValue(20) + self.latency_spin.setValue(100) + self.fading_check.setChecked(False) + self.interference_check.setChecked(False) + + def set_fair_preset(self): + """Set fair signal conditions""" + self.signal_strength_slider.setValue(-85) + self.signal_quality_slider.setValue(50) + self.noise_slider.setValue(20) + self.packet_loss_spin.setValue(3) + self.jitter_spin.setValue(50) + self.latency_spin.setValue(150) + self.fading_check.setChecked(True) + self.fading_combo.setCurrentText('medium') + self.interference_check.setChecked(False) + + def set_poor_preset(self): + """Set poor signal conditions""" + self.signal_strength_slider.setValue(-100) + self.signal_quality_slider.setValue(25) + self.noise_slider.setValue(35) + self.packet_loss_spin.setValue(8) + self.jitter_spin.setValue(100) + self.latency_spin.setValue(300) + self.fading_check.setChecked(True) + self.fading_combo.setCurrentText('fast') + self.interference_check.setChecked(True) \ No newline at end of file