RemoteRF 2.0.4__tar.gz → 2.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.
Files changed (63) hide show
  1. {remoterf-2.0.4/src/remoteRF.egg-info → remoterf-2.0.8}/PKG-INFO +77 -2
  2. {remoterf-2.0.4 → remoterf-2.0.8}/README.md +76 -1
  3. {remoterf-2.0.4 → remoterf-2.0.8}/setup.py +1 -1
  4. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/grpc/grpc_pb2.py +46 -46
  5. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/utils/process_arg.py +102 -62
  6. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/grpc_client.py +12 -0
  7. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/dynamic_v2.py +49 -1
  8. remoterf-2.0.8/src/remoteRF/drivers/hackrf/__init__.py +6 -0
  9. remoterf-2.0.8/src/remoteRF/drivers/hackrf/hackrf_remote.py +216 -0
  10. remoterf-2.0.8/src/remoteRF/drivers/rtl_sdr/__init__.py +6 -0
  11. remoterf-2.0.8/src/remoteRF/drivers/rtl_sdr/rtl_sdr_remote.py +244 -0
  12. remoterf-2.0.8/src/remoteRF/drivers/support/ti_mmwave.py +295 -0
  13. remoterf-2.0.8/src/remoteRF/drivers/support/uhd_dsp.py +76 -0
  14. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/support/uhd_v2.py +17 -1
  15. remoterf-2.0.8/src/remoteRF/drivers/ti_mmwave/__init__.py +15 -0
  16. remoterf-2.0.8/src/remoteRF/drivers/ti_mmwave/ti_mmwave_remote.py +163 -0
  17. remoterf-2.0.8/src/remoteRF/drivers/usrp/usrp_remote.py +8 -0
  18. {remoterf-2.0.4 → remoterf-2.0.8/src/remoterf.egg-info}/PKG-INFO +77 -2
  19. remoterf-2.0.8/src/remoterf.egg-info/SOURCES.txt +94 -0
  20. {remoterf-2.0.4 → remoterf-2.0.8}/tests/test_dynamic_device_codegen.py +65 -0
  21. {remoterf-2.0.4 → remoterf-2.0.8}/tests/test_dynamic_v2.py +105 -1
  22. remoterf-2.0.8/tests/test_process_arg.py +218 -0
  23. remoterf-2.0.8/tests/test_ti_mmwave.py +211 -0
  24. remoterf-2.0.4/LICENSE +0 -21
  25. remoterf-2.0.4/src/remoteRF/drivers/usrp/usrp_remote.py +0 -8
  26. remoterf-2.0.4/src/remoteRF.egg-info/SOURCES.txt +0 -55
  27. remoterf-2.0.4/tests/test_process_arg.py +0 -110
  28. {remoterf-2.0.4 → remoterf-2.0.8}/MANIFEST.in +0 -0
  29. {remoterf-2.0.4 → remoterf-2.0.8}/setup.cfg +0 -0
  30. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/__init__.py +0 -0
  31. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/__init__.py +0 -0
  32. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/grpc/__init__.py +0 -0
  33. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/grpc/grpc_pb2_grpc.py +0 -0
  34. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/grpc/v2_codec.py +0 -0
  35. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/tos_notice.txt +0 -0
  36. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/utils/__init__.py +0 -0
  37. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/utils/ansi_codes.py +0 -0
  38. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/utils/api_token.py +0 -0
  39. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/common/utils/list_string.py +0 -0
  40. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/config/__init__.py +0 -0
  41. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/config/cert_fetcher.py +0 -0
  42. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/config/config.py +0 -0
  43. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/__init__.py +0 -0
  44. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/acc_login.py +0 -0
  45. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/app.py +0 -0
  46. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/banner_note.txt +0 -0
  47. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/dynamic_v2_transport.py +0 -0
  48. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/grpc_acc.py +0 -0
  49. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/core/v2_errors.py +0 -0
  50. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/__init__.py +0 -0
  51. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/adalm_pluto/__init__.py +0 -0
  52. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/adalm_pluto/pluto_remote.py +0 -0
  53. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/dynamic_device.py +0 -0
  54. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/support/__init__.py +0 -0
  55. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/support/uhd.py +0 -0
  56. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/usrp/__init__.py +0 -0
  57. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/drivers/usrp/usrp_remote.pyi +0 -0
  58. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/remoterf_cli.py +0 -0
  59. {remoterf-2.0.4 → remoterf-2.0.8}/src/remoteRF/version.py +0 -0
  60. {remoterf-2.0.4/src/remoteRF.egg-info → remoterf-2.0.8/src/remoterf.egg-info}/dependency_links.txt +0 -0
  61. {remoterf-2.0.4/src/remoteRF.egg-info → remoterf-2.0.8/src/remoterf.egg-info}/entry_points.txt +0 -0
  62. {remoterf-2.0.4/src/remoteRF.egg-info → remoterf-2.0.8/src/remoterf.egg-info}/requires.txt +0 -0
  63. {remoterf-2.0.4/src/remoteRF.egg-info → remoterf-2.0.8/src/remoterf.egg-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: remoterf
3
- Version: 2.0.4
3
+ Version: 2.0.8
4
4
  Summary: A python API to remotely access signal centric hardware. Client-side only! Courtesy of Wireless Lab @ UCLA & Prof. Ian Roberts.
5
5
  Author: Ethan Ge
6
6
  Author-email: ethoGalaxy@gmail.com
@@ -53,7 +53,13 @@ source venv/bin/activate # Activate virtual environment
53
53
  pip install remoterf # Install remoteRF
54
54
  ```
55
55
 
56
- ## NI USRP-2901 / B200-family
56
+ ## NI USRP-2901, Ettus B205-mini, B200-family, and USRP N210
57
+
58
+ The packaged client natively includes the shared USRP schema for the qualified
59
+ NI USRP-2901, Ettus Research USRP B205-mini, the broader USB/B200 family, and
60
+ the Ethernet-connected N210. No custom client driver is required. The B205-mini
61
+ uses the same native-style API and reports its live 1 RX/1 TX channel topology
62
+ through `remoterf_capabilities`.
57
63
 
58
64
  After reserving a server-local `usrp` inventory entry, fetch or refresh its
59
65
  Dynamic v2 package with the reservation token:
@@ -112,6 +118,75 @@ generic native dispatch, but are not release-qualified as exact UHD overload
112
118
  parity until the server's UHD 4.10 target-introspection and hardware
113
119
  differential gates pass.
114
120
 
121
+ ## RTL-SDR
122
+
123
+ RTL-SDR clients are generated from the server's `rtl_sdr` schema. The machine
124
+ running client code does not need `librtlsdr` or PyRtlSdr:
125
+
126
+ ```python
127
+ from remoteRF.drivers import ensure_driver
128
+
129
+ token = "reservation-token"
130
+ ensure_driver(token=token)
131
+
132
+ from remoteRF.drivers.rtl_sdr import RtlSdr
133
+
134
+ sdr = RtlSdr(token)
135
+ sdr.sample_rate = 2_048_000
136
+ sdr.center_freq = 100_000_000
137
+ sdr.gain = "auto"
138
+ sdr.agc_mode = True
139
+
140
+ samples = sdr.read_samples(16_384) # NumPy complex64
141
+ raw_iq = sdr.read_bytes(4096) # packed uint8 I/Q bytes
142
+ ```
143
+
144
+ The server owns the USB handle for its lifetime, so the generated client does
145
+ not close the physical radio. `read_samples` and `read_bytes` are bounded to a
146
+ 4 MiB response. Call them repeatedly for longer captures. Native asynchronous
147
+ callbacks are not transported remotely.
148
+
149
+ When a Tailscale address differs from the IP or DNS identity in the server
150
+ certificate, keep TLS verification enabled and set the expected identity:
151
+
152
+ ```bash
153
+ export REMOTERF_ADDR=rrf2.example.ts.net:61005
154
+ export REMOTERF_TLS_SERVER_NAME=certificate-name.example
155
+ ```
156
+
157
+ ## TI mmWave radar
158
+
159
+ TI radar clients are generated from the server's `ti_mmwave` schema. Only the
160
+ machine physically connected to the radar needs `pyserial` or a CP210x driver.
161
+ The initial parser profile supports xWR68xx mmWave SDK 3 out-of-box TLV output.
162
+
163
+ ```python
164
+ from remoteRF.drivers import ensure_driver
165
+
166
+ token = "reservation-token"
167
+ ensure_driver(token=token)
168
+
169
+ from remoteRF.drivers.ti_mmwave import TiMmWave, decode_frame
170
+
171
+ radar = TiMmWave(token)
172
+ print(radar.device_info)
173
+ print(radar.query_version())
174
+
175
+ radar.apply_config(open("profile.cfg").read(), start=True)
176
+ try:
177
+ packet = radar.read_frame(timeout=1.0)
178
+ frame = decode_frame(packet)
179
+ print(frame.header.frame_number, frame.points, frame.side_info)
180
+ finally:
181
+ radar.stop()
182
+ ```
183
+
184
+ `read_frame()` returns one complete binary UART packet. Decoding is client-local
185
+ and retains unknown TLVs as raw bytes, allowing custom firmware to be captured
186
+ before a dedicated parser profile is added. `stream_stats` reports dropped
187
+ frames, queued frames, resynchronization bytes, invalid headers, and reader
188
+ health. Remote firmware flashing is deliberately unsupported.
189
+
115
190
  If `pip install` doesn't work, you can clone the [source](https://github.com/WirelessLabAtUCLA/RemoteRF-Client) directly from github.
116
191
 
117
192
  <!-- 1. **Clone the repository:**
@@ -27,7 +27,13 @@ source venv/bin/activate # Activate virtual environment
27
27
  pip install remoterf # Install remoteRF
28
28
  ```
29
29
 
30
- ## NI USRP-2901 / B200-family
30
+ ## NI USRP-2901, Ettus B205-mini, B200-family, and USRP N210
31
+
32
+ The packaged client natively includes the shared USRP schema for the qualified
33
+ NI USRP-2901, Ettus Research USRP B205-mini, the broader USB/B200 family, and
34
+ the Ethernet-connected N210. No custom client driver is required. The B205-mini
35
+ uses the same native-style API and reports its live 1 RX/1 TX channel topology
36
+ through `remoterf_capabilities`.
31
37
 
32
38
  After reserving a server-local `usrp` inventory entry, fetch or refresh its
33
39
  Dynamic v2 package with the reservation token:
@@ -86,6 +92,75 @@ generic native dispatch, but are not release-qualified as exact UHD overload
86
92
  parity until the server's UHD 4.10 target-introspection and hardware
87
93
  differential gates pass.
88
94
 
95
+ ## RTL-SDR
96
+
97
+ RTL-SDR clients are generated from the server's `rtl_sdr` schema. The machine
98
+ running client code does not need `librtlsdr` or PyRtlSdr:
99
+
100
+ ```python
101
+ from remoteRF.drivers import ensure_driver
102
+
103
+ token = "reservation-token"
104
+ ensure_driver(token=token)
105
+
106
+ from remoteRF.drivers.rtl_sdr import RtlSdr
107
+
108
+ sdr = RtlSdr(token)
109
+ sdr.sample_rate = 2_048_000
110
+ sdr.center_freq = 100_000_000
111
+ sdr.gain = "auto"
112
+ sdr.agc_mode = True
113
+
114
+ samples = sdr.read_samples(16_384) # NumPy complex64
115
+ raw_iq = sdr.read_bytes(4096) # packed uint8 I/Q bytes
116
+ ```
117
+
118
+ The server owns the USB handle for its lifetime, so the generated client does
119
+ not close the physical radio. `read_samples` and `read_bytes` are bounded to a
120
+ 4 MiB response. Call them repeatedly for longer captures. Native asynchronous
121
+ callbacks are not transported remotely.
122
+
123
+ When a Tailscale address differs from the IP or DNS identity in the server
124
+ certificate, keep TLS verification enabled and set the expected identity:
125
+
126
+ ```bash
127
+ export REMOTERF_ADDR=rrf2.example.ts.net:61005
128
+ export REMOTERF_TLS_SERVER_NAME=certificate-name.example
129
+ ```
130
+
131
+ ## TI mmWave radar
132
+
133
+ TI radar clients are generated from the server's `ti_mmwave` schema. Only the
134
+ machine physically connected to the radar needs `pyserial` or a CP210x driver.
135
+ The initial parser profile supports xWR68xx mmWave SDK 3 out-of-box TLV output.
136
+
137
+ ```python
138
+ from remoteRF.drivers import ensure_driver
139
+
140
+ token = "reservation-token"
141
+ ensure_driver(token=token)
142
+
143
+ from remoteRF.drivers.ti_mmwave import TiMmWave, decode_frame
144
+
145
+ radar = TiMmWave(token)
146
+ print(radar.device_info)
147
+ print(radar.query_version())
148
+
149
+ radar.apply_config(open("profile.cfg").read(), start=True)
150
+ try:
151
+ packet = radar.read_frame(timeout=1.0)
152
+ frame = decode_frame(packet)
153
+ print(frame.header.frame_number, frame.points, frame.side_info)
154
+ finally:
155
+ radar.stop()
156
+ ```
157
+
158
+ `read_frame()` returns one complete binary UART packet. Decoding is client-local
159
+ and retains unknown TLVs as raw bytes, allowing custom firmware to be captured
160
+ before a dedicated parser profile is added. `stream_stats` reports dropped
161
+ frames, queued frames, resynchronization bytes, invalid headers, and reader
162
+ health. Remote firmware flashing is deliberately unsupported.
163
+
89
164
  If `pip install` doesn't work, you can clone the [source](https://github.com/WirelessLabAtUCLA/RemoteRF-Client) directly from github.
90
165
 
91
166
  <!-- 1. **Clone the repository:**
@@ -6,7 +6,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
6
6
 
7
7
  setup(
8
8
  name="remoterf",
9
- version="2.0.4",
9
+ version="2.0.8",
10
10
  author="Ethan Ge",
11
11
  author_email="ethoGalaxy@gmail.com",
12
12
  description="A python API to remotely access signal centric hardware. Client-side only! Courtesy of Wireless Lab @ UCLA & Prof. Ian Roberts.",
@@ -24,7 +24,7 @@ _sym_db = _symbol_database.Default()
24
24
 
25
25
 
26
26
 
27
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ngrpc.proto\x12\tremote_rf\"\xa2\x01\n\x11GenericRPCRequest\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x34\n\x04\x61rgs\x18\x02 \x03(\x0b\x32&.remote_rf.GenericRPCRequest.ArgsEntry\x1a@\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.remote_rf.Argument:\x02\x38\x01\"\x96\x01\n\x12GenericRPCResponse\x12;\n\x07results\x18\x01 \x03(\x0b\x32*.remote_rf.GenericRPCResponse.ResultsEntry\x1a\x43\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.remote_rf.Argument:\x02\x38\x01\"\x19\n\nArrayShape\x12\x0b\n\x03\x64im\x18\x01 \x03(\x05\"+\n\rComplexNumber\x12\x0c\n\x04real\x18\x01 \x01(\x02\x12\x0c\n\x04imag\x18\x02 \x01(\x02\"a\n\x11\x43omplexNumpyArray\x12$\n\x05shape\x18\x01 \x01(\x0b\x32\x15.remote_rf.ArrayShape\x12&\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x18.remote_rf.ComplexNumber\"D\n\x0eRealNumpyArray\x12$\n\x05shape\x18\x01 \x01(\x0b\x32\x15.remote_rf.ArrayShape\x12\x0c\n\x04\x64\x61ta\x18\x02 \x03(\x02\"\xed\x01\n\x08\x41rgument\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x15\n\x0bint64_value\x18\x02 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x03 \x01(\x02H\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12\x35\n\rcomplex_array\x18\x05 \x01(\x0b\x32\x1c.remote_rf.ComplexNumpyArrayH\x00\x12/\n\nreal_array\x18\x06 \x01(\x0b\x32\x19.remote_rf.RealNumpyArrayH\x00\x12\x14\n\njson_value\x18\x07 \x01(\tH\x00\x42\x07\n\x05value\":\n\x0cNDArrayValue\x12\r\n\x05\x64type\x18\x01 \x01(\t\x12\r\n\x05shape\x18\x02 \x03(\x03\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\xe9\x01\n\x0c\x44ynamicValue\x12\x14\n\nnull_value\x18\x01 \x01(\x08H\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x15\n\x0bint64_value\x18\x03 \x01(\x12H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x05 \x01(\tH\x00\x12\x15\n\x0b\x62ytes_value\x18\x06 \x01(\x0cH\x00\x12\x14\n\njson_value\x18\x07 \x01(\tH\x00\x12\x30\n\rndarray_value\x18\x08 \x01(\x0b\x32\x17.remote_rf.NDArrayValueH\x00\x42\x07\n\x05value\"B\n\nNamedValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.remote_rf.DynamicValue\"B\n\x08Mutation\x12\x0e\n\x06target\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.remote_rf.DynamicValue\"\xb0\x01\n\rErrorEnvelope\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x14\n\x0c\x64\x65tails_json\x18\x03 \x01(\t\x12\x0e\n\x06method\x18\x04 \x01(\t\x12\x18\n\x10native_exception\x18\x05 \x01(\t\x12\x13\n\x0buhd_version\x18\x06 \x01(\t\x12\x11\n\tretryable\x18\x07 \x01(\x08\x12\x18\n\x10\x66\x61tal_to_session\x18\x08 \x01(\x08\"s\n\x10NegotiateRequest\x12\x17\n\x0fschema_versions\x18\x01 \x03(\t\x12!\n\x19\x63ontrol_protocol_versions\x18\x02 \x03(\t\x12#\n\x1bstreaming_protocol_versions\x18\x03 \x03(\t\"\x9a\x01\n\x11NegotiateResponse\x12\x16\n\x0eschema_version\x18\x01 \x01(\t\x12 \n\x18\x63ontrol_protocol_version\x18\x02 \x01(\t\x12\"\n\x1astreaming_protocol_version\x18\x03 \x01(\t\x12\'\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\":\n\x10GetSchemaRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x17\n\x0fschema_versions\x18\x02 \x03(\t\"~\n\x11GetSchemaResponse\x12\x16\n\x0eschema_version\x18\x01 \x01(\t\x12\x13\n\x0bschema_json\x18\x02 \x01(\t\x12\x13\n\x0bschema_hash\x18\x03 \x01(\t\x12\'\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"\x88\x01\n\x12OpenSessionRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x1d\n\x15requested_schema_hash\x18\x02 \x01(\t\x12 \n\x18\x63ontrol_protocol_version\x18\x03 \x01(\t\x12\"\n\x1astreaming_protocol_version\x18\x04 \x01(\t\"\xee\x01\n\x13OpenSessionResponse\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x15\n\rdevice_handle\x18\x02 \x01(\t\x12\x13\n\x0bschema_json\x18\x03 \x01(\t\x12\x13\n\x0bschema_hash\x18\x04 \x01(\t\x12\x19\n\x11\x63\x61pabilities_json\x18\x05 \x01(\t\x12\x13\n\x0buhd_version\x18\x06 \x01(\t\x12\x0f\n\x07uhd_abi\x18\x07 \x01(\t\x12\x18\n\x10hardware_profile\x18\x08 \x01(\t\x12\'\n\x05\x65rror\x18\t \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"}\n\rInvokeRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0e\n\x06method\x18\x03 \x01(\t\x12\x13\n\x0boverload_id\x18\x04 \x01(\t\x12#\n\x04\x61rgs\x18\x05 \x03(\x0b\x32\x15.remote_rf.NamedValue\"\x8a\x01\n\x0eInvokeResponse\x12\'\n\x06result\x18\x01 \x01(\x0b\x32\x17.remote_rf.DynamicValue\x12&\n\tmutations\x18\x02 \x03(\x0b\x32\x13.remote_rf.Mutation\x12\'\n\x05\x65rror\x18\x03 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"8\n\x12\x43loseHandleRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0e\n\x06handle\x18\x02 \x01(\t\")\n\x13\x43loseSessionRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\"H\n\rCloseResponse\x12\x0e\n\x06\x63losed\x18\x01 \x01(\x08\x12\'\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"\xea\x03\n\x0bSampleFrame\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x12\n\ngeneration\x18\x03 \x01(\x04\x12\x14\n\x0coperation_id\x18\x04 \x01(\t\x12\x10\n\x08sequence\x18\x05 \x01(\x04\x12-\n\tdirection\x18\x06 \x01(\x0e\x32\x1a.remote_rf.SampleDirection\x12(\n\x04kind\x18\x07 \x01(\x0e\x32\x1a.remote_rf.SampleFrameKind\x12\r\n\x05\x64type\x18\x08 \x01(\t\x12\r\n\x05shape\x18\t \x03(\x03\x12\x10\n\x08\x63hannels\x18\n \x03(\r\x12\x14\n\x0csample_count\x18\x0b \x01(\x04\x12\x0f\n\x07payload\x18\x0c \x01(\x0c\x12\x15\n\rmetadata_json\x18\r \x01(\t\x12\x18\n\x10\x64\x65vice_time_secs\x18\x0e \x01(\x01\x12\x0f\n\x07\x63redits\x18\x0f \x01(\r\x12\x13\n\x0btimeout_sec\x18\x10 \x01(\x01\x12\x12\n\none_packet\x18\x11 \x01(\x08\x12\x15\n\rend_of_stream\x18\x12 \x01(\x08\x12\x11\n\tcancelled\x18\x13 \x01(\x08\x12\'\n\x05\x65rror\x18\x14 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\x12\r\n\x05\x66lags\x18\x15 \x01(\x04*e\n\x0fSampleDirection\x12 \n\x1cSAMPLE_DIRECTION_UNSPECIFIED\x10\x00\x12\x17\n\x13SAMPLE_DIRECTION_RX\x10\x01\x12\x17\n\x13SAMPLE_DIRECTION_TX\x10\x02*\xf2\x01\n\x0fSampleFrameKind\x12\x1c\n\x18SAMPLE_FRAME_UNSPECIFIED\x10\x00\x12\x15\n\x11SAMPLE_FRAME_OPEN\x10\x01\x12\x18\n\x14SAMPLE_FRAME_REQUEST\x10\x02\x12\x15\n\x11SAMPLE_FRAME_DATA\x10\x03\x12\x17\n\x13SAMPLE_FRAME_RESULT\x10\x04\x12\x17\n\x13SAMPLE_FRAME_CREDIT\x10\x05\x12\x17\n\x13SAMPLE_FRAME_CANCEL\x10\x06\x12\x16\n\x12SAMPLE_FRAME_CLOSE\x10\x07\x12\x16\n\x12SAMPLE_FRAME_ERROR\x10\x08\x32Q\n\nGenericRPC\x12\x43\n\x04\x43\x61ll\x12\x1c.remote_rf.GenericRPCRequest\x1a\x1d.remote_rf.GenericRPCResponse2\xc1\x03\n\x10\x44ynamicControlV2\x12\x46\n\tNegotiate\x12\x1b.remote_rf.NegotiateRequest\x1a\x1c.remote_rf.NegotiateResponse\x12\x46\n\tGetSchema\x12\x1b.remote_rf.GetSchemaRequest\x1a\x1c.remote_rf.GetSchemaResponse\x12L\n\x0bOpenSession\x12\x1d.remote_rf.OpenSessionRequest\x1a\x1e.remote_rf.OpenSessionResponse\x12=\n\x06Invoke\x12\x18.remote_rf.InvokeRequest\x1a\x19.remote_rf.InvokeResponse\x12\x46\n\x0b\x43loseHandle\x12\x1d.remote_rf.CloseHandleRequest\x1a\x18.remote_rf.CloseResponse\x12H\n\x0c\x43loseSession\x12\x1e.remote_rf.CloseSessionRequest\x1a\x18.remote_rf.CloseResponse2R\n\x0cSampleDataV1\x12\x42\n\x0cSampleStream\x12\x16.remote_rf.SampleFrame\x1a\x16.remote_rf.SampleFrame(\x01\x30\x01\x42\x1e\n\x10\x63om.example.demoB\nDemoProtosb\x06proto3')
27
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ngrpc.proto\x12\tremote_rf\"\xa2\x01\n\x11GenericRPCRequest\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x34\n\x04\x61rgs\x18\x02 \x03(\x0b\x32&.remote_rf.GenericRPCRequest.ArgsEntry\x1a@\n\tArgsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.remote_rf.Argument:\x02\x38\x01\"\x96\x01\n\x12GenericRPCResponse\x12;\n\x07results\x18\x01 \x03(\x0b\x32*.remote_rf.GenericRPCResponse.ResultsEntry\x1a\x43\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\"\n\x05value\x18\x02 \x01(\x0b\x32\x13.remote_rf.Argument:\x02\x38\x01\"\x19\n\nArrayShape\x12\x0b\n\x03\x64im\x18\x01 \x03(\x05\"+\n\rComplexNumber\x12\x0c\n\x04real\x18\x01 \x01(\x02\x12\x0c\n\x04imag\x18\x02 \x01(\x02\"a\n\x11\x43omplexNumpyArray\x12$\n\x05shape\x18\x01 \x01(\x0b\x32\x15.remote_rf.ArrayShape\x12&\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x18.remote_rf.ComplexNumber\"D\n\x0eRealNumpyArray\x12$\n\x05shape\x18\x01 \x01(\x0b\x32\x15.remote_rf.ArrayShape\x12\x0c\n\x04\x64\x61ta\x18\x02 \x03(\x02\"\xb6\x02\n\x08\x41rgument\x12\x16\n\x0cstring_value\x18\x01 \x01(\tH\x00\x12\x15\n\x0bint64_value\x18\x02 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x03 \x01(\x02H\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12\x35\n\rcomplex_array\x18\x05 \x01(\x0b\x32\x1c.remote_rf.ComplexNumpyArrayH\x00\x12/\n\nreal_array\x18\x06 \x01(\x0b\x32\x19.remote_rf.RealNumpyArrayH\x00\x12\x14\n\njson_value\x18\x07 \x01(\tH\x00\x12\x15\n\x0b\x62ytes_value\x18\x08 \x01(\x0cH\x00\x12\x30\n\rndarray_value\x18\t \x01(\x0b\x32\x17.remote_rf.NDArrayValueH\x00\x42\x07\n\x05value\":\n\x0cNDArrayValue\x12\r\n\x05\x64type\x18\x01 \x01(\t\x12\r\n\x05shape\x18\x02 \x03(\x03\x12\x0c\n\x04\x64\x61ta\x18\x03 \x01(\x0c\"\xe9\x01\n\x0c\x44ynamicValue\x12\x14\n\nnull_value\x18\x01 \x01(\x08H\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x15\n\x0bint64_value\x18\x03 \x01(\x12H\x00\x12\x16\n\x0c\x64ouble_value\x18\x04 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x05 \x01(\tH\x00\x12\x15\n\x0b\x62ytes_value\x18\x06 \x01(\x0cH\x00\x12\x14\n\njson_value\x18\x07 \x01(\tH\x00\x12\x30\n\rndarray_value\x18\x08 \x01(\x0b\x32\x17.remote_rf.NDArrayValueH\x00\x42\x07\n\x05value\"B\n\nNamedValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.remote_rf.DynamicValue\"B\n\x08Mutation\x12\x0e\n\x06target\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.remote_rf.DynamicValue\"\xb0\x01\n\rErrorEnvelope\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x14\n\x0c\x64\x65tails_json\x18\x03 \x01(\t\x12\x0e\n\x06method\x18\x04 \x01(\t\x12\x18\n\x10native_exception\x18\x05 \x01(\t\x12\x13\n\x0buhd_version\x18\x06 \x01(\t\x12\x11\n\tretryable\x18\x07 \x01(\x08\x12\x18\n\x10\x66\x61tal_to_session\x18\x08 \x01(\x08\"s\n\x10NegotiateRequest\x12\x17\n\x0fschema_versions\x18\x01 \x03(\t\x12!\n\x19\x63ontrol_protocol_versions\x18\x02 \x03(\t\x12#\n\x1bstreaming_protocol_versions\x18\x03 \x03(\t\"\x9a\x01\n\x11NegotiateResponse\x12\x16\n\x0eschema_version\x18\x01 \x01(\t\x12 \n\x18\x63ontrol_protocol_version\x18\x02 \x01(\t\x12\"\n\x1astreaming_protocol_version\x18\x03 \x01(\t\x12\'\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\":\n\x10GetSchemaRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x17\n\x0fschema_versions\x18\x02 \x03(\t\"~\n\x11GetSchemaResponse\x12\x16\n\x0eschema_version\x18\x01 \x01(\t\x12\x13\n\x0bschema_json\x18\x02 \x01(\t\x12\x13\n\x0bschema_hash\x18\x03 \x01(\t\x12\'\n\x05\x65rror\x18\x04 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"\x88\x01\n\x12OpenSessionRequest\x12\r\n\x05token\x18\x01 \x01(\t\x12\x1d\n\x15requested_schema_hash\x18\x02 \x01(\t\x12 \n\x18\x63ontrol_protocol_version\x18\x03 \x01(\t\x12\"\n\x1astreaming_protocol_version\x18\x04 \x01(\t\"\xee\x01\n\x13OpenSessionResponse\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x15\n\rdevice_handle\x18\x02 \x01(\t\x12\x13\n\x0bschema_json\x18\x03 \x01(\t\x12\x13\n\x0bschema_hash\x18\x04 \x01(\t\x12\x19\n\x11\x63\x61pabilities_json\x18\x05 \x01(\t\x12\x13\n\x0buhd_version\x18\x06 \x01(\t\x12\x0f\n\x07uhd_abi\x18\x07 \x01(\t\x12\x18\n\x10hardware_profile\x18\x08 \x01(\t\x12\'\n\x05\x65rror\x18\t \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"}\n\rInvokeRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x0e\n\x06method\x18\x03 \x01(\t\x12\x13\n\x0boverload_id\x18\x04 \x01(\t\x12#\n\x04\x61rgs\x18\x05 \x03(\x0b\x32\x15.remote_rf.NamedValue\"\x8a\x01\n\x0eInvokeResponse\x12\'\n\x06result\x18\x01 \x01(\x0b\x32\x17.remote_rf.DynamicValue\x12&\n\tmutations\x18\x02 \x03(\x0b\x32\x13.remote_rf.Mutation\x12\'\n\x05\x65rror\x18\x03 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"8\n\x12\x43loseHandleRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0e\n\x06handle\x18\x02 \x01(\t\")\n\x13\x43loseSessionRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\"H\n\rCloseResponse\x12\x0e\n\x06\x63losed\x18\x01 \x01(\x08\x12\'\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\"\xea\x03\n\x0bSampleFrame\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0e\n\x06handle\x18\x02 \x01(\t\x12\x12\n\ngeneration\x18\x03 \x01(\x04\x12\x14\n\x0coperation_id\x18\x04 \x01(\t\x12\x10\n\x08sequence\x18\x05 \x01(\x04\x12-\n\tdirection\x18\x06 \x01(\x0e\x32\x1a.remote_rf.SampleDirection\x12(\n\x04kind\x18\x07 \x01(\x0e\x32\x1a.remote_rf.SampleFrameKind\x12\r\n\x05\x64type\x18\x08 \x01(\t\x12\r\n\x05shape\x18\t \x03(\x03\x12\x10\n\x08\x63hannels\x18\n \x03(\r\x12\x14\n\x0csample_count\x18\x0b \x01(\x04\x12\x0f\n\x07payload\x18\x0c \x01(\x0c\x12\x15\n\rmetadata_json\x18\r \x01(\t\x12\x18\n\x10\x64\x65vice_time_secs\x18\x0e \x01(\x01\x12\x0f\n\x07\x63redits\x18\x0f \x01(\r\x12\x13\n\x0btimeout_sec\x18\x10 \x01(\x01\x12\x12\n\none_packet\x18\x11 \x01(\x08\x12\x15\n\rend_of_stream\x18\x12 \x01(\x08\x12\x11\n\tcancelled\x18\x13 \x01(\x08\x12\'\n\x05\x65rror\x18\x14 \x01(\x0b\x32\x18.remote_rf.ErrorEnvelope\x12\r\n\x05\x66lags\x18\x15 \x01(\x04*e\n\x0fSampleDirection\x12 \n\x1cSAMPLE_DIRECTION_UNSPECIFIED\x10\x00\x12\x17\n\x13SAMPLE_DIRECTION_RX\x10\x01\x12\x17\n\x13SAMPLE_DIRECTION_TX\x10\x02*\xf2\x01\n\x0fSampleFrameKind\x12\x1c\n\x18SAMPLE_FRAME_UNSPECIFIED\x10\x00\x12\x15\n\x11SAMPLE_FRAME_OPEN\x10\x01\x12\x18\n\x14SAMPLE_FRAME_REQUEST\x10\x02\x12\x15\n\x11SAMPLE_FRAME_DATA\x10\x03\x12\x17\n\x13SAMPLE_FRAME_RESULT\x10\x04\x12\x17\n\x13SAMPLE_FRAME_CREDIT\x10\x05\x12\x17\n\x13SAMPLE_FRAME_CANCEL\x10\x06\x12\x16\n\x12SAMPLE_FRAME_CLOSE\x10\x07\x12\x16\n\x12SAMPLE_FRAME_ERROR\x10\x08\x32Q\n\nGenericRPC\x12\x43\n\x04\x43\x61ll\x12\x1c.remote_rf.GenericRPCRequest\x1a\x1d.remote_rf.GenericRPCResponse2\xc1\x03\n\x10\x44ynamicControlV2\x12\x46\n\tNegotiate\x12\x1b.remote_rf.NegotiateRequest\x1a\x1c.remote_rf.NegotiateResponse\x12\x46\n\tGetSchema\x12\x1b.remote_rf.GetSchemaRequest\x1a\x1c.remote_rf.GetSchemaResponse\x12L\n\x0bOpenSession\x12\x1d.remote_rf.OpenSessionRequest\x1a\x1e.remote_rf.OpenSessionResponse\x12=\n\x06Invoke\x12\x18.remote_rf.InvokeRequest\x1a\x19.remote_rf.InvokeResponse\x12\x46\n\x0b\x43loseHandle\x12\x1d.remote_rf.CloseHandleRequest\x1a\x18.remote_rf.CloseResponse\x12H\n\x0c\x43loseSession\x12\x1e.remote_rf.CloseSessionRequest\x1a\x18.remote_rf.CloseResponse2R\n\x0cSampleDataV1\x12\x42\n\x0cSampleStream\x12\x16.remote_rf.SampleFrame\x1a\x16.remote_rf.SampleFrame(\x01\x30\x01\x42\x1e\n\x10\x63om.example.demoB\nDemoProtosb\x06proto3')
28
28
 
29
29
  _globals = globals()
30
30
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -36,10 +36,10 @@ if not _descriptor._USE_C_DESCRIPTORS:
36
36
  _globals['_GENERICRPCREQUEST_ARGSENTRY']._serialized_options = b'8\001'
37
37
  _globals['_GENERICRPCRESPONSE_RESULTSENTRY']._loaded_options = None
38
38
  _globals['_GENERICRPCRESPONSE_RESULTSENTRY']._serialized_options = b'8\001'
39
- _globals['_SAMPLEDIRECTION']._serialized_start=3213
40
- _globals['_SAMPLEDIRECTION']._serialized_end=3314
41
- _globals['_SAMPLEFRAMEKIND']._serialized_start=3317
42
- _globals['_SAMPLEFRAMEKIND']._serialized_end=3559
39
+ _globals['_SAMPLEDIRECTION']._serialized_start=3286
40
+ _globals['_SAMPLEDIRECTION']._serialized_end=3387
41
+ _globals['_SAMPLEFRAMEKIND']._serialized_start=3390
42
+ _globals['_SAMPLEFRAMEKIND']._serialized_end=3632
43
43
  _globals['_GENERICRPCREQUEST']._serialized_start=26
44
44
  _globals['_GENERICRPCREQUEST']._serialized_end=188
45
45
  _globals['_GENERICRPCREQUEST_ARGSENTRY']._serialized_start=124
@@ -57,45 +57,45 @@ if not _descriptor._USE_C_DESCRIPTORS:
57
57
  _globals['_REALNUMPYARRAY']._serialized_start=514
58
58
  _globals['_REALNUMPYARRAY']._serialized_end=582
59
59
  _globals['_ARGUMENT']._serialized_start=585
60
- _globals['_ARGUMENT']._serialized_end=822
61
- _globals['_NDARRAYVALUE']._serialized_start=824
62
- _globals['_NDARRAYVALUE']._serialized_end=882
63
- _globals['_DYNAMICVALUE']._serialized_start=885
64
- _globals['_DYNAMICVALUE']._serialized_end=1118
65
- _globals['_NAMEDVALUE']._serialized_start=1120
66
- _globals['_NAMEDVALUE']._serialized_end=1186
67
- _globals['_MUTATION']._serialized_start=1188
68
- _globals['_MUTATION']._serialized_end=1254
69
- _globals['_ERRORENVELOPE']._serialized_start=1257
70
- _globals['_ERRORENVELOPE']._serialized_end=1433
71
- _globals['_NEGOTIATEREQUEST']._serialized_start=1435
72
- _globals['_NEGOTIATEREQUEST']._serialized_end=1550
73
- _globals['_NEGOTIATERESPONSE']._serialized_start=1553
74
- _globals['_NEGOTIATERESPONSE']._serialized_end=1707
75
- _globals['_GETSCHEMAREQUEST']._serialized_start=1709
76
- _globals['_GETSCHEMAREQUEST']._serialized_end=1767
77
- _globals['_GETSCHEMARESPONSE']._serialized_start=1769
78
- _globals['_GETSCHEMARESPONSE']._serialized_end=1895
79
- _globals['_OPENSESSIONREQUEST']._serialized_start=1898
80
- _globals['_OPENSESSIONREQUEST']._serialized_end=2034
81
- _globals['_OPENSESSIONRESPONSE']._serialized_start=2037
82
- _globals['_OPENSESSIONRESPONSE']._serialized_end=2275
83
- _globals['_INVOKEREQUEST']._serialized_start=2277
84
- _globals['_INVOKEREQUEST']._serialized_end=2402
85
- _globals['_INVOKERESPONSE']._serialized_start=2405
86
- _globals['_INVOKERESPONSE']._serialized_end=2543
87
- _globals['_CLOSEHANDLEREQUEST']._serialized_start=2545
88
- _globals['_CLOSEHANDLEREQUEST']._serialized_end=2601
89
- _globals['_CLOSESESSIONREQUEST']._serialized_start=2603
90
- _globals['_CLOSESESSIONREQUEST']._serialized_end=2644
91
- _globals['_CLOSERESPONSE']._serialized_start=2646
92
- _globals['_CLOSERESPONSE']._serialized_end=2718
93
- _globals['_SAMPLEFRAME']._serialized_start=2721
94
- _globals['_SAMPLEFRAME']._serialized_end=3211
95
- _globals['_GENERICRPC']._serialized_start=3561
96
- _globals['_GENERICRPC']._serialized_end=3642
97
- _globals['_DYNAMICCONTROLV2']._serialized_start=3645
98
- _globals['_DYNAMICCONTROLV2']._serialized_end=4094
99
- _globals['_SAMPLEDATAV1']._serialized_start=4096
100
- _globals['_SAMPLEDATAV1']._serialized_end=4178
60
+ _globals['_ARGUMENT']._serialized_end=895
61
+ _globals['_NDARRAYVALUE']._serialized_start=897
62
+ _globals['_NDARRAYVALUE']._serialized_end=955
63
+ _globals['_DYNAMICVALUE']._serialized_start=958
64
+ _globals['_DYNAMICVALUE']._serialized_end=1191
65
+ _globals['_NAMEDVALUE']._serialized_start=1193
66
+ _globals['_NAMEDVALUE']._serialized_end=1259
67
+ _globals['_MUTATION']._serialized_start=1261
68
+ _globals['_MUTATION']._serialized_end=1327
69
+ _globals['_ERRORENVELOPE']._serialized_start=1330
70
+ _globals['_ERRORENVELOPE']._serialized_end=1506
71
+ _globals['_NEGOTIATEREQUEST']._serialized_start=1508
72
+ _globals['_NEGOTIATEREQUEST']._serialized_end=1623
73
+ _globals['_NEGOTIATERESPONSE']._serialized_start=1626
74
+ _globals['_NEGOTIATERESPONSE']._serialized_end=1780
75
+ _globals['_GETSCHEMAREQUEST']._serialized_start=1782
76
+ _globals['_GETSCHEMAREQUEST']._serialized_end=1840
77
+ _globals['_GETSCHEMARESPONSE']._serialized_start=1842
78
+ _globals['_GETSCHEMARESPONSE']._serialized_end=1968
79
+ _globals['_OPENSESSIONREQUEST']._serialized_start=1971
80
+ _globals['_OPENSESSIONREQUEST']._serialized_end=2107
81
+ _globals['_OPENSESSIONRESPONSE']._serialized_start=2110
82
+ _globals['_OPENSESSIONRESPONSE']._serialized_end=2348
83
+ _globals['_INVOKEREQUEST']._serialized_start=2350
84
+ _globals['_INVOKEREQUEST']._serialized_end=2475
85
+ _globals['_INVOKERESPONSE']._serialized_start=2478
86
+ _globals['_INVOKERESPONSE']._serialized_end=2616
87
+ _globals['_CLOSEHANDLEREQUEST']._serialized_start=2618
88
+ _globals['_CLOSEHANDLEREQUEST']._serialized_end=2674
89
+ _globals['_CLOSESESSIONREQUEST']._serialized_start=2676
90
+ _globals['_CLOSESESSIONREQUEST']._serialized_end=2717
91
+ _globals['_CLOSERESPONSE']._serialized_start=2719
92
+ _globals['_CLOSERESPONSE']._serialized_end=2791
93
+ _globals['_SAMPLEFRAME']._serialized_start=2794
94
+ _globals['_SAMPLEFRAME']._serialized_end=3284
95
+ _globals['_GENERICRPC']._serialized_start=3634
96
+ _globals['_GENERICRPC']._serialized_end=3715
97
+ _globals['_DYNAMICCONTROLV2']._serialized_start=3718
98
+ _globals['_DYNAMICCONTROLV2']._serialized_end=4167
99
+ _globals['_SAMPLEDATAV1']._serialized_start=4169
100
+ _globals['_SAMPLEDATAV1']._serialized_end=4251
101
101
  # @@protoc_insertion_point(module_scope)
@@ -1,10 +1,55 @@
1
- from ..grpc import grpc_pb2, grpc_pb2_grpc
1
+ """Serialization helpers for the legacy GenericRPC protocol."""
2
+ from __future__ import annotations
3
+
2
4
  import json
5
+ import math
6
+ from typing import Any
7
+
3
8
  import numpy as np
4
9
 
10
+ from ..grpc import grpc_pb2
11
+
5
12
  _JSON_TYPE_KEY = "__remoterf_json_type__"
13
+ _MAX_NDARRAY_BYTES = 64 * 1024 * 1024
14
+ _MAX_NDARRAY_DIMENSIONS = 8
15
+ _SUPPORTED_NDARRAY_KINDS = {"b", "i", "u", "f", "c"}
16
+
17
+
18
+ def _validate_ndarray(dtype: np.dtype, shape) -> int:
19
+ """Return the expected payload length for a safe numeric ndarray."""
20
+ if dtype.hasobject or dtype.kind not in _SUPPORTED_NDARRAY_KINDS:
21
+ raise ValueError(f"unsupported ndarray dtype: {dtype}")
22
+
23
+ normalized_shape = tuple(int(item) for item in shape)
24
+ if (
25
+ len(normalized_shape) > _MAX_NDARRAY_DIMENSIONS
26
+ or any(item < 0 for item in normalized_shape)
27
+ ):
28
+ raise ValueError("invalid ndarray shape")
29
+
30
+ expected = math.prod(normalized_shape) * dtype.itemsize
31
+ if expected > _MAX_NDARRAY_BYTES:
32
+ raise ValueError(f"ndarray exceeds {_MAX_NDARRAY_BYTES} bytes")
33
+ return expected
6
34
 
7
- def _json_safe(value):
35
+
36
+ def _decode_ndarray(descriptor: grpc_pb2.NDArrayValue) -> np.ndarray:
37
+ try:
38
+ dtype = np.dtype(descriptor.dtype)
39
+ except (TypeError, ValueError) as exc:
40
+ raise ValueError(f"invalid ndarray dtype: {descriptor.dtype!r}") from exc
41
+
42
+ shape = tuple(int(item) for item in descriptor.shape)
43
+ expected = _validate_ndarray(dtype, shape)
44
+ actual = len(descriptor.data)
45
+ if actual != expected:
46
+ raise ValueError(
47
+ f"ndarray byte length mismatch: expected {expected}, got {actual}"
48
+ )
49
+ return np.frombuffer(descriptor.data, dtype=dtype).reshape(shape).copy()
50
+
51
+
52
+ def _json_safe(value: Any):
8
53
  if hasattr(value, "as_payload"):
9
54
  return _json_safe(value.as_payload())
10
55
  if isinstance(value, np.ndarray):
@@ -27,21 +72,26 @@ def _json_safe(value):
27
72
  "complex": False,
28
73
  "data": array.tolist(),
29
74
  }
30
- if isinstance(value, (np.bool_,)):
75
+ if isinstance(value, np.bool_):
31
76
  return bool(value)
32
- if isinstance(value, (np.integer,)):
77
+ if isinstance(value, np.integer):
33
78
  return int(value)
34
- if isinstance(value, (np.floating,)):
79
+ if isinstance(value, np.floating):
35
80
  return float(value)
36
81
  if isinstance(value, complex):
37
- return {_JSON_TYPE_KEY: "complex", "real": float(value.real), "imag": float(value.imag)}
82
+ return {
83
+ _JSON_TYPE_KEY: "complex",
84
+ "real": float(value.real),
85
+ "imag": float(value.imag),
86
+ }
38
87
  if isinstance(value, dict):
39
88
  return {str(key): _json_safe(item) for key, item in value.items()}
40
89
  if isinstance(value, (list, tuple)):
41
90
  return [_json_safe(item) for item in value]
42
91
  return value
43
92
 
44
- def _json_restore(value):
93
+
94
+ def _json_restore(value: Any):
45
95
  if isinstance(value, dict):
46
96
  kind = value.get(_JSON_TYPE_KEY)
47
97
  if kind == "ndarray":
@@ -58,30 +108,36 @@ def _json_restore(value):
58
108
  return [_json_restore(item) for item in value]
59
109
  return value
60
110
 
61
- def unmap_arg(arg):
62
- if arg.HasField('int64_value'):
111
+
112
+ def unmap_arg(arg: grpc_pb2.Argument):
113
+ kind = arg.WhichOneof("value")
114
+ if kind == "int64_value":
63
115
  return arg.int64_value
64
- elif arg.HasField('float_value'):
116
+ if kind == "float_value":
65
117
  return arg.float_value
66
- elif arg.HasField('string_value'):
118
+ if kind == "string_value":
67
119
  return arg.string_value
68
- elif arg.HasField('bool_value'):
120
+ if kind == "bool_value":
69
121
  return arg.bool_value
70
- elif arg.HasField('real_array'):
122
+ if kind == "ndarray_value":
123
+ return _decode_ndarray(arg.ndarray_value)
124
+ if kind == "real_array":
71
125
  shape = tuple(arg.real_array.shape.dim)
72
126
  return np.array(arg.real_array.data, dtype=np.float64).reshape(shape)
73
- elif arg.HasField('complex_array'):
127
+ if kind == "complex_array":
74
128
  shape = tuple(arg.complex_array.shape.dim)
75
- data = [complex(c.real, c.imag) for c in arg.complex_array.data]
129
+ data = [complex(item.real, item.imag) for item in arg.complex_array.data]
76
130
  return np.array(data, dtype=np.complex64).reshape(shape)
77
- elif arg.HasField('json_value'):
131
+ if kind == "json_value":
78
132
  return _json_restore(json.loads(arg.json_value))
79
- else:
80
- raise ValueError(f"Unknown argument type during unmapping: {arg}")
81
-
82
- def map_arg(value):
133
+ if kind == "bytes_value":
134
+ return bytes(arg.bytes_value)
135
+ raise ValueError(f"Unknown argument type during unmapping: {arg}")
136
+
137
+
138
+ def map_arg(value: Any) -> grpc_pb2.Argument:
83
139
  arg = grpc_pb2.Argument()
84
-
140
+
85
141
  if isinstance(value, (bool, np.bool_)):
86
142
  arg.bool_value = bool(value)
87
143
  elif hasattr(value, "as_payload"):
@@ -94,6 +150,8 @@ def map_arg(value):
94
150
  arg.float_value = float(value)
95
151
  elif isinstance(value, str):
96
152
  arg.string_value = value
153
+ elif isinstance(value, (bytes, bytearray, memoryview)):
154
+ arg.bytes_value = bytes(value)
97
155
  elif isinstance(value, (list, tuple)):
98
156
  try:
99
157
  array = np.asarray(value)
@@ -110,51 +168,33 @@ def map_arg(value):
110
168
  elif isinstance(value, np.ndarray):
111
169
  if value.dtype == object:
112
170
  raise ValueError(f"Cannot map object-dtype array: {value!r}")
113
- if value.dtype.kind not in {"b", "i", "u", "f", "c"}:
114
- arg.json_value = json.dumps(_json_safe(value.tolist()), separators=(",", ":"))
171
+ if value.dtype.kind not in _SUPPORTED_NDARRAY_KINDS:
172
+ arg.json_value = json.dumps(
173
+ _json_safe(value.tolist()), separators=(",", ":")
174
+ )
115
175
  return arg
116
- if np.iscomplexobj(value):
117
- complex_array = arg.complex_array
118
- complex_array.shape.dim.extend(value.shape)
119
- for num in value.ravel():
120
- complex_num = complex_array.data.add()
121
- complex_num.real = float(num.real)
122
- complex_num.imag = float(num.imag)
123
- else:
124
- float_array = arg.real_array
125
- float_array.shape.dim.extend(value.shape)
126
- float_array.data.extend(np.asarray(value, dtype=np.float32).ravel())
176
+
177
+ array = np.asarray(value)
178
+ _validate_ndarray(array.dtype, array.shape)
179
+ if not array.flags.c_contiguous:
180
+ array = np.ascontiguousarray(array)
181
+ descriptor = arg.ndarray_value
182
+ descriptor.dtype = array.dtype.str
183
+ descriptor.shape.extend(array.shape)
184
+ descriptor.data = array.tobytes(order="C")
127
185
  else:
128
186
  raise ValueError(f"Unknown argument type during mapping: {value}")
129
187
  return arg
130
-
131
- def map_array_proto(np_array):
132
- arg = grpc_pb2.Argument()
133
-
134
- # Check if the array is complex
135
- if np.iscomplexobj(np_array):
136
- complex_array = grpc_pb2.ComplexArray()
137
- for num in np_array.flat:
138
- complex_number = complex_array.data.add()
139
- complex_number.real = num.real
140
- complex_number.imag = num.imag
141
- arg.complex_array.CopyFrom(complex_array)
142
- else:
143
- # Handle as a regular float array
144
- float_array = grpc_pb2.FloatArray()
145
- float_array.data.extend(np_array.flat)
146
- arg.float_array.CopyFrom(float_array)
147
188
 
148
- return arg
149
189
 
150
- def unmap_array_proto(arg):
151
- # Check which type of array is available and convert appropriately
152
- if arg.HasField('complex_array'):
153
- # Convert ComplexArray to a numpy array of complex numbers
154
- data = [complex(cn.real, cn.imag) for cn in arg.complex_array.data]
155
- return np.array(data, dtype=np.complex64)
156
- elif arg.HasField('float_array'):
157
- # Convert FloatArray to a numpy array of floats
158
- return np.array(arg.float_array.data, dtype=np.float32)
159
- else:
190
+ def map_array_proto(np_array) -> grpc_pb2.Argument:
191
+ """Backward-compatible wrapper around :func:`map_arg`."""
192
+ return map_arg(np.asarray(np_array))
193
+
194
+
195
+ def unmap_array_proto(arg: grpc_pb2.Argument) -> np.ndarray:
196
+ """Backward-compatible array-only wrapper around :func:`unmap_arg`."""
197
+ value = unmap_arg(arg)
198
+ if not isinstance(value, np.ndarray):
160
199
  raise ValueError("Argument does not contain a recognizable array.")
200
+ return value
@@ -49,6 +49,18 @@ options = [
49
49
  ('grpc.max_receive_message_length', 100 * 1024 * 1024),
50
50
  ]
51
51
 
52
+ # A server reached over Tailscale may present the same certificate it uses on
53
+ # its public or LAN address. Keep certificate verification enabled while
54
+ # allowing the configured certificate identity to differ from REMOTERF_ADDR.
55
+ tls_server_name = (os.getenv("REMOTERF_TLS_SERVER_NAME") or "").strip()
56
+ if tls_server_name:
57
+ options.extend(
58
+ [
59
+ ("grpc.ssl_target_name_override", tls_server_name),
60
+ ("grpc.default_authority", tls_server_name),
61
+ ]
62
+ )
63
+
52
64
  # Server.crt
53
65
  certs_path = Path(ca_path).expanduser().resolve()
54
66
  with certs_path.open('rb') as f: