remoteRF-server 1.0.7__tar.gz → 1.0.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/PKG-INFO +1 -1
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/pyproject.toml +1 -1
- {remoterf_server-1.0.7/src/remoteRF_server/drivers/adalm_pluto → remoterf_server-1.0.8/src/remoteRF_server/common/idl}/pluto_schema.py +128 -5
- {remoterf_server-1.0.7/src/remoteRF_server/common/idl → remoterf_server-1.0.8/src/remoteRF_server/drivers/adalm_pluto}/pluto_schema.py +128 -5
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/usrp_schema.py +45 -3
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/PKG-INFO +1 -1
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_idl_schema.py +47 -2
- remoterf_server-1.0.8/tests/test_pluto_compat.py +221 -0
- remoterf_server-1.0.7/tests/test_pluto_compat.py +0 -99
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/README.md +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/setup.cfg +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/grpc_host_pb2.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/grpc_host_pb2_grpc.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/grpc_pb2.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/v2_codec.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/device_schema.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/pluto_mimo_schema.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/schema.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/v2.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/ansi_codes.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/api_token.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/db_connection.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/db_location.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/list_string.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/process_arg.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/adalm_pluto/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/adalm_pluto/pluto_mimo_schema.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/adalm_pluto/pluto_remote_server.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/policy.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/uhd_manifest.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/host/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/host/host_auth_token.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/host/host_directory_store.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/host/host_tunnel_server.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/acc_perms.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/cert_provider.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/device_manager.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/dynamic_v2.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/grpc_server.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/reservation.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/rpc_manager.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/user_group_cli.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/user_group_handler.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/v2_errors.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/serverrf_cli.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/tools/__init__.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/tools/gen_certs.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/tools/gist_status.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/tools/gist_status_testing.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/tools/introspect_uhd.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/SOURCES.txt +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/dependency_links.txt +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/entry_points.txt +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/requires.txt +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/top_level.txt +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_cert_provider.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_default_usrp_schema.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_dynamic_v2.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_process_arg.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_reservation_timestamps.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_rpc_manager_calln.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_usrp_client_server_hardware.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_usrp_client_server_localhost.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_usrp_remoterf_rx_hardware.py +0 -0
- {remoterf_server-1.0.7 → remoterf_server-1.0.8}/tests/test_usrp_uhd410_hardware.py +0 -0
|
@@ -8,6 +8,26 @@ import subprocess
|
|
|
8
8
|
import re
|
|
9
9
|
import adi
|
|
10
10
|
|
|
11
|
+
|
|
12
|
+
def _normalize_channels(value):
|
|
13
|
+
"""Restore channel lists after numeric lists cross the legacy RPC codec."""
|
|
14
|
+
if hasattr(value, "tolist"):
|
|
15
|
+
value = value.tolist()
|
|
16
|
+
if isinstance(value, tuple):
|
|
17
|
+
value = list(value)
|
|
18
|
+
if not isinstance(value, list):
|
|
19
|
+
return value
|
|
20
|
+
|
|
21
|
+
channels = []
|
|
22
|
+
for channel in value:
|
|
23
|
+
if not isinstance(channel, str):
|
|
24
|
+
integer = int(channel)
|
|
25
|
+
if channel == integer:
|
|
26
|
+
channel = integer
|
|
27
|
+
channels.append(channel)
|
|
28
|
+
return channels
|
|
29
|
+
|
|
30
|
+
|
|
11
31
|
# == PLUTO Connection Logic ==
|
|
12
32
|
|
|
13
33
|
def connect_pluto(*, serial: str):
|
|
@@ -50,7 +70,7 @@ class PlutoSchema(DeviceSchema):
|
|
|
50
70
|
|
|
51
71
|
device_type = "adalm_pluto"
|
|
52
72
|
client_class = "Pluto"
|
|
53
|
-
driver_version = "0.0.
|
|
73
|
+
driver_version = "0.0.2"
|
|
54
74
|
|
|
55
75
|
@staticmethod
|
|
56
76
|
def make_device(**kwargs):
|
|
@@ -85,13 +105,13 @@ class PlutoSchema(DeviceSchema):
|
|
|
85
105
|
|
|
86
106
|
@idl_expose(kind="get")
|
|
87
107
|
def get_rx_hardwaregain_chan0(self):
|
|
88
|
-
"""RX hardware gain (dB). pyadi-iio attribute:
|
|
89
|
-
return self.device.
|
|
108
|
+
"""RX hardware gain (dB). pyadi-iio attribute: rx_hardwaregain_chan0"""
|
|
109
|
+
return self.device.rx_hardwaregain_chan0
|
|
90
110
|
|
|
91
111
|
@idl_expose(kind="set")
|
|
92
112
|
def set_rx_hardwaregain_chan0(self, value):
|
|
93
|
-
"""RX hardware gain (dB). pyadi-iio attribute:
|
|
94
|
-
self.device.
|
|
113
|
+
"""RX hardware gain (dB). pyadi-iio attribute: rx_hardwaregain_chan0"""
|
|
114
|
+
self.device.rx_hardwaregain_chan0 = value
|
|
95
115
|
|
|
96
116
|
@idl_expose(kind="get")
|
|
97
117
|
def get_tx_hardwaregain_chan0(self):
|
|
@@ -180,6 +200,109 @@ class PlutoSchema(DeviceSchema):
|
|
|
180
200
|
"""Disable the internal DDS tone generator."""
|
|
181
201
|
self.device.disable_dds()
|
|
182
202
|
|
|
203
|
+
# region DDS
|
|
204
|
+
|
|
205
|
+
@idl_expose(kind="call")
|
|
206
|
+
def call_dds_single_tone(self, frequency, scale, channel=0):
|
|
207
|
+
"""Generate one complex DDS tone on the selected TX channel."""
|
|
208
|
+
self.device.dds_single_tone(frequency, scale, channel)
|
|
209
|
+
|
|
210
|
+
@idl_expose(kind="call")
|
|
211
|
+
def call_dds_dual_tone(
|
|
212
|
+
self,
|
|
213
|
+
frequency1,
|
|
214
|
+
scale1,
|
|
215
|
+
frequency2,
|
|
216
|
+
scale2,
|
|
217
|
+
channel=0,
|
|
218
|
+
):
|
|
219
|
+
"""Generate two complex DDS tones on the selected TX channel."""
|
|
220
|
+
self.device.dds_dual_tone(
|
|
221
|
+
frequency1,
|
|
222
|
+
scale1,
|
|
223
|
+
frequency2,
|
|
224
|
+
scale2,
|
|
225
|
+
channel,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
@idl_expose(kind="get")
|
|
229
|
+
def get_dds_frequencies(self):
|
|
230
|
+
return self.device.dds_frequencies
|
|
231
|
+
|
|
232
|
+
@idl_expose(kind="set")
|
|
233
|
+
def set_dds_frequencies(self, value):
|
|
234
|
+
self.device.dds_frequencies = value
|
|
235
|
+
|
|
236
|
+
@idl_expose(kind="get")
|
|
237
|
+
def get_dds_scales(self):
|
|
238
|
+
return self.device.dds_scales
|
|
239
|
+
|
|
240
|
+
@idl_expose(kind="set")
|
|
241
|
+
def set_dds_scales(self, value):
|
|
242
|
+
self.device.dds_scales = value
|
|
243
|
+
|
|
244
|
+
@idl_expose(kind="get")
|
|
245
|
+
def get_dds_phases(self):
|
|
246
|
+
return self.device.dds_phases
|
|
247
|
+
|
|
248
|
+
@idl_expose(kind="set")
|
|
249
|
+
def set_dds_phases(self, value):
|
|
250
|
+
self.device.dds_phases = value
|
|
251
|
+
|
|
252
|
+
@idl_expose(kind="get")
|
|
253
|
+
def get_dds_enabled(self):
|
|
254
|
+
return self.device.dds_enabled
|
|
255
|
+
|
|
256
|
+
@idl_expose(kind="set")
|
|
257
|
+
def set_dds_enabled(self, value):
|
|
258
|
+
self.device.dds_enabled = value
|
|
259
|
+
|
|
260
|
+
# endregion
|
|
261
|
+
|
|
262
|
+
# region channel configuration
|
|
263
|
+
|
|
264
|
+
@idl_expose(kind="get")
|
|
265
|
+
def get_rx_enabled_channels(self):
|
|
266
|
+
return self.device.rx_enabled_channels
|
|
267
|
+
|
|
268
|
+
@idl_expose(kind="set")
|
|
269
|
+
def set_rx_enabled_channels(self, value):
|
|
270
|
+
self.device.rx_enabled_channels = _normalize_channels(value)
|
|
271
|
+
|
|
272
|
+
@idl_expose(kind="get")
|
|
273
|
+
def get_tx_enabled_channels(self):
|
|
274
|
+
return self.device.tx_enabled_channels
|
|
275
|
+
|
|
276
|
+
@idl_expose(kind="set")
|
|
277
|
+
def set_tx_enabled_channels(self, value):
|
|
278
|
+
self.device.tx_enabled_channels = _normalize_channels(value)
|
|
279
|
+
|
|
280
|
+
@idl_expose(kind="get")
|
|
281
|
+
def get_rx_annotated(self):
|
|
282
|
+
return self.device.rx_annotated
|
|
283
|
+
|
|
284
|
+
@idl_expose(kind="set")
|
|
285
|
+
def set_rx_annotated(self, value):
|
|
286
|
+
self.device.rx_annotated = value
|
|
287
|
+
|
|
288
|
+
@idl_expose(kind="get")
|
|
289
|
+
def get_rx_output_type(self):
|
|
290
|
+
return self.device.rx_output_type
|
|
291
|
+
|
|
292
|
+
@idl_expose(kind="set")
|
|
293
|
+
def set_rx_output_type(self, value):
|
|
294
|
+
self.device.rx_output_type = value
|
|
295
|
+
|
|
296
|
+
@idl_expose(kind="get")
|
|
297
|
+
def get_rx_channel_names(self):
|
|
298
|
+
return self.device.rx_channel_names
|
|
299
|
+
|
|
300
|
+
@idl_expose(kind="get")
|
|
301
|
+
def get_tx_channel_names(self):
|
|
302
|
+
return self.device.tx_channel_names
|
|
303
|
+
|
|
304
|
+
# endregion
|
|
305
|
+
|
|
183
306
|
# endregion
|
|
184
307
|
|
|
185
308
|
# region ip / repr
|
|
@@ -8,6 +8,26 @@ import subprocess
|
|
|
8
8
|
import re
|
|
9
9
|
import adi
|
|
10
10
|
|
|
11
|
+
|
|
12
|
+
def _normalize_channels(value):
|
|
13
|
+
"""Restore channel lists after numeric lists cross the legacy RPC codec."""
|
|
14
|
+
if hasattr(value, "tolist"):
|
|
15
|
+
value = value.tolist()
|
|
16
|
+
if isinstance(value, tuple):
|
|
17
|
+
value = list(value)
|
|
18
|
+
if not isinstance(value, list):
|
|
19
|
+
return value
|
|
20
|
+
|
|
21
|
+
channels = []
|
|
22
|
+
for channel in value:
|
|
23
|
+
if not isinstance(channel, str):
|
|
24
|
+
integer = int(channel)
|
|
25
|
+
if channel == integer:
|
|
26
|
+
channel = integer
|
|
27
|
+
channels.append(channel)
|
|
28
|
+
return channels
|
|
29
|
+
|
|
30
|
+
|
|
11
31
|
# == PLUTO Connection Logic ==
|
|
12
32
|
|
|
13
33
|
def connect_pluto(*, serial: str):
|
|
@@ -50,7 +70,7 @@ class PlutoSchema(DeviceSchema):
|
|
|
50
70
|
|
|
51
71
|
device_type = "adalm_pluto"
|
|
52
72
|
client_class = "Pluto"
|
|
53
|
-
driver_version = "0.0.
|
|
73
|
+
driver_version = "0.0.2"
|
|
54
74
|
|
|
55
75
|
@staticmethod
|
|
56
76
|
def make_device(**kwargs):
|
|
@@ -85,13 +105,13 @@ class PlutoSchema(DeviceSchema):
|
|
|
85
105
|
|
|
86
106
|
@idl_expose(kind="get")
|
|
87
107
|
def get_rx_hardwaregain_chan0(self):
|
|
88
|
-
"""RX hardware gain (dB). pyadi-iio attribute:
|
|
89
|
-
return self.device.
|
|
108
|
+
"""RX hardware gain (dB). pyadi-iio attribute: rx_hardwaregain_chan0"""
|
|
109
|
+
return self.device.rx_hardwaregain_chan0
|
|
90
110
|
|
|
91
111
|
@idl_expose(kind="set")
|
|
92
112
|
def set_rx_hardwaregain_chan0(self, value):
|
|
93
|
-
"""RX hardware gain (dB). pyadi-iio attribute:
|
|
94
|
-
self.device.
|
|
113
|
+
"""RX hardware gain (dB). pyadi-iio attribute: rx_hardwaregain_chan0"""
|
|
114
|
+
self.device.rx_hardwaregain_chan0 = value
|
|
95
115
|
|
|
96
116
|
@idl_expose(kind="get")
|
|
97
117
|
def get_tx_hardwaregain_chan0(self):
|
|
@@ -180,6 +200,109 @@ class PlutoSchema(DeviceSchema):
|
|
|
180
200
|
"""Disable the internal DDS tone generator."""
|
|
181
201
|
self.device.disable_dds()
|
|
182
202
|
|
|
203
|
+
# region DDS
|
|
204
|
+
|
|
205
|
+
@idl_expose(kind="call")
|
|
206
|
+
def call_dds_single_tone(self, frequency, scale, channel=0):
|
|
207
|
+
"""Generate one complex DDS tone on the selected TX channel."""
|
|
208
|
+
self.device.dds_single_tone(frequency, scale, channel)
|
|
209
|
+
|
|
210
|
+
@idl_expose(kind="call")
|
|
211
|
+
def call_dds_dual_tone(
|
|
212
|
+
self,
|
|
213
|
+
frequency1,
|
|
214
|
+
scale1,
|
|
215
|
+
frequency2,
|
|
216
|
+
scale2,
|
|
217
|
+
channel=0,
|
|
218
|
+
):
|
|
219
|
+
"""Generate two complex DDS tones on the selected TX channel."""
|
|
220
|
+
self.device.dds_dual_tone(
|
|
221
|
+
frequency1,
|
|
222
|
+
scale1,
|
|
223
|
+
frequency2,
|
|
224
|
+
scale2,
|
|
225
|
+
channel,
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
@idl_expose(kind="get")
|
|
229
|
+
def get_dds_frequencies(self):
|
|
230
|
+
return self.device.dds_frequencies
|
|
231
|
+
|
|
232
|
+
@idl_expose(kind="set")
|
|
233
|
+
def set_dds_frequencies(self, value):
|
|
234
|
+
self.device.dds_frequencies = value
|
|
235
|
+
|
|
236
|
+
@idl_expose(kind="get")
|
|
237
|
+
def get_dds_scales(self):
|
|
238
|
+
return self.device.dds_scales
|
|
239
|
+
|
|
240
|
+
@idl_expose(kind="set")
|
|
241
|
+
def set_dds_scales(self, value):
|
|
242
|
+
self.device.dds_scales = value
|
|
243
|
+
|
|
244
|
+
@idl_expose(kind="get")
|
|
245
|
+
def get_dds_phases(self):
|
|
246
|
+
return self.device.dds_phases
|
|
247
|
+
|
|
248
|
+
@idl_expose(kind="set")
|
|
249
|
+
def set_dds_phases(self, value):
|
|
250
|
+
self.device.dds_phases = value
|
|
251
|
+
|
|
252
|
+
@idl_expose(kind="get")
|
|
253
|
+
def get_dds_enabled(self):
|
|
254
|
+
return self.device.dds_enabled
|
|
255
|
+
|
|
256
|
+
@idl_expose(kind="set")
|
|
257
|
+
def set_dds_enabled(self, value):
|
|
258
|
+
self.device.dds_enabled = value
|
|
259
|
+
|
|
260
|
+
# endregion
|
|
261
|
+
|
|
262
|
+
# region channel configuration
|
|
263
|
+
|
|
264
|
+
@idl_expose(kind="get")
|
|
265
|
+
def get_rx_enabled_channels(self):
|
|
266
|
+
return self.device.rx_enabled_channels
|
|
267
|
+
|
|
268
|
+
@idl_expose(kind="set")
|
|
269
|
+
def set_rx_enabled_channels(self, value):
|
|
270
|
+
self.device.rx_enabled_channels = _normalize_channels(value)
|
|
271
|
+
|
|
272
|
+
@idl_expose(kind="get")
|
|
273
|
+
def get_tx_enabled_channels(self):
|
|
274
|
+
return self.device.tx_enabled_channels
|
|
275
|
+
|
|
276
|
+
@idl_expose(kind="set")
|
|
277
|
+
def set_tx_enabled_channels(self, value):
|
|
278
|
+
self.device.tx_enabled_channels = _normalize_channels(value)
|
|
279
|
+
|
|
280
|
+
@idl_expose(kind="get")
|
|
281
|
+
def get_rx_annotated(self):
|
|
282
|
+
return self.device.rx_annotated
|
|
283
|
+
|
|
284
|
+
@idl_expose(kind="set")
|
|
285
|
+
def set_rx_annotated(self, value):
|
|
286
|
+
self.device.rx_annotated = value
|
|
287
|
+
|
|
288
|
+
@idl_expose(kind="get")
|
|
289
|
+
def get_rx_output_type(self):
|
|
290
|
+
return self.device.rx_output_type
|
|
291
|
+
|
|
292
|
+
@idl_expose(kind="set")
|
|
293
|
+
def set_rx_output_type(self, value):
|
|
294
|
+
self.device.rx_output_type = value
|
|
295
|
+
|
|
296
|
+
@idl_expose(kind="get")
|
|
297
|
+
def get_rx_channel_names(self):
|
|
298
|
+
return self.device.rx_channel_names
|
|
299
|
+
|
|
300
|
+
@idl_expose(kind="get")
|
|
301
|
+
def get_tx_channel_names(self):
|
|
302
|
+
return self.device.tx_channel_names
|
|
303
|
+
|
|
304
|
+
# endregion
|
|
305
|
+
|
|
183
306
|
# endregion
|
|
184
307
|
|
|
185
308
|
# region ip / repr
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/usrp_schema.py
RENAMED
|
@@ -98,6 +98,31 @@ def _payload_type(value):
|
|
|
98
98
|
return None
|
|
99
99
|
|
|
100
100
|
|
|
101
|
+
def _tune_request_policy(value, current):
|
|
102
|
+
"""Translate a portable policy name back to UHD's native enum value."""
|
|
103
|
+
if not isinstance(value, str):
|
|
104
|
+
return value
|
|
105
|
+
name = value.rsplit(".", 1)[-1].upper()
|
|
106
|
+
policy_types = (
|
|
107
|
+
type(current),
|
|
108
|
+
getattr(getattr(uhd, "types", None), "TuneRequestPolicy", None),
|
|
109
|
+
getattr(getattr(uhd, "types", None), "tune_request_policy", None),
|
|
110
|
+
getattr(
|
|
111
|
+
getattr(getattr(uhd, "libpyuhd", None), "types", None),
|
|
112
|
+
"tune_request_policy",
|
|
113
|
+
None,
|
|
114
|
+
),
|
|
115
|
+
)
|
|
116
|
+
for policy_type in policy_types:
|
|
117
|
+
if policy_type is None:
|
|
118
|
+
continue
|
|
119
|
+
for candidate in (name, name.lower(), f"POLICY_{name}"):
|
|
120
|
+
native = getattr(policy_type, candidate, None)
|
|
121
|
+
if native is not None:
|
|
122
|
+
return native
|
|
123
|
+
return value
|
|
124
|
+
|
|
125
|
+
|
|
101
126
|
def _require_dict(value, method):
|
|
102
127
|
if not isinstance(value, dict):
|
|
103
128
|
raise TypeError(
|
|
@@ -159,7 +184,16 @@ def _construct(value):
|
|
|
159
184
|
return uhd.usrp.SubdevSpec(value["spec"])
|
|
160
185
|
|
|
161
186
|
if kind == "TuneRequest":
|
|
162
|
-
|
|
187
|
+
# Older generated clients used ``args`` for constructor arguments.
|
|
188
|
+
# Current TuneRequest snapshots use that same key for UHD's DeviceAddr
|
|
189
|
+
# field, so only sequences may be interpreted as constructor arguments.
|
|
190
|
+
raw_args = value.get("args", ())
|
|
191
|
+
legacy_constructor_args = isinstance(raw_args, (list, tuple))
|
|
192
|
+
args = (
|
|
193
|
+
[_construct(item) for item in raw_args]
|
|
194
|
+
if legacy_constructor_args
|
|
195
|
+
else []
|
|
196
|
+
)
|
|
163
197
|
kwargs = {
|
|
164
198
|
key: _construct(item)
|
|
165
199
|
for key, item in value.get("kwargs", {}).items()
|
|
@@ -174,10 +208,18 @@ def _construct(value):
|
|
|
174
208
|
obj = constructor(*args, **kwargs)
|
|
175
209
|
for field in (
|
|
176
210
|
"rf_freq", "dsp_freq", "rf_freq_policy", "dsp_freq_policy",
|
|
177
|
-
"
|
|
211
|
+
"args",
|
|
178
212
|
):
|
|
213
|
+
if field == "args" and legacy_constructor_args:
|
|
214
|
+
continue
|
|
179
215
|
if field in value and hasattr(obj, field):
|
|
180
|
-
|
|
216
|
+
converted = _construct(value[field])
|
|
217
|
+
if field in {"rf_freq_policy", "dsp_freq_policy"}:
|
|
218
|
+
converted = _tune_request_policy(
|
|
219
|
+
converted,
|
|
220
|
+
getattr(obj, field),
|
|
221
|
+
)
|
|
222
|
+
setattr(obj, field, converted)
|
|
181
223
|
return obj
|
|
182
224
|
|
|
183
225
|
if kind == "DeviceAddr":
|
|
@@ -319,6 +319,25 @@ class DeviceSchemaTests(unittest.TestCase):
|
|
|
319
319
|
def __init__(self, spec):
|
|
320
320
|
self.spec = spec
|
|
321
321
|
|
|
322
|
+
class DeviceAddr:
|
|
323
|
+
def __init__(self, value=""):
|
|
324
|
+
self.value = value
|
|
325
|
+
|
|
326
|
+
class TuneRequestPolicy:
|
|
327
|
+
AUTO = object()
|
|
328
|
+
MANUAL = object()
|
|
329
|
+
NONE = object()
|
|
330
|
+
|
|
331
|
+
class TuneRequest:
|
|
332
|
+
def __init__(self, target_freq=0.0, lo_offset=None):
|
|
333
|
+
self.target_freq = float(target_freq)
|
|
334
|
+
self.lo_offset = lo_offset
|
|
335
|
+
self.rf_freq = 0.0
|
|
336
|
+
self.dsp_freq = 0.0
|
|
337
|
+
self.rf_freq_policy = TuneRequestPolicy.AUTO
|
|
338
|
+
self.dsp_freq_policy = TuneRequestPolicy.AUTO
|
|
339
|
+
self.args = DeviceAddr()
|
|
340
|
+
|
|
322
341
|
class TXMetadata:
|
|
323
342
|
def __init__(self):
|
|
324
343
|
self.has_time_spec = False
|
|
@@ -334,6 +353,9 @@ class DeviceSchemaTests(unittest.TestCase):
|
|
|
334
353
|
|
|
335
354
|
fake_uhd.types = types.SimpleNamespace(
|
|
336
355
|
TimeSpec=TimeSpec,
|
|
356
|
+
DeviceAddr=DeviceAddr,
|
|
357
|
+
TuneRequest=TuneRequest,
|
|
358
|
+
TuneRequestPolicy=TuneRequestPolicy,
|
|
337
359
|
TXMetadata=TXMetadata,
|
|
338
360
|
StreamCMD=StreamCMD,
|
|
339
361
|
StreamMode=types.SimpleNamespace(
|
|
@@ -403,9 +425,32 @@ class DeviceSchemaTests(unittest.TestCase):
|
|
|
403
425
|
tune = usrp_schema._construct({
|
|
404
426
|
"__uhd_type__": "TuneRequest",
|
|
405
427
|
"args": [915e6],
|
|
406
|
-
"kwargs": {
|
|
428
|
+
"kwargs": {},
|
|
429
|
+
})
|
|
430
|
+
self.assertIsInstance(tune, TuneRequest)
|
|
431
|
+
self.assertEqual(tune.target_freq, 915e6)
|
|
432
|
+
|
|
433
|
+
tune = usrp_schema._construct({
|
|
434
|
+
"__uhd_type__": "TuneRequest",
|
|
435
|
+
"target_freq": 100e6,
|
|
436
|
+
"lo_offset": None,
|
|
437
|
+
"rf_freq": 99e6,
|
|
438
|
+
"dsp_freq": 1e6,
|
|
439
|
+
"rf_freq_policy": "MANUAL",
|
|
440
|
+
"dsp_freq_policy": "AUTO",
|
|
441
|
+
"args": {
|
|
442
|
+
"__uhd_type__": "DeviceAddr",
|
|
443
|
+
"items": {"mode_n": "integer"},
|
|
444
|
+
},
|
|
407
445
|
})
|
|
408
|
-
self.
|
|
446
|
+
self.assertIsInstance(tune, TuneRequest)
|
|
447
|
+
self.assertEqual(tune.target_freq, 100e6)
|
|
448
|
+
self.assertEqual(tune.rf_freq, 99e6)
|
|
449
|
+
self.assertEqual(tune.dsp_freq, 1e6)
|
|
450
|
+
self.assertIs(tune.rf_freq_policy, TuneRequestPolicy.MANUAL)
|
|
451
|
+
self.assertIs(tune.dsp_freq_policy, TuneRequestPolicy.AUTO)
|
|
452
|
+
self.assertIsInstance(tune.args, DeviceAddr)
|
|
453
|
+
self.assertEqual(tune.args.value, "mode_n=integer")
|
|
409
454
|
|
|
410
455
|
subdev = usrp_schema._construct({"__uhd_type__": "SubdevSpec", "spec": "A:0"})
|
|
411
456
|
self.assertIsInstance(subdev, SubdevSpec)
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import types
|
|
5
|
+
import unittest
|
|
6
|
+
from unittest.mock import patch
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
sys.modules.setdefault("adi", types.ModuleType("adi"))
|
|
11
|
+
|
|
12
|
+
from remoteRF_server.common.idl.pluto_schema import PlutoSchema
|
|
13
|
+
from remoteRF_server.common.utils import map_arg, unmap_arg
|
|
14
|
+
from remoteRF_server.drivers.adalm_pluto.pluto_remote_server import PlutoServer
|
|
15
|
+
from remoteRF_server.server import device_manager
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FakePluto:
|
|
19
|
+
def __init__(self):
|
|
20
|
+
self.sample_rate = 1_000_000
|
|
21
|
+
self.rx_hardwaregain_chan0 = 12.5
|
|
22
|
+
self.dds_frequencies = [100_000, 100_000]
|
|
23
|
+
self.dds_scales = [0.25, 0.25]
|
|
24
|
+
self.dds_phases = [0, 90_000]
|
|
25
|
+
self.dds_enabled = [True, True]
|
|
26
|
+
self.rx_enabled_channels = [0]
|
|
27
|
+
self.tx_enabled_channels = [0]
|
|
28
|
+
self.rx_annotated = False
|
|
29
|
+
self.rx_output_type = "raw"
|
|
30
|
+
self.rx_channel_names = ["voltage0", "voltage1"]
|
|
31
|
+
self.tx_channel_names = ["voltage0", "voltage1"]
|
|
32
|
+
self.single_tone_args = None
|
|
33
|
+
self.dual_tone_args = None
|
|
34
|
+
self.tx_samples = None
|
|
35
|
+
self.rx_samples = np.array([1 + 2j, 3 + 4j], dtype=np.complex64)
|
|
36
|
+
|
|
37
|
+
def rx(self):
|
|
38
|
+
return self.rx_samples
|
|
39
|
+
|
|
40
|
+
def tx(self, samples):
|
|
41
|
+
self.tx_samples = samples
|
|
42
|
+
|
|
43
|
+
def dds_single_tone(self, frequency, scale, channel=0):
|
|
44
|
+
self.single_tone_args = (frequency, scale, channel)
|
|
45
|
+
|
|
46
|
+
def dds_dual_tone(
|
|
47
|
+
self,
|
|
48
|
+
frequency1,
|
|
49
|
+
scale1,
|
|
50
|
+
frequency2,
|
|
51
|
+
scale2,
|
|
52
|
+
channel=0,
|
|
53
|
+
):
|
|
54
|
+
self.dual_tone_args = (
|
|
55
|
+
frequency1,
|
|
56
|
+
scale1,
|
|
57
|
+
frequency2,
|
|
58
|
+
scale2,
|
|
59
|
+
channel,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class PlutoCompatTests(unittest.TestCase):
|
|
64
|
+
def setUp(self) -> None:
|
|
65
|
+
self.device = FakePluto()
|
|
66
|
+
|
|
67
|
+
def handle(self, function_name: str, args: dict):
|
|
68
|
+
with patch(
|
|
69
|
+
"remoteRF_server.drivers.adalm_pluto.pluto_remote_server.device_pluto",
|
|
70
|
+
return_value=self.device,
|
|
71
|
+
):
|
|
72
|
+
return PlutoServer.handle_call(function_name=function_name, args=args)
|
|
73
|
+
|
|
74
|
+
def test_get_and_set_still_use_legacy_token_paths(self) -> None:
|
|
75
|
+
response = self.handle("Pluto:sample_rate:GET", {"a": map_arg("token")})
|
|
76
|
+
self.assertEqual(unmap_arg(response["sample_rate"]), 1_000_000)
|
|
77
|
+
|
|
78
|
+
response = self.handle(
|
|
79
|
+
"Pluto:sample_rate:SET",
|
|
80
|
+
{"a": map_arg("token"), "sample_rate": map_arg(2_000_000)},
|
|
81
|
+
)
|
|
82
|
+
self.assertEqual(response, {})
|
|
83
|
+
self.assertEqual(self.device.sample_rate, 2_000_000)
|
|
84
|
+
|
|
85
|
+
def test_call0_and_call1_still_use_existing_wire_shape(self) -> None:
|
|
86
|
+
response = self.handle("Pluto:rx:CALL0", {"a": map_arg("token")})
|
|
87
|
+
np.testing.assert_allclose(unmap_arg(response["rx"]), self.device.rx_samples)
|
|
88
|
+
|
|
89
|
+
samples = np.array([5 + 6j, 7 + 8j], dtype=np.complex64)
|
|
90
|
+
response = self.handle(
|
|
91
|
+
"Pluto:tx:CALL1",
|
|
92
|
+
{"a": map_arg("token"), "arg1": map_arg(samples)},
|
|
93
|
+
)
|
|
94
|
+
self.assertEqual(unmap_arg(response["tx"]), "None")
|
|
95
|
+
np.testing.assert_allclose(self.device.tx_samples, samples)
|
|
96
|
+
|
|
97
|
+
def test_schema_dispatch_preserves_pluto_get_set_call0_and_call1(self) -> None:
|
|
98
|
+
schema = PlutoSchema()
|
|
99
|
+
schema.bind(self.device)
|
|
100
|
+
|
|
101
|
+
idl = schema.get_idl()
|
|
102
|
+
self.assertEqual(idl["calls"]["call_rx"]["args"], [])
|
|
103
|
+
self.assertEqual(idl["calls"]["call_tx"]["args"][0]["name"], "value")
|
|
104
|
+
self.assertTrue(idl["calls"]["call_tx"]["args"][0]["required"])
|
|
105
|
+
|
|
106
|
+
self.assertEqual(schema.dispatch("get_sample_rate", {}), 1_000_000)
|
|
107
|
+
schema.dispatch("set_sample_rate", {"value": 2_000_000})
|
|
108
|
+
self.assertEqual(self.device.sample_rate, 2_000_000)
|
|
109
|
+
|
|
110
|
+
np.testing.assert_allclose(schema.dispatch("call_rx", {}), self.device.rx_samples)
|
|
111
|
+
samples = np.array([9 + 1j, 10 + 2j], dtype=np.complex64)
|
|
112
|
+
self.assertIsNone(schema.dispatch("call_tx", {"value": samples}))
|
|
113
|
+
np.testing.assert_allclose(self.device.tx_samples, samples)
|
|
114
|
+
|
|
115
|
+
def test_schema_rx_hardware_gain_uses_pyadi_property_name(self) -> None:
|
|
116
|
+
schema = PlutoSchema()
|
|
117
|
+
schema.bind(self.device)
|
|
118
|
+
|
|
119
|
+
self.assertEqual(schema.dispatch("get_rx_hardwaregain_chan0", {}), 12.5)
|
|
120
|
+
schema.dispatch("set_rx_hardwaregain_chan0", {"value": 24.0})
|
|
121
|
+
self.assertEqual(self.device.rx_hardwaregain_chan0, 24.0)
|
|
122
|
+
|
|
123
|
+
def test_schema_exposes_dds_generation_and_controls(self) -> None:
|
|
124
|
+
schema = PlutoSchema()
|
|
125
|
+
schema.bind(self.device)
|
|
126
|
+
|
|
127
|
+
idl = schema.get_idl()
|
|
128
|
+
single_args = idl["calls"]["call_dds_single_tone"]["args"]
|
|
129
|
+
dual_args = idl["calls"]["call_dds_dual_tone"]["args"]
|
|
130
|
+
self.assertEqual(
|
|
131
|
+
[arg["name"] for arg in single_args],
|
|
132
|
+
["frequency", "scale", "channel"],
|
|
133
|
+
)
|
|
134
|
+
self.assertEqual(single_args[-1]["default"], 0)
|
|
135
|
+
self.assertEqual(
|
|
136
|
+
[arg["name"] for arg in dual_args],
|
|
137
|
+
["frequency1", "scale1", "frequency2", "scale2", "channel"],
|
|
138
|
+
)
|
|
139
|
+
self.assertEqual(dual_args[-1]["default"], 0)
|
|
140
|
+
|
|
141
|
+
schema.dispatch(
|
|
142
|
+
"call_dds_single_tone",
|
|
143
|
+
{"frequency": 125_000, "scale": 0.5},
|
|
144
|
+
)
|
|
145
|
+
self.assertEqual(self.device.single_tone_args, (125_000, 0.5, 0))
|
|
146
|
+
schema.dispatch(
|
|
147
|
+
"call_dds_dual_tone",
|
|
148
|
+
{
|
|
149
|
+
"frequency1": 100_000,
|
|
150
|
+
"scale1": 0.25,
|
|
151
|
+
"frequency2": -200_000,
|
|
152
|
+
"scale2": 0.4,
|
|
153
|
+
"channel": 1,
|
|
154
|
+
},
|
|
155
|
+
)
|
|
156
|
+
self.assertEqual(
|
|
157
|
+
self.device.dual_tone_args,
|
|
158
|
+
(100_000, 0.25, -200_000, 0.4, 1),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
controls = {
|
|
162
|
+
"dds_frequencies": [200_000, 200_000],
|
|
163
|
+
"dds_scales": [0.5, 0.5],
|
|
164
|
+
"dds_phases": [90_000, 0],
|
|
165
|
+
"dds_enabled": [False, True],
|
|
166
|
+
}
|
|
167
|
+
for name, value in controls.items():
|
|
168
|
+
schema.dispatch(f"set_{name}", {"value": value})
|
|
169
|
+
self.assertEqual(schema.dispatch(f"get_{name}", {}), value)
|
|
170
|
+
|
|
171
|
+
def test_schema_exposes_channel_selection_and_receive_formatting(self) -> None:
|
|
172
|
+
schema = PlutoSchema()
|
|
173
|
+
schema.bind(self.device)
|
|
174
|
+
|
|
175
|
+
# Numeric lists use ndarray transport in the legacy codec. The schema
|
|
176
|
+
# restores the integer list shape required by pyadi-iio.
|
|
177
|
+
encoded_channels = unmap_arg(map_arg([0]))
|
|
178
|
+
schema.dispatch("set_rx_enabled_channels", {"value": encoded_channels})
|
|
179
|
+
self.assertEqual(self.device.rx_enabled_channels, [0])
|
|
180
|
+
self.assertIs(type(self.device.rx_enabled_channels[0]), int)
|
|
181
|
+
|
|
182
|
+
schema.dispatch("set_tx_enabled_channels", {"value": ["voltage0"]})
|
|
183
|
+
self.assertEqual(self.device.tx_enabled_channels, ["voltage0"])
|
|
184
|
+
schema.dispatch("set_rx_annotated", {"value": True})
|
|
185
|
+
schema.dispatch("set_rx_output_type", {"value": "SI"})
|
|
186
|
+
self.assertTrue(schema.dispatch("get_rx_annotated", {}))
|
|
187
|
+
self.assertEqual(schema.dispatch("get_rx_output_type", {}), "SI")
|
|
188
|
+
|
|
189
|
+
def test_schema_exposes_channel_metadata_as_read_only(self) -> None:
|
|
190
|
+
schema = PlutoSchema()
|
|
191
|
+
schema.bind(self.device)
|
|
192
|
+
|
|
193
|
+
idl = schema.get_idl()
|
|
194
|
+
self.assertEqual(
|
|
195
|
+
schema.dispatch("get_rx_channel_names", {}),
|
|
196
|
+
["voltage0", "voltage1"],
|
|
197
|
+
)
|
|
198
|
+
self.assertEqual(
|
|
199
|
+
schema.dispatch("get_tx_channel_names", {}),
|
|
200
|
+
["voltage0", "voltage1"],
|
|
201
|
+
)
|
|
202
|
+
self.assertNotIn("set_rx_channel_names", idl["setters"])
|
|
203
|
+
self.assertNotIn("set_tx_channel_names", idl["setters"])
|
|
204
|
+
|
|
205
|
+
def test_legacy_pluto_inventory_type_resolves_to_packaged_schema(self) -> None:
|
|
206
|
+
with patch.object(PlutoSchema, "make_device", return_value=self.device):
|
|
207
|
+
schema, ident, dtype = device_manager._connect_from_record(
|
|
208
|
+
{
|
|
209
|
+
"TYPE": "pluto",
|
|
210
|
+
"IDENT": "104473f6",
|
|
211
|
+
"INIT": {"serial": "104473f6"},
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
self.assertIsInstance(schema, PlutoSchema)
|
|
216
|
+
self.assertEqual(ident, "104473f6")
|
|
217
|
+
self.assertEqual(dtype, "adalm_pluto")
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
if __name__ == "__main__":
|
|
221
|
+
unittest.main()
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import sys
|
|
4
|
-
import types
|
|
5
|
-
import unittest
|
|
6
|
-
from unittest.mock import patch
|
|
7
|
-
|
|
8
|
-
import numpy as np
|
|
9
|
-
|
|
10
|
-
sys.modules.setdefault("adi", types.ModuleType("adi"))
|
|
11
|
-
|
|
12
|
-
from remoteRF_server.common.idl.pluto_schema import PlutoSchema
|
|
13
|
-
from remoteRF_server.common.utils import map_arg, unmap_arg
|
|
14
|
-
from remoteRF_server.drivers.adalm_pluto.pluto_remote_server import PlutoServer
|
|
15
|
-
from remoteRF_server.server import device_manager
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class FakePluto:
|
|
19
|
-
def __init__(self):
|
|
20
|
-
self.sample_rate = 1_000_000
|
|
21
|
-
self.tx_samples = None
|
|
22
|
-
self.rx_samples = np.array([1 + 2j, 3 + 4j], dtype=np.complex64)
|
|
23
|
-
|
|
24
|
-
def rx(self):
|
|
25
|
-
return self.rx_samples
|
|
26
|
-
|
|
27
|
-
def tx(self, samples):
|
|
28
|
-
self.tx_samples = samples
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class PlutoCompatTests(unittest.TestCase):
|
|
32
|
-
def setUp(self) -> None:
|
|
33
|
-
self.device = FakePluto()
|
|
34
|
-
|
|
35
|
-
def handle(self, function_name: str, args: dict):
|
|
36
|
-
with patch(
|
|
37
|
-
"remoteRF_server.drivers.adalm_pluto.pluto_remote_server.device_pluto",
|
|
38
|
-
return_value=self.device,
|
|
39
|
-
):
|
|
40
|
-
return PlutoServer.handle_call(function_name=function_name, args=args)
|
|
41
|
-
|
|
42
|
-
def test_get_and_set_still_use_legacy_token_paths(self) -> None:
|
|
43
|
-
response = self.handle("Pluto:sample_rate:GET", {"a": map_arg("token")})
|
|
44
|
-
self.assertEqual(unmap_arg(response["sample_rate"]), 1_000_000)
|
|
45
|
-
|
|
46
|
-
response = self.handle(
|
|
47
|
-
"Pluto:sample_rate:SET",
|
|
48
|
-
{"a": map_arg("token"), "sample_rate": map_arg(2_000_000)},
|
|
49
|
-
)
|
|
50
|
-
self.assertEqual(response, {})
|
|
51
|
-
self.assertEqual(self.device.sample_rate, 2_000_000)
|
|
52
|
-
|
|
53
|
-
def test_call0_and_call1_still_use_existing_wire_shape(self) -> None:
|
|
54
|
-
response = self.handle("Pluto:rx:CALL0", {"a": map_arg("token")})
|
|
55
|
-
np.testing.assert_allclose(unmap_arg(response["rx"]), self.device.rx_samples)
|
|
56
|
-
|
|
57
|
-
samples = np.array([5 + 6j, 7 + 8j], dtype=np.complex64)
|
|
58
|
-
response = self.handle(
|
|
59
|
-
"Pluto:tx:CALL1",
|
|
60
|
-
{"a": map_arg("token"), "arg1": map_arg(samples)},
|
|
61
|
-
)
|
|
62
|
-
self.assertEqual(unmap_arg(response["tx"]), "None")
|
|
63
|
-
np.testing.assert_allclose(self.device.tx_samples, samples)
|
|
64
|
-
|
|
65
|
-
def test_schema_dispatch_preserves_pluto_get_set_call0_and_call1(self) -> None:
|
|
66
|
-
schema = PlutoSchema()
|
|
67
|
-
schema.bind(self.device)
|
|
68
|
-
|
|
69
|
-
idl = schema.get_idl()
|
|
70
|
-
self.assertEqual(idl["calls"]["call_rx"]["args"], [])
|
|
71
|
-
self.assertEqual(idl["calls"]["call_tx"]["args"][0]["name"], "value")
|
|
72
|
-
self.assertTrue(idl["calls"]["call_tx"]["args"][0]["required"])
|
|
73
|
-
|
|
74
|
-
self.assertEqual(schema.dispatch("get_sample_rate", {}), 1_000_000)
|
|
75
|
-
schema.dispatch("set_sample_rate", {"value": 2_000_000})
|
|
76
|
-
self.assertEqual(self.device.sample_rate, 2_000_000)
|
|
77
|
-
|
|
78
|
-
np.testing.assert_allclose(schema.dispatch("call_rx", {}), self.device.rx_samples)
|
|
79
|
-
samples = np.array([9 + 1j, 10 + 2j], dtype=np.complex64)
|
|
80
|
-
self.assertIsNone(schema.dispatch("call_tx", {"value": samples}))
|
|
81
|
-
np.testing.assert_allclose(self.device.tx_samples, samples)
|
|
82
|
-
|
|
83
|
-
def test_legacy_pluto_inventory_type_resolves_to_packaged_schema(self) -> None:
|
|
84
|
-
with patch.object(PlutoSchema, "make_device", return_value=self.device):
|
|
85
|
-
schema, ident, dtype = device_manager._connect_from_record(
|
|
86
|
-
{
|
|
87
|
-
"TYPE": "pluto",
|
|
88
|
-
"IDENT": "104473f6",
|
|
89
|
-
"INIT": {"serial": "104473f6"},
|
|
90
|
-
}
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
self.assertIsInstance(schema, PlutoSchema)
|
|
94
|
-
self.assertEqual(ident, "104473f6")
|
|
95
|
-
self.assertEqual(dtype, "adalm_pluto")
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if __name__ == "__main__":
|
|
99
|
-
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/grpc_host_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/grpc/grpc_pb2_grpc.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/device_schema.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/idl/pluto_mimo_schema.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/__init__.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/ansi_codes.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/api_token.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/db_connection.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/db_location.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/list_string.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/common/utils/process_arg.py
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/adalm_pluto/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/drivers/usrp/uhd_manifest.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/host/host_directory_store.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/host/host_tunnel_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/device_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/user_group_cli.py
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/server/user_group_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server/tools/gist_status_testing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{remoterf_server-1.0.7 → remoterf_server-1.0.8}/src/remoteRF_server.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|