remoterf 0.1.0.3__py3-none-any.whl
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/__init__.py +0 -0
- remoteRF/common/__init__.py +2 -0
- remoteRF/common/grpc/__init__.py +1 -0
- remoteRF/common/grpc/grpc_pb2.py +59 -0
- remoteRF/common/grpc/grpc_pb2_grpc.py +97 -0
- remoteRF/common/utils/__init__.py +4 -0
- remoteRF/common/utils/ansi_codes.py +120 -0
- remoteRF/common/utils/api_token.py +31 -0
- remoteRF/common/utils/list_string.py +5 -0
- remoteRF/common/utils/process_arg.py +80 -0
- remoteRF/config/__init__.py +0 -0
- remoteRF/config/cert_fetcher.py +118 -0
- remoteRF/config/config.py +135 -0
- remoteRF/core/__init__.py +2 -0
- remoteRF/core/acc_login.py +4 -0
- remoteRF/core/app.py +624 -0
- remoteRF/core/grpc_acc.py +60 -0
- remoteRF/core/grpc_client.py +320 -0
- remoteRF/core/version.py +8 -0
- remoteRF/drivers/__init__.py +0 -0
- remoteRF/drivers/adalm_pluto/__init__.py +1 -0
- remoteRF/drivers/adalm_pluto/pluto_remote.py +249 -0
- remoteRF/remoterf_cli.py +203 -0
- remoterf-0.1.0.3.dist-info/METADATA +158 -0
- remoterf-0.1.0.3.dist-info/RECORD +28 -0
- remoterf-0.1.0.3.dist-info/WHEEL +5 -0
- remoterf-0.1.0.3.dist-info/entry_points.txt +2 -0
- remoterf-0.1.0.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
import socket
|
|
2
|
+
import getpass
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import os
|
|
5
|
+
from dotenv import load_dotenv
|
|
6
|
+
|
|
7
|
+
import grpc
|
|
8
|
+
from ..common.grpc import grpc_pb2
|
|
9
|
+
from ..common.grpc import grpc_pb2_grpc
|
|
10
|
+
from ..common.utils import *
|
|
11
|
+
|
|
12
|
+
load_dotenv(Path.home() / ".config" / "remoterf" / ".env")
|
|
13
|
+
addr = os.getenv("REMOTERF_ADDR") # "host:port"
|
|
14
|
+
ca_path = os.getenv("REMOTERF_CA_CERT") # path to saved CA cert
|
|
15
|
+
|
|
16
|
+
options = [
|
|
17
|
+
('grpc.max_send_message_length', 100 * 1024 * 1024),
|
|
18
|
+
('grpc.max_receive_message_length', 100 * 1024 * 1024),
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
# Server.crt
|
|
22
|
+
certs_path = Path(ca_path).expanduser().resolve()
|
|
23
|
+
with certs_path.open('rb') as f:
|
|
24
|
+
trusted_certs = f.read()
|
|
25
|
+
|
|
26
|
+
credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
|
|
27
|
+
channel = grpc.secure_channel(addr, credentials, options=options)
|
|
28
|
+
stub = grpc_pb2_grpc.GenericRPCStub(channel)
|
|
29
|
+
|
|
30
|
+
tcp_calls = 0
|
|
31
|
+
|
|
32
|
+
def get_tcp_calls():
|
|
33
|
+
return tcp_calls
|
|
34
|
+
|
|
35
|
+
def rpc_client(*, function_name, args):
|
|
36
|
+
global tcp_calls
|
|
37
|
+
tcp_calls += 1
|
|
38
|
+
# print(tcp_calls)
|
|
39
|
+
# if not is_connected:
|
|
40
|
+
# response = rpc_client(function_name="UserLogin", args={"username": grpc_pb2.Argument(string_value=input("Username: ")), "password": grpc_pb2.Argument(string_value=getpass.getpass("Password: ")), "client_ip": grpc_pb2.Argument(string_value=local_ip)})
|
|
41
|
+
# if (response.results['status'].string_value == 'Success'):
|
|
42
|
+
# print("Login successful.")
|
|
43
|
+
# is_connected = True
|
|
44
|
+
|
|
45
|
+
# TODO: Handle user login
|
|
46
|
+
|
|
47
|
+
# print(f"Opening connection to {server_ip}:{server_port}")
|
|
48
|
+
|
|
49
|
+
# TODO: Handle Errors
|
|
50
|
+
|
|
51
|
+
# print(f"Calling function: {function_name}")
|
|
52
|
+
response = stub.Call(grpc_pb2.GenericRPCRequest(function_name=function_name, args=args))
|
|
53
|
+
|
|
54
|
+
if 'a' in response.results:
|
|
55
|
+
print(f"Error: {unmap_arg(response.results['a'])}")
|
|
56
|
+
exit()
|
|
57
|
+
|
|
58
|
+
if 'UE' in response.results:
|
|
59
|
+
print(f"UserError: {unmap_arg(response.results['UE'])}")
|
|
60
|
+
input("Hit enter to continue...")
|
|
61
|
+
|
|
62
|
+
if 'Message' in response.results:
|
|
63
|
+
print(f"{unmap_arg(response.results['Message'])}")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
return response
|
|
67
|
+
|
|
68
|
+
#region Example Usage
|
|
69
|
+
|
|
70
|
+
# if __name__ == '__main__':
|
|
71
|
+
# args={
|
|
72
|
+
# "key1": grpc_pb2.Argument(string_value="Hello"),
|
|
73
|
+
# "key2": grpc_pb2.Argument(int32_value=123),
|
|
74
|
+
# "key3": grpc_pb2.Argument(float_value=4.56),
|
|
75
|
+
# "key4": grpc_pb2.Argument(bool_value=True),
|
|
76
|
+
# "client_ip": grpc_pb2.Argument(string_value=local_ip)
|
|
77
|
+
# }
|
|
78
|
+
|
|
79
|
+
# response = rpc_client(function_name="echo", args=args)
|
|
80
|
+
|
|
81
|
+
# if 'client_ip' in response.results:
|
|
82
|
+
# del response.results['client_ip']
|
|
83
|
+
|
|
84
|
+
# # Print results
|
|
85
|
+
# print("Received response:")
|
|
86
|
+
# for key, arg in response.results.items():
|
|
87
|
+
# # Decode the oneof fields
|
|
88
|
+
# if arg.HasField('string_value'):
|
|
89
|
+
# value = arg.string_value
|
|
90
|
+
# elif arg.HasField('int32_value'):
|
|
91
|
+
# value = arg.int32_value
|
|
92
|
+
# elif arg.HasField('float_value'):
|
|
93
|
+
# value = arg.float_value
|
|
94
|
+
# elif arg.HasField('bool_value'):
|
|
95
|
+
# value = arg.bool_value
|
|
96
|
+
# else:
|
|
97
|
+
# value = "Undefined"
|
|
98
|
+
|
|
99
|
+
# print(f"{key}: {value}")
|
|
100
|
+
|
|
101
|
+
#endregion
|
|
102
|
+
|
|
103
|
+
from typing import Any, Dict, Optional
|
|
104
|
+
|
|
105
|
+
def handle_admin_command(inpu: str):
|
|
106
|
+
"""
|
|
107
|
+
Parses commands like:
|
|
108
|
+
admin help
|
|
109
|
+
admin printa | printr | printp | printd
|
|
110
|
+
admin rm aa | rm ar | rm a <username>
|
|
111
|
+
admin setacc <username> <U|P|A> [devices=1,2,3] [max_res=5] [max_time=1800]
|
|
112
|
+
|
|
113
|
+
Requires account.is_admin == True (client-side gate). Server still enforces.
|
|
114
|
+
"""
|
|
115
|
+
if not getattr(account, "is_admin", False):
|
|
116
|
+
print("Access denied: you are not an Admin.")
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
tokens = (inpu or "").strip().split()
|
|
120
|
+
if len(tokens) < 2 or tokens[0].lower() != "admin":
|
|
121
|
+
print("Usage: admin <command>. Try: admin help")
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
cmd = tokens[1].lower()
|
|
125
|
+
|
|
126
|
+
def call_admin(fn: str, extra: dict | None = None):
|
|
127
|
+
return remote_admin_rpc_client(
|
|
128
|
+
function_name=fn,
|
|
129
|
+
auth_un=account.username,
|
|
130
|
+
auth_pw=account.password,
|
|
131
|
+
args=extra or {},
|
|
132
|
+
print_result=True,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if cmd in ("help", "h"):
|
|
136
|
+
print("Admin commands:")
|
|
137
|
+
print(" admin printa - Print all accounts")
|
|
138
|
+
print(" admin printr - Print all reservations")
|
|
139
|
+
print(" admin printp - Print all perms")
|
|
140
|
+
print(" admin printd - Print all devices")
|
|
141
|
+
print(" admin rm aa - Remove all accounts")
|
|
142
|
+
print(" admin rm ar - Remove all reservations")
|
|
143
|
+
print(" admin rm a <username> - Remove one account")
|
|
144
|
+
print(" admin setacc <u> <U|P|A> [devices=1,2] [max_res=3] [max_time=1800]")
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
# ----- print* -----
|
|
148
|
+
if cmd in ("printa", "print_accounts", "print_all_accounts"):
|
|
149
|
+
call_admin("print_all_accounts")
|
|
150
|
+
return
|
|
151
|
+
|
|
152
|
+
if cmd in ("printr", "print_res", "print_all_reservations"):
|
|
153
|
+
call_admin("print_all_reservations")
|
|
154
|
+
return
|
|
155
|
+
|
|
156
|
+
if cmd in ("printp", "print_perms", "print_all_perms"):
|
|
157
|
+
call_admin("print_all_perms")
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
if cmd in ("printd", "print_devices", "print_all_devices"):
|
|
161
|
+
call_admin("print_all_devices")
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
# ----- rm -----
|
|
165
|
+
if cmd == "rm":
|
|
166
|
+
if len(tokens) < 3:
|
|
167
|
+
print("Usage: admin rm <aa|ar|a> [username]")
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
sub = tokens[2].lower()
|
|
171
|
+
|
|
172
|
+
if sub == "aa":
|
|
173
|
+
call_admin("remove_all_users")
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
if sub == "ar":
|
|
177
|
+
call_admin("remove_all_reservations")
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
if sub == "a":
|
|
181
|
+
if len(tokens) < 4:
|
|
182
|
+
print("Usage: admin rm a <username>")
|
|
183
|
+
return
|
|
184
|
+
call_admin("remove_user", {"username": tokens[3]})
|
|
185
|
+
return
|
|
186
|
+
|
|
187
|
+
print("Unknown rm subcommand. Use: aa, ar, a <username>")
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
# ----- setacc -----
|
|
191
|
+
if cmd in ("setacc", "set_account", "setperm", "set"):
|
|
192
|
+
if len(tokens) < 4:
|
|
193
|
+
print("Usage: admin setacc <username> <U|P|A> [devices=1,2] [max_res=3] [max_time=1800]")
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
target_user = tokens[2]
|
|
197
|
+
perm = tokens[3].upper()
|
|
198
|
+
|
|
199
|
+
extra: dict = {"username": target_user, "permission": perm}
|
|
200
|
+
|
|
201
|
+
# Parse optional k=v args (very lightweight parser)
|
|
202
|
+
# Examples:
|
|
203
|
+
# devices=1,2,3
|
|
204
|
+
# max_res=5
|
|
205
|
+
# max_time=1800
|
|
206
|
+
for t in tokens[4:]:
|
|
207
|
+
if "=" not in t:
|
|
208
|
+
continue
|
|
209
|
+
k, v = t.split("=", 1)
|
|
210
|
+
k = k.strip().lower()
|
|
211
|
+
v = v.strip()
|
|
212
|
+
|
|
213
|
+
if k in ("devices", "device_list", "devices_allowed", "device_ids"):
|
|
214
|
+
# server-side remote_admin_call already supports "1,2,3" as string
|
|
215
|
+
extra["device_list"] = v
|
|
216
|
+
elif k in ("max_res", "max_reservations"):
|
|
217
|
+
extra["max_reservations"] = int(v)
|
|
218
|
+
elif k in ("max_time", "max_res_time", "max_reservation_time_sec"):
|
|
219
|
+
extra["max_reservation_time_sec"] = int(v)
|
|
220
|
+
|
|
221
|
+
call_admin("set_account", extra)
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
print(f"Unknown admin command: {cmd}. Try: admin help")
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def remote_admin_rpc_client(
|
|
228
|
+
*,
|
|
229
|
+
function_name: str,
|
|
230
|
+
auth_un: str,
|
|
231
|
+
auth_pw: str,
|
|
232
|
+
args: Optional[Dict[str, Any]] = None,
|
|
233
|
+
raise_on_error: bool = False,
|
|
234
|
+
print_result: bool = False,
|
|
235
|
+
) -> Dict[str, Any]:
|
|
236
|
+
"""
|
|
237
|
+
Client helper for RemoteAdmin:<function> calls.
|
|
238
|
+
|
|
239
|
+
Builds and sends:
|
|
240
|
+
function_name = "RemoteAdmin:<function_name>"
|
|
241
|
+
args include:
|
|
242
|
+
auth_un, auth_pw (mapped via map_arg)
|
|
243
|
+
+ any additional args (mapped via map_arg if not already grpc_pb2.Argument)
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
{
|
|
247
|
+
"ok": bool,
|
|
248
|
+
"result": str | None,
|
|
249
|
+
"error": str | None,
|
|
250
|
+
"traceback": str | None,
|
|
251
|
+
"raw": grpc_pb2.GenericRPCResponse,
|
|
252
|
+
}
|
|
253
|
+
"""
|
|
254
|
+
fn = (function_name or "").strip()
|
|
255
|
+
if fn.startswith("RemoteAdmin:"):
|
|
256
|
+
rpc_fn = fn
|
|
257
|
+
else:
|
|
258
|
+
rpc_fn = f"RemoteAdmin:{fn}"
|
|
259
|
+
|
|
260
|
+
payload: Dict[str, Any] = {
|
|
261
|
+
"auth_un": map_arg(auth_un),
|
|
262
|
+
"auth_pw": map_arg(auth_pw),
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if args:
|
|
266
|
+
for k, v in args.items():
|
|
267
|
+
if v is None:
|
|
268
|
+
continue
|
|
269
|
+
# If caller already passed a grpc Argument, keep it.
|
|
270
|
+
if isinstance(v, grpc_pb2.Argument):
|
|
271
|
+
payload[str(k)] = v
|
|
272
|
+
else:
|
|
273
|
+
payload[str(k)] = map_arg(v)
|
|
274
|
+
|
|
275
|
+
resp = rpc_client(function_name=rpc_fn, args=payload)
|
|
276
|
+
|
|
277
|
+
# Parse the standardized RemoteAdmin response keys:
|
|
278
|
+
# Ok, Result, Error, Traceback (each typically map_arg-encoded)
|
|
279
|
+
results = getattr(resp, "results", {}) or {}
|
|
280
|
+
|
|
281
|
+
def _get_str(key: str) -> Optional[str]:
|
|
282
|
+
if key not in results:
|
|
283
|
+
return None
|
|
284
|
+
try:
|
|
285
|
+
return str(unmap_arg(results[key]))
|
|
286
|
+
except Exception:
|
|
287
|
+
try:
|
|
288
|
+
return str(results[key])
|
|
289
|
+
except Exception:
|
|
290
|
+
return None
|
|
291
|
+
|
|
292
|
+
ok_val = results.get("Ok", None)
|
|
293
|
+
ok = False
|
|
294
|
+
if ok_val is not None:
|
|
295
|
+
try:
|
|
296
|
+
ok = bool(unmap_arg(ok_val))
|
|
297
|
+
except Exception:
|
|
298
|
+
ok = False
|
|
299
|
+
|
|
300
|
+
out = {
|
|
301
|
+
"ok": ok,
|
|
302
|
+
"result": _get_str("Result"),
|
|
303
|
+
"error": _get_str("Error"),
|
|
304
|
+
"traceback": _get_str("Traceback"),
|
|
305
|
+
"raw": resp,
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if print_result:
|
|
309
|
+
if out["ok"]:
|
|
310
|
+
print(out["result"] or "OK")
|
|
311
|
+
else:
|
|
312
|
+
print(out["error"] or "RemoteAdmin call failed.")
|
|
313
|
+
if out["traceback"]:
|
|
314
|
+
print(out["traceback"])
|
|
315
|
+
|
|
316
|
+
if raise_on_error and not out["ok"]:
|
|
317
|
+
msg = out["error"] or "RemoteAdmin call failed."
|
|
318
|
+
raise RuntimeError(msg)
|
|
319
|
+
|
|
320
|
+
return out
|
remoteRF/core/version.py
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from . import pluto_remote as adi
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
from ...core.grpc_client import rpc_client
|
|
2
|
+
from ...common.utils import *
|
|
3
|
+
from ...common.grpc import grpc_pb2
|
|
4
|
+
from ...core.grpc_client import get_tcp_calls
|
|
5
|
+
|
|
6
|
+
def try_get(function_name, token):
|
|
7
|
+
try:
|
|
8
|
+
return unmap_arg(rpc_client(function_name=f"Pluto:{function_name}:GET", args={'a':map_arg(token)}).results[function_name])
|
|
9
|
+
except Exception as e:
|
|
10
|
+
input(f"Error: {e}\nHit enter to continue...")
|
|
11
|
+
return None
|
|
12
|
+
|
|
13
|
+
def try_set(function_name, value, token):
|
|
14
|
+
try:
|
|
15
|
+
rpc_client(function_name=f"Pluto:{function_name}:SET", args={function_name: map_arg(value), 'a':map_arg(token)})
|
|
16
|
+
except Exception as e:
|
|
17
|
+
input(f"Error: {e}\nHit enter to continue...")
|
|
18
|
+
|
|
19
|
+
def try_call_0_arg(function_name, token): # 0 argument call
|
|
20
|
+
try:
|
|
21
|
+
response = rpc_client(
|
|
22
|
+
function_name=f"Pluto:{function_name}:CALL0",
|
|
23
|
+
args={
|
|
24
|
+
'a': map_arg(token)
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
return unmap_arg(response.results[function_name])
|
|
28
|
+
except Exception as e:
|
|
29
|
+
input(f"RPC_0_call Error: {e}\nHit enter to continue...")
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def try_call_1_arg(function_name, arg, token): # 1 argument call
|
|
33
|
+
try:
|
|
34
|
+
response = rpc_client(
|
|
35
|
+
function_name=f"Pluto:{function_name}:CALL1",
|
|
36
|
+
args={
|
|
37
|
+
'a': map_arg(token),
|
|
38
|
+
'arg1': map_arg(arg)
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
# The server should return something like {function_name: <something>}
|
|
42
|
+
return unmap_arg(response.results[function_name])
|
|
43
|
+
except Exception as e:
|
|
44
|
+
input(f"RPC_1_call Error: {e}\nHit enter to continue...")
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
class rx_def:
|
|
48
|
+
pass
|
|
49
|
+
|
|
50
|
+
class tx_def:
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
class rx_tx_def(rx_def, tx_def):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
class ad9364(rx_tx_def):
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
class Pluto: # client
|
|
60
|
+
|
|
61
|
+
def __init__(self, token:str, debug=False):
|
|
62
|
+
self.token = token
|
|
63
|
+
response = try_call_0_arg(function_name="ip", token=token)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def api_token(self, token:str) -> None:
|
|
67
|
+
self.token = token
|
|
68
|
+
try_call_0_arg(function_name="ip", token=token)
|
|
69
|
+
|
|
70
|
+
# PlutoSDR
|
|
71
|
+
|
|
72
|
+
_device_name = "PlutoSDR"
|
|
73
|
+
_uri_auto = "ip:pluto.local"
|
|
74
|
+
|
|
75
|
+
def __repr__(self): # ! UNTESTED !
|
|
76
|
+
return try_get("__repr__", self.token)
|
|
77
|
+
|
|
78
|
+
#region ad9364
|
|
79
|
+
"""AD9364 Transceiver"""
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def filter(self):
|
|
83
|
+
return try_get("filter", self.token)
|
|
84
|
+
|
|
85
|
+
@filter.setter
|
|
86
|
+
def filter(self, value):
|
|
87
|
+
try_set("filter", value, self.token)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def loopback(self):
|
|
91
|
+
"""loopback: Set loopback mode. Options are:
|
|
92
|
+
0 (Disable), 1 (Digital), 2 (RF)"""
|
|
93
|
+
return try_get("loopback", self.token)
|
|
94
|
+
|
|
95
|
+
@loopback.setter
|
|
96
|
+
def loopback(self, value):
|
|
97
|
+
try_set("loopback", value, self.token)
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def gain_control_mode_chan0(self):
|
|
101
|
+
"""gain_control_mode_chan0: Mode of receive path AGC. Options are:
|
|
102
|
+
slow_attack, fast_attack, manual"""
|
|
103
|
+
return try_get("gain_control_mode_chan0", self.token)
|
|
104
|
+
|
|
105
|
+
@gain_control_mode_chan0.setter
|
|
106
|
+
def gain_control_mode_chan0(self, value):
|
|
107
|
+
try_set("gain_control_mode_chan0", value, self.token)
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def rx_hardwaregain_chan0(self):
|
|
111
|
+
"""rx_hardwaregain_chan0: Gain applied to RX path. Only applicable when
|
|
112
|
+
gain_control_mode is set to 'manual'"""
|
|
113
|
+
return try_get("rx_hardwaregain_chan0", self.token)
|
|
114
|
+
|
|
115
|
+
@rx_hardwaregain_chan0.setter
|
|
116
|
+
def rx_hardwaregain_chan0(self, value):
|
|
117
|
+
try_set("rx_hardwaregain_chan0", value, self.token)
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
def tx_hardwaregain_chan0(self):
|
|
121
|
+
"""tx_hardwaregain_chan0: Attenuation applied to TX path"""
|
|
122
|
+
return try_get("tx_hardwaregain_chan0", self.token)
|
|
123
|
+
|
|
124
|
+
@tx_hardwaregain_chan0.setter
|
|
125
|
+
def tx_hardwaregain_chan0(self, value):
|
|
126
|
+
try_set("tx_hardwaregain_chan0", value, self.token)
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def rx_rf_bandwidth(self):
|
|
130
|
+
"""rx_rf_bandwidth: Bandwidth of front-end analog filter of RX path"""
|
|
131
|
+
return try_get("rx_rf_bandwidth", self.token)
|
|
132
|
+
|
|
133
|
+
@rx_rf_bandwidth.setter
|
|
134
|
+
def rx_rf_bandwidth(self, value):
|
|
135
|
+
try_set("rx_rf_bandwidth", value, self.token)
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def tx_rf_bandwidth(self):
|
|
139
|
+
"""tx_rf_bandwidth: Bandwidth of front-end analog filter of TX path"""
|
|
140
|
+
return try_get("tx_rf_bandwidth", self.token)
|
|
141
|
+
|
|
142
|
+
@tx_rf_bandwidth.setter
|
|
143
|
+
def tx_rf_bandwidth(self, value):
|
|
144
|
+
try_set("tx_rf_bandwidth", value, self.token)
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def sample_rate(self): # ! UNTESTED !
|
|
148
|
+
"""sample_rate: Sample rate RX and TX paths in samples per second"""
|
|
149
|
+
return try_get("sample_rate", self.token)
|
|
150
|
+
|
|
151
|
+
@sample_rate.setter
|
|
152
|
+
def sample_rate(self, rate): # ! UNTESTED !
|
|
153
|
+
try_set("sample_rate", rate, self.token)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def rx_lo(self):
|
|
157
|
+
"""rx_lo: Carrier frequency of RX path"""
|
|
158
|
+
return try_get("rx_lo", self.token)
|
|
159
|
+
|
|
160
|
+
@rx_lo.setter
|
|
161
|
+
def rx_lo(self, value):
|
|
162
|
+
try_set("rx_lo", value, self.token)
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def tx_lo(self):
|
|
166
|
+
"""tx_lo: Carrier frequency of TX path"""
|
|
167
|
+
return try_get("tx_lo", self.token)
|
|
168
|
+
|
|
169
|
+
@tx_lo.setter
|
|
170
|
+
def tx_lo(self, value):
|
|
171
|
+
try_set("tx_lo", value, self.token)
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def tx_cyclic_buffer(self):
|
|
175
|
+
"""tx_cyclic_buffer: Size of cyclic buffer"""
|
|
176
|
+
return try_get("tx_cyclic_buffer", self.token)
|
|
177
|
+
|
|
178
|
+
@tx_cyclic_buffer.setter
|
|
179
|
+
def tx_cyclic_buffer(self, value):
|
|
180
|
+
try_set("tx_cyclic_buffer", value, self.token)
|
|
181
|
+
|
|
182
|
+
def tx_destroy_buffer(self):
|
|
183
|
+
try_call_0_arg("tx_destroy_buffer", self.token)
|
|
184
|
+
|
|
185
|
+
def rx_destroy_buffer(self):
|
|
186
|
+
try_call_0_arg("rx_destroy_buffer", self.token)
|
|
187
|
+
|
|
188
|
+
#endregion
|
|
189
|
+
|
|
190
|
+
#region rx_def
|
|
191
|
+
|
|
192
|
+
def rx(self):
|
|
193
|
+
return try_get("rx", self.token)
|
|
194
|
+
|
|
195
|
+
@property
|
|
196
|
+
def rx_buffer_size(self):
|
|
197
|
+
return try_get("rx_buffer_size", self.token)
|
|
198
|
+
|
|
199
|
+
@rx_buffer_size.setter
|
|
200
|
+
def rx_buffer_size(self, value):
|
|
201
|
+
try_set("rx_buffer_size", value, self.token)
|
|
202
|
+
|
|
203
|
+
#endregion
|
|
204
|
+
|
|
205
|
+
#region tx_def
|
|
206
|
+
|
|
207
|
+
def tx(self, value):
|
|
208
|
+
return try_call_1_arg("tx", value, self.token)
|
|
209
|
+
|
|
210
|
+
# @tx.setter
|
|
211
|
+
# def tx(self, value):
|
|
212
|
+
# try_set("tx", value, self.token)
|
|
213
|
+
|
|
214
|
+
#endregion
|
|
215
|
+
|
|
216
|
+
#region tx
|
|
217
|
+
|
|
218
|
+
#endregion
|
|
219
|
+
|
|
220
|
+
#region _dec_int_fpga_filter
|
|
221
|
+
|
|
222
|
+
"""Decimator and interpolator fpga filter controls"""
|
|
223
|
+
|
|
224
|
+
def _get_rates(self, dev, output): # ! UNTESTED !
|
|
225
|
+
"""Get the decimation and interpolation rates"""
|
|
226
|
+
return try_get("rates", self.token)
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def rx_dec8_filter_en(self) -> bool: # ! UNTESTED !
|
|
230
|
+
"""rx_dec8_filter_en: Enable decimate by 8 filter in FPGA"""
|
|
231
|
+
return try_get("rx_dec8_filter_en", self.token)
|
|
232
|
+
|
|
233
|
+
@rx_dec8_filter_en.setter
|
|
234
|
+
def rx_dec8_filter_en(self, value: bool): # ! UNTESTED !
|
|
235
|
+
"""rx_dec8_filter_en: Enable decimate by 8 filter in FPGA"""
|
|
236
|
+
return try_set("rx_dec8_filter_en", value, self.token)
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def tx_int8_filter_en(self) -> bool: # ! UNTESTED !
|
|
240
|
+
"""tx_int8_filter_en: Enable interpolate by 8 filter in FPGA"""
|
|
241
|
+
return try_get("tx_int8_filter_en", self.token)
|
|
242
|
+
|
|
243
|
+
@tx_int8_filter_en.setter
|
|
244
|
+
def tx_int8_filter_en(self, value: bool): # ! UNTESTED !
|
|
245
|
+
"""tx_int8_filter_en: Enable interpolate by 8 filter in FPGA"""
|
|
246
|
+
return try_set("tx_int8_filter_en", value, self.token)
|
|
247
|
+
|
|
248
|
+
#endregion
|
|
249
|
+
|