Skip to content

Commit

Permalink
init commit with skfs using grpc to sign changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ccall48 committed Dec 3, 2023
1 parent 673619f commit 08d1138
Show file tree
Hide file tree
Showing 4 changed files with 396 additions and 92 deletions.
156 changes: 77 additions & 79 deletions app/ChirpHeliumKeys.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@
import grpc
from google.protobuf.json_format import MessageToDict
from chirpstack_api import api
import logging


class ChirpDeviceKeys:
def __init__(
self,
route_id: str,
postgres_host: str,
postgres_user: str,
postgres_pass: str,
postgres_name: str,
postgres_port: str,
postgres_ssl_mode: str,
chirpstack_host: str,
chirpstack_token: str,
self,
route_id: str,
postgres_host: str,
postgres_user: str,
postgres_pass: str,
postgres_name: str,
postgres_port: str,
postgres_ssl_mode: str,
chirpstack_host: str,
chirpstack_token: str,
):
self.route_id = route_id
self.pg_host = postgres_host
Expand All @@ -27,13 +28,13 @@ def __init__(
self.pg_name = postgres_name
self.pg_port = postgres_port
self.pg_ssl_mode = postgres_ssl_mode
conn_str = f'postgresql://{self.pg_user}:{self.pg_pass}@{self.pg_host}:{self.pg_port}/{self.pg_name}'
if self.pg_ssl_mode[0] != 'require':
conn_str = f"postgresql://{self.pg_user}:{self.pg_pass}@{self.pg_host}:{self.pg_port}/{self.pg_name}"
if self.pg_ssl_mode[0] != "require":
self.postgres = conn_str
else:
self.postgres = '%s?sslmode=%s' % (conn_str, self.pg_ssl_mode)
self.postgres = "%s?sslmode=%s" % (conn_str, self.pg_ssl_mode)
self.cs_gprc = chirpstack_host
self.auth_token = [('authorization', f'Bearer {chirpstack_token}')]
self.auth_token = [("authorization", f"Bearer {chirpstack_token}")]

def config_service_cli(self, cmd: str):
p = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE)
Expand All @@ -57,15 +58,15 @@ def fetch_all_devices(self) -> list[str]:
with psycopg2.connect(self.postgres) as con:
with con.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
cur.execute("SELECT dev_eui FROM device WHERE is_disabled=false;")
return [dev['dev_eui'].hex() for dev in cur.fetchall()]
return [dev["dev_eui"].hex() for dev in cur.fetchall()]

def get_device(self, dev_eui: str) -> dict[str]:
with grpc.insecure_channel(self.cs_gprc) as channel:
client = api.DeviceServiceStub(channel)
req = api.GetDeviceRequest()
req.dev_eui = dev_eui
resp = client.Get(req, metadata=self.auth_token)
data = MessageToDict(resp)['device']
data = MessageToDict(resp)["device"]
return data

def get_device_activation(self, dev_eui: str) -> dict[str]:
Expand All @@ -76,27 +77,27 @@ def get_device_activation(self, dev_eui: str) -> dict[str]:
resp = client.GetActivation(req, metadata=self.auth_token)
data = MessageToDict(resp)
if bool(data):
return data['deviceActivation']
return data["deviceActivation"]
return data

def get_merged_keys(self, dev_eui: str) -> dict[str]:
devices = {
'devAddr': '',
'appSKey': '',
'nwkSEncKey': '',
'name': '',
"devAddr": "",
"appSKey": "",
"nwkSEncKey": "",
"name": "",
}

devices.update(self.get_device(dev_eui))
devices.update(self.get_device_activation(dev_eui))

max_copies = 0
if devices.get('variables') and 'max_copies' in devices.get('variables'):
max_copies = devices['variables']['max_copies']
if 'fCntUp' not in devices.keys():
devices['fCntUp'] = 0
if 'nFCntDown' not in devices.keys():
devices['nFCntDown'] = 0
if devices.get("variables") and "max_copies" in devices.get("variables"):
max_copies = devices["variables"]["max_copies"]
if "fCntUp" not in devices.keys():
devices["fCntUp"] = 0
if "nFCntDown" not in devices.keys():
devices["nFCntDown"] = 0

query = """
INSERT INTO helium_devices
Expand All @@ -111,18 +112,19 @@ def get_merged_keys(self, dev_eui: str) -> dict[str]:
dev_name = '{6}',
fcnt_up = '{7}',
fcnt_down = '{8}';
""".format(devices['devEui'],
devices['joinEui'],
devices['devAddr'],
max_copies,
devices['appSKey'],
devices['nwkSEncKey'],
devices['name'],
devices['fCntUp'],
devices['nFCntDown']
)
""".format(
devices["devEui"],
devices["joinEui"],
devices["devAddr"],
max_copies,
devices["appSKey"],
devices["nwkSEncKey"],
devices["name"],
devices["fCntUp"],
devices["nFCntDown"],
)
self.db_transaction(query)
return f'Updated: {dev_eui}'
return f"Updated: {dev_eui}"

def helium_skfs_update(self):
"""
Expand All @@ -137,46 +139,42 @@ def helium_skfs_update(self):
"""
all_helium_devices = self.db_fetch(helium_devices)

cmd = f'hpr route skfs list --route-id {self.route_id}'
cmd = f"hpr route skfs list --route-id {self.route_id}"
skfs_list = ujson.loads(self.config_service_cli(cmd))

for device in skfs_list:
dev_addr = device['devaddr']
nws_key = device['session_key']
max_copies = device['max_copies']
print(dev_addr, nws_key, max_copies)
if any(x['dev_addr'] == dev_addr and
x['nws_key'] == nws_key and
x['max_copies'] == max_copies
for x in all_helium_devices
):
# print(f'DEVICE CURRENT -> d {dev_addr} -> s {nws_key} -> m {max_copies} Skipping...')
continue

else:
remove_skfs = f'hpr route skfs remove -r {self.route_id} -d {dev_addr} -s {nws_key} -c'
print(remove_skfs)
#print(f'DEVICE STALE REMOVING -> d {dev_addr} -> s {nws_key} -> m {max_copies}')
self.config_service_cli(remove_skfs)

for devices in all_helium_devices:
dev_addr = devices['dev_addr']
nws_key = devices['nws_key']
max_copies = devices['max_copies']
print(dev_addr, nws_key, max_copies)
if any(x['devaddr'] == dev_addr and
x['session_key'] == nws_key and
x['max_copies'] == max_copies
for x in skfs_list
):
# print(f'DEVICE CURRENT -> d {dev_addr} -> s {nws_key} -> m {max_copies} Skipping...')
continue

remove_skfs = f'hpr route skfs remove -r {self.route_id} -d {dev_addr} -s {nws_key} -c'
print(remove_skfs)
# print(f'DEVICE NOT FOUND -> {remove_skfs}')
self.config_service_cli(remove_skfs)

add_skfs = f'hpr route skfs add -r {self.route_id} -d {dev_addr} -s {nws_key} -m {max_copies} -c'
print(f'ADDING DEVICE -> {add_skfs}')
self.config_service_cli(add_skfs)
logging.info(f"SKFS List: {skfs_list}")
logging.info(f"All Helium Devices: {all_helium_devices}")

# Convert the lists to sets for efficient set operations
all_helium_devices_set = {
(d["dev_addr"], d["nws_key"], d["max_copies"]) for d in all_helium_devices
}

skfs_list_set = {
(d["devaddr"], d["session_key"], d["max_copies"]) for d in skfs_list
}

logging.info(f"SKFS List Set: {skfs_list_set}")
logging.info(f"All Helium Devices Set: {all_helium_devices_set}")

# Devices to remove from skfs_list
devices_to_remove = skfs_list_set - all_helium_devices_set
# Devices to add to skfs_list
devices_to_add = all_helium_devices_set - skfs_list_set

logging.info(f"Devices_to_remove: {devices_to_remove}")
logging.info(f"Devices_to_add: {devices_to_add}")

for device in devices_to_remove:
dev_addr, nws_key, max_copies = device
cmd = f"hpr route skfs remove -r {self.route_id} -d {dev_addr} -s {nws_key} -c"
logging.info(f"Removing_skfs: {cmd}")
self.config_service_cli(cmd)

for device in devices_to_add:
dev_addr, nws_key, max_copies = device
cmd = f"hpr route skfs add -r {self.route_id} -d {dev_addr} -s {nws_key} -m {max_copies} -c"
logging.info(f"Adding_skfs: {cmd}")
self.config_service_cli(cmd)

return "Updated SKFS"
Loading

0 comments on commit 08d1138

Please sign in to comment.