diff --git a/scripts/apn_set.py b/scripts/apn_set.py index 9e2672c..125c801 100755 --- a/scripts/apn_set.py +++ b/scripts/apn_set.py @@ -7,8 +7,8 @@ from rich.status import Status from rich.table import Table -import infuse_iot.generated.kv_definitions as kv -import infuse_iot.generated.rpc_definitions as rpc +import infuse_iot.definitions.kv as kv +import infuse_iot.definitions.rpc as rpc from infuse_iot.definitions.tdf import readings from infuse_iot.epacket.packet import Auth from infuse_iot.rpc_client import RpcClient diff --git a/scripts/reboot_count_reset.py b/scripts/reboot_count_reset.py index f091ae8..a6700b3 100755 --- a/scripts/reboot_count_reset.py +++ b/scripts/reboot_count_reset.py @@ -6,8 +6,8 @@ from rich.status import Status from rich.table import Table -import infuse_iot.generated.kv_definitions as kv -import infuse_iot.generated.rpc_definitions as rpc +import infuse_iot.definitions.kv as kv +import infuse_iot.definitions.rpc as rpc from infuse_iot.definitions.tdf import readings from infuse_iot.epacket.packet import Auth from infuse_iot.rpc_client import RpcClient diff --git a/src/infuse_iot/credentials.py b/src/infuse_iot/credentials.py index 1268e60..5ce12a8 100644 --- a/src/infuse_iot/credentials.py +++ b/src/infuse_iot/credentials.py @@ -20,6 +20,7 @@ def get_api_key() -> str: raise FileNotFoundError("API key does not exist in keyring") return key + def delete_api_key() -> None: """ Delete the Infuse-IoT API key from the keyring module @@ -65,3 +66,24 @@ def delete_custom_tool_path() -> None: Delete the location of custom Infuse-IoT tools on the filesystem """ return keyring.delete_password("infuse-iot", "custom-tools") + + +def set_custom_definitions_path(path: str): + """ + Save the location of custom Infuse-IoT definitions on the filesystem + """ + keyring.set_password("infuse-iot", "custom-definitions", path) + + +def get_custom_definitions_path() -> str | None: + """ + Retrieve the location of custom Infuse-IoT definitions on the filesystem + """ + return keyring.get_password("infuse-iot", "custom-definitions") + + +def delete_custom_definitions_path() -> None: + """ + Delete the location of custom Infuse-IoT definitions on the filesystem + """ + return keyring.delete_password("infuse-iot", "custom-definitions") diff --git a/src/infuse_iot/definitions/kv.py b/src/infuse_iot/definitions/kv.py index dd8c5a5..31aa372 100644 --- a/src/infuse_iot/definitions/kv.py +++ b/src/infuse_iot/definitions/kv.py @@ -1,3 +1,21 @@ #!/usr/bin/env python3 -from infuse_iot.generated.kv_definitions import slots, structs # noqa: F401 +import infuse_iot.generated.kv_definitions as _kv_base +from infuse_iot.util.internal import extension_load as _loader + +if extension_module := _loader("kv_definitions"): + + class slots(_kv_base.slots, extension_module.slots): # type: ignore + pass + + class structs(_kv_base.structs, extension_module.structs): # type: ignore + pass + +else: + slots = _kv_base.slots # type: ignore + structs = _kv_base.structs # type: ignore + +__all__ = [ + "slots", + "structs", +] diff --git a/src/infuse_iot/definitions/rpc.py b/src/infuse_iot/definitions/rpc.py index ebf9915..9657c1d 100644 --- a/src/infuse_iot/definitions/rpc.py +++ b/src/infuse_iot/definitions/rpc.py @@ -1,3 +1,9 @@ #!/usr/bin/env python3 from infuse_iot.generated.rpc_definitions import * # noqa: F403 +from infuse_iot.util.internal import extension_load as _loader + +if _extension_module := _loader("rpc_definitions"): + _globals = globals() + for _name in _extension_module.__all__: + _globals[_name] = getattr(_extension_module, _name) diff --git a/src/infuse_iot/definitions/tdf.py b/src/infuse_iot/definitions/tdf.py index eba50f5..0acb118 100644 --- a/src/infuse_iot/definitions/tdf.py +++ b/src/infuse_iot/definitions/tdf.py @@ -1,3 +1,27 @@ #!/usr/bin/env python3 -from infuse_iot.generated.tdf_definitions import id_type_mapping, readings, structs # noqa: F401 +import infuse_iot.generated.tdf_definitions as _tdf_base +from infuse_iot.util.internal import extension_load as _loader + +if _extension_module := _loader("tdf_definitions"): + id_type_mapping = { + **_tdf_base.id_type_mapping, + **_extension_module.id_type_mapping, + } + + class readings(_tdf_base.readings, _extension_module.readings): # type: ignore + pass + + class structs(_tdf_base.structs, _extension_module.structs): # type: ignore + pass +else: + id_type_mapping = _tdf_base.id_type_mapping + readings = _tdf_base.readings # type: ignore + structs = _tdf_base.structs # type: ignore + + +__all__ = [ + "id_type_mapping", + "readings", + "structs", +] diff --git a/src/infuse_iot/epacket/interface.py b/src/infuse_iot/epacket/interface.py index f178195..8a083e8 100644 --- a/src/infuse_iot/epacket/interface.py +++ b/src/infuse_iot/epacket/interface.py @@ -5,8 +5,8 @@ from typing_extensions import Self -import infuse_iot.generated.rpc_definitions as rpc_defs -import infuse_iot.generated.tdf_definitions as tdf_defs +import infuse_iot.definitions.rpc as rpc_defs +import infuse_iot.definitions.tdf as tdf_defs from infuse_iot.epacket.common import Serializable from infuse_iot.util.ctypes import bytes_to_uint8 diff --git a/src/infuse_iot/generated/kv_definitions.py b/src/infuse_iot/generated/kv_definitions.py index 1636ff0..86af714 100644 --- a/src/infuse_iot/generated/kv_definitions.py +++ b/src/infuse_iot/generated/kv_definitions.py @@ -468,3 +468,9 @@ class secure_storage_reserved(VLACompatLittleEndianStruct): 30008: secure_storage_reserved, 30009: secure_storage_reserved, } + + +__all__ = [ + "structs", + "slots", +] diff --git a/src/infuse_iot/generated/rpc_definitions.py b/src/infuse_iot/generated/rpc_definitions.py index 89e303a..3c88040 100644 --- a/src/infuse_iot/generated/rpc_definitions.py +++ b/src/infuse_iot/generated/rpc_definitions.py @@ -993,3 +993,61 @@ class response(VLACompatLittleEndianStruct): _fields_ = [] vla_field = ("array", 0 * ctypes.c_uint8) _pack_ = 1 + + +__all__ = [ + "rpc_struct_mcuboot_img_sem_ver", + "rpc_struct_kv_store_value", + "rpc_struct_kv_store_crc", + "rpc_struct_bt_addr_le", + "rpc_struct_ipv4_address", + "rpc_struct_ipv6_address", + "rpc_struct_network_state", + "rpc_struct_wifi_state", + "rpc_struct_lte_state", + "rpc_struct_wifi_scan_result", + "rpc_struct_xyz_s16", + "rpc_struct_infuse_state", + "rpc_struct_sockaddr", + "rpc_struct_heap_info", + "rpc_enum_bt_le_addr_type", + "rpc_enum_file_action", + "rpc_enum_infuse_bt_characteristic", + "rpc_enum_data_logger", + "rpc_enum_zperf_data_source", + "reboot", + "fault", + "time_get", + "time_set", + "kv_write", + "kv_read", + "kv_reflect_crcs", + "zbus_channel_state", + "application_info", + "wifi_scan", + "wifi_state", + "last_reboot", + "data_logger_state", + "data_logger_read", + "mem_read", + "infuse_states_query", + "infuse_states_update", + "data_logger_erase", + "heap_stats", + "lte_at_cmd", + "lte_state", + "data_logger_read_available", + "coap_download", + "zperf_upload", + "file_write_basic", + "annotate", + "bt_connect_infuse", + "bt_disconnect", + "bt_file_copy_basic", + "bt_file_copy_coap", + "gravity_reference_update", + "security_state", + "data_sender", + "data_receiver", + "echo", +] diff --git a/src/infuse_iot/generated/tdf_definitions.py b/src/infuse_iot/generated/tdf_definitions.py index 0594de3..e713a30 100644 --- a/src/infuse_iot/generated/tdf_definitions.py +++ b/src/infuse_iot/generated/tdf_definitions.py @@ -1487,3 +1487,9 @@ class array_type(TdfReadingBase): 50: readings.wifi_disconnected, 100: readings.array_type, } + +__all__ = [ + "structs", + "readings", + "id_type_mapping", +] diff --git a/src/infuse_iot/rpc_wrappers/application_info.py b/src/infuse_iot/rpc_wrappers/application_info.py index 668f1c3..5298578 100644 --- a/src/infuse_iot/rpc_wrappers/application_info.py +++ b/src/infuse_iot/rpc_wrappers/application_info.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/bt_connect_infuse.py b/src/infuse_iot/rpc_wrappers/bt_connect_infuse.py index 39b2f0e..cb6e74a 100644 --- a/src/infuse_iot/rpc_wrappers/bt_connect_infuse.py +++ b/src/infuse_iot/rpc_wrappers/bt_connect_infuse.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.definitions.rpc import ( rpc_enum_bt_le_addr_type, @@ -11,6 +11,7 @@ from infuse_iot.util.argparse import BtLeAddress from infuse_iot.util.ctypes import bytes_to_uint8 from infuse_iot.zephyr.errno import errno +from infuse_iot.zephyr.hci import error class bt_connect_infuse(InfuseRpcCommand, defs.bt_connect_infuse): @@ -61,11 +62,10 @@ def handle_response(self, return_code, response): if return_code < 0: print(f"Failed to connect ({errno.strerror(-return_code)})") return + elif return_code > 0: + print(f"Failed to connect ({error.strerror(return_code)})") - if return_code == 1: - print("Already connected") - else: - print("Connected") + print("Connected") print(f"\tDevice Public Key: {bytes(response.device_public_key).hex()}") print(f"\t Cloud Public Key: {bytes(response.cloud_public_key).hex()}") print(f"\t Network: 0x{response.network_id:06x}") diff --git a/src/infuse_iot/rpc_wrappers/bt_disconnect.py b/src/infuse_iot/rpc_wrappers/bt_disconnect.py index 4246f52..e644e9b 100644 --- a/src/infuse_iot/rpc_wrappers/bt_disconnect.py +++ b/src/infuse_iot/rpc_wrappers/bt_disconnect.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.definitions.rpc import ( rpc_enum_bt_le_addr_type, diff --git a/src/infuse_iot/rpc_wrappers/bt_file_copy_coap.py b/src/infuse_iot/rpc_wrappers/bt_file_copy_coap.py index f5636c1..2743bee 100644 --- a/src/infuse_iot/rpc_wrappers/bt_file_copy_coap.py +++ b/src/infuse_iot/rpc_wrappers/bt_file_copy_coap.py @@ -2,7 +2,7 @@ import ctypes -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.definitions.rpc import rpc_enum_bt_le_addr_type, rpc_enum_file_action, rpc_struct_bt_addr_le from infuse_iot.rpc_wrappers.coap_download import coap_download, coap_server_file_stats diff --git a/src/infuse_iot/rpc_wrappers/coap_download.py b/src/infuse_iot/rpc_wrappers/coap_download.py index 3b523ee..5f0568e 100644 --- a/src/infuse_iot/rpc_wrappers/coap_download.py +++ b/src/infuse_iot/rpc_wrappers/coap_download.py @@ -5,7 +5,7 @@ from http import HTTPStatus from json import loads -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.api_client import Client from infuse_iot.api_client.api.coap import get_coap_file_stats from infuse_iot.commands import InfuseRpcCommand diff --git a/src/infuse_iot/rpc_wrappers/data_logger_erase.py b/src/infuse_iot/rpc_wrappers/data_logger_erase.py index 36ecc7a..c9e4a79 100644 --- a/src/infuse_iot/rpc_wrappers/data_logger_erase.py +++ b/src/infuse_iot/rpc_wrappers/data_logger_erase.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/data_logger_read.py b/src/infuse_iot/rpc_wrappers/data_logger_read.py index 0cc12f9..6d719eb 100644 --- a/src/infuse_iot/rpc_wrappers/data_logger_read.py +++ b/src/infuse_iot/rpc_wrappers/data_logger_read.py @@ -3,7 +3,7 @@ import binascii import time -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import UINT32_MAX from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/data_logger_state.py b/src/infuse_iot/rpc_wrappers/data_logger_state.py index 9f302ba..9415c01 100644 --- a/src/infuse_iot/rpc_wrappers/data_logger_state.py +++ b/src/infuse_iot/rpc_wrappers/data_logger_state.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.time import humanised_seconds from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/fault.py b/src/infuse_iot/rpc_wrappers/fault.py index 004ae28..0ba940a 100644 --- a/src/infuse_iot/rpc_wrappers/fault.py +++ b/src/infuse_iot/rpc_wrappers/fault.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/file_write_basic.py b/src/infuse_iot/rpc_wrappers/file_write_basic.py index c83d40e..e3abff1 100644 --- a/src/infuse_iot/rpc_wrappers/file_write_basic.py +++ b/src/infuse_iot/rpc_wrappers/file_write_basic.py @@ -8,7 +8,7 @@ TransferSpeedColumn, ) -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import Auth, InfuseRpcCommand from infuse_iot.definitions.rpc import rpc_enum_file_action from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/gravity_reference_update.py b/src/infuse_iot/rpc_wrappers/gravity_reference_update.py index d842c17..46388e6 100644 --- a/src/infuse_iot/rpc_wrappers/gravity_reference_update.py +++ b/src/infuse_iot/rpc_wrappers/gravity_reference_update.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/heap_stats.py b/src/infuse_iot/rpc_wrappers/heap_stats.py index 95a887a..8e4b7f5 100644 --- a/src/infuse_iot/rpc_wrappers/heap_stats.py +++ b/src/infuse_iot/rpc_wrappers/heap_stats.py @@ -2,7 +2,7 @@ import tabulate -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/infuse_states_query.py b/src/infuse_iot/rpc_wrappers/infuse_states_query.py index d9aedb6..ced6fec 100644 --- a/src/infuse_iot/rpc_wrappers/infuse_states_query.py +++ b/src/infuse_iot/rpc_wrappers/infuse_states_query.py @@ -2,7 +2,7 @@ import tabulate -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/infuse_states_update.py b/src/infuse_iot/rpc_wrappers/infuse_states_update.py index 2562735..d6082d7 100644 --- a/src/infuse_iot/rpc_wrappers/infuse_states_update.py +++ b/src/infuse_iot/rpc_wrappers/infuse_states_update.py @@ -2,7 +2,7 @@ import ctypes -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import UINT16_MAX from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/kv_bt_peer.py b/src/infuse_iot/rpc_wrappers/kv_bt_peer.py index af19b25..0f12835 100644 --- a/src/infuse_iot/rpc_wrappers/kv_bt_peer.py +++ b/src/infuse_iot/rpc_wrappers/kv_bt_peer.py @@ -3,7 +3,7 @@ import ctypes import os -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.argparse import BtLeAddress from infuse_iot.util.ctypes import VLACompatLittleEndianStruct, bytes_to_uint8 diff --git a/src/infuse_iot/rpc_wrappers/kv_read.py b/src/infuse_iot/rpc_wrappers/kv_read.py index 0b498f0..6b1b1b6 100644 --- a/src/infuse_iot/rpc_wrappers/kv_read.py +++ b/src/infuse_iot/rpc_wrappers/kv_read.py @@ -5,8 +5,8 @@ from tabulate import tabulate -import infuse_iot.generated.kv_definitions as kv -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.kv as kv +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/kv_reflect_crcs.py b/src/infuse_iot/rpc_wrappers/kv_reflect_crcs.py index 8271272..8cc2542 100644 --- a/src/infuse_iot/rpc_wrappers/kv_reflect_crcs.py +++ b/src/infuse_iot/rpc_wrappers/kv_reflect_crcs.py @@ -2,7 +2,7 @@ import ctypes -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import VLACompatLittleEndianStruct from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/kv_write.py b/src/infuse_iot/rpc_wrappers/kv_write.py index 2b39a4c..4bb0714 100644 --- a/src/infuse_iot/rpc_wrappers/kv_write.py +++ b/src/infuse_iot/rpc_wrappers/kv_write.py @@ -4,8 +4,8 @@ import os import sys -import infuse_iot.generated.kv_definitions as kv_defs -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.kv as kv_defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import VLACompatLittleEndianStruct, bytes_to_uint8 from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/last_reboot.py b/src/infuse_iot/rpc_wrappers/last_reboot.py index 6c8fb88..5bc0f62 100644 --- a/src/infuse_iot/rpc_wrappers/last_reboot.py +++ b/src/infuse_iot/rpc_wrappers/last_reboot.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/lte_at_cmd.py b/src/infuse_iot/rpc_wrappers/lte_at_cmd.py index c60b61c..73b6597 100644 --- a/src/infuse_iot/rpc_wrappers/lte_at_cmd.py +++ b/src/infuse_iot/rpc_wrappers/lte_at_cmd.py @@ -2,7 +2,7 @@ import ctypes -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import VLACompatLittleEndianStruct from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/lte_pdp_ctx.py b/src/infuse_iot/rpc_wrappers/lte_pdp_ctx.py index ae931ce..1d3548c 100644 --- a/src/infuse_iot/rpc_wrappers/lte_pdp_ctx.py +++ b/src/infuse_iot/rpc_wrappers/lte_pdp_ctx.py @@ -3,7 +3,7 @@ import ctypes import enum -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import VLACompatLittleEndianStruct from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/lte_state.py b/src/infuse_iot/rpc_wrappers/lte_state.py index 6882761..db9384d 100644 --- a/src/infuse_iot/rpc_wrappers/lte_state.py +++ b/src/infuse_iot/rpc_wrappers/lte_state.py @@ -3,7 +3,7 @@ import ctypes import ipaddress -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr import lte as z_lte from infuse_iot.zephyr import net_if as z_nif diff --git a/src/infuse_iot/rpc_wrappers/reboot.py b/src/infuse_iot/rpc_wrappers/reboot.py index fdc9962..4796313 100644 --- a/src/infuse_iot/rpc_wrappers/reboot.py +++ b/src/infuse_iot/rpc_wrappers/reboot.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/security_state.py b/src/infuse_iot/rpc_wrappers/security_state.py index 104f19d..7628c5b 100644 --- a/src/infuse_iot/rpc_wrappers/security_state.py +++ b/src/infuse_iot/rpc_wrappers/security_state.py @@ -8,7 +8,7 @@ from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 from cryptography.hazmat.primitives.kdf.hkdf import HKDF -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.epacket.packet import Auth from infuse_iot.util.argparse import ValidFile diff --git a/src/infuse_iot/rpc_wrappers/sym_read.py b/src/infuse_iot/rpc_wrappers/sym_read.py index dca2d65..36f5983 100644 --- a/src/infuse_iot/rpc_wrappers/sym_read.py +++ b/src/infuse_iot/rpc_wrappers/sym_read.py @@ -7,7 +7,7 @@ from elftools.dwarf.die import DIE from elftools.elf.elffile import ELFFile -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util import console, elftools from infuse_iot.util.argparse import ValidFile diff --git a/src/infuse_iot/rpc_wrappers/time_get.py b/src/infuse_iot/rpc_wrappers/time_get.py index cad7da1..6a04e89 100644 --- a/src/infuse_iot/rpc_wrappers/time_get.py +++ b/src/infuse_iot/rpc_wrappers/time_get.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/time_set.py b/src/infuse_iot/rpc_wrappers/time_set.py index 845abdd..c048f19 100644 --- a/src/infuse_iot/rpc_wrappers/time_set.py +++ b/src/infuse_iot/rpc_wrappers/time_set.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/wifi_configure.py b/src/infuse_iot/rpc_wrappers/wifi_configure.py index fd35bff..60bacba 100644 --- a/src/infuse_iot/rpc_wrappers/wifi_configure.py +++ b/src/infuse_iot/rpc_wrappers/wifi_configure.py @@ -2,7 +2,7 @@ import ctypes -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs import infuse_iot.zephyr.wifi as wifi from infuse_iot.commands import InfuseRpcCommand from infuse_iot.util.ctypes import UINT8_MAX, VLACompatLittleEndianStruct, bytes_to_uint8 diff --git a/src/infuse_iot/rpc_wrappers/wifi_scan.py b/src/infuse_iot/rpc_wrappers/wifi_scan.py index 0b151f9..7d28507 100644 --- a/src/infuse_iot/rpc_wrappers/wifi_scan.py +++ b/src/infuse_iot/rpc_wrappers/wifi_scan.py @@ -4,7 +4,7 @@ import tabulate -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr import wifi as z_wifi from infuse_iot.zephyr.errno import errno diff --git a/src/infuse_iot/rpc_wrappers/wifi_state.py b/src/infuse_iot/rpc_wrappers/wifi_state.py index 7182c6f..c974d95 100644 --- a/src/infuse_iot/rpc_wrappers/wifi_state.py +++ b/src/infuse_iot/rpc_wrappers/wifi_state.py @@ -3,7 +3,7 @@ import ctypes import ipaddress -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr import net_if as z_nif from infuse_iot.zephyr import wifi as z_wifi diff --git a/src/infuse_iot/rpc_wrappers/zbus_channel_state.py b/src/infuse_iot/rpc_wrappers/zbus_channel_state.py index 34303c3..dec321f 100644 --- a/src/infuse_iot/rpc_wrappers/zbus_channel_state.py +++ b/src/infuse_iot/rpc_wrappers/zbus_channel_state.py @@ -4,9 +4,9 @@ import tabulate -import infuse_iot.generated.rpc_definitions as rpc_defs from infuse_iot.commands import InfuseRpcCommand -from infuse_iot.tdf import tdf_definitions as defs +from infuse_iot.definitions import rpc as rpc_defs +from infuse_iot.definitions import tdf as tdf_defs from infuse_iot.util.ctypes import VLACompatLittleEndianStruct from infuse_iot.zephyr.errno import errno @@ -22,11 +22,11 @@ class response(VLACompatLittleEndianStruct): class BatteryChannel: id = 0x43210000 - data = defs.readings.battery_state + data = tdf_defs.readings.battery_state class AmbeintEnvChannel(ctypes.LittleEndianStructure): id = 0x43210001 - data = defs.readings.ambient_temp_pres_hum + data = tdf_defs.readings.ambient_temp_pres_hum class ImuChannel(ctypes.LittleEndianStructure): id = 0x43210002 @@ -38,15 +38,15 @@ class AccMagChannel(ctypes.LittleEndianStructure): class LocationChannel(ctypes.LittleEndianStructure): id = 0x43210004 - data = defs.readings.gcs_wgs84_llha + data = tdf_defs.readings.gcs_wgs84_llha class NavPvtUbxChannel(ctypes.LittleEndianStructure): id = 0x43210007 - data = defs.readings.ubx_nav_pvt + data = tdf_defs.readings.ubx_nav_pvt class NavPvtNRFChannel(ctypes.LittleEndianStructure): id = 0x43210008 - data = defs.readings.nrf9x_gnss_pvt + data = tdf_defs.readings.nrf9x_gnss_pvt @classmethod def add_parser(cls, parser): diff --git a/src/infuse_iot/rpc_wrappers/zperf_upload.py b/src/infuse_iot/rpc_wrappers/zperf_upload.py index d2f4ffb..af74eb6 100644 --- a/src/infuse_iot/rpc_wrappers/zperf_upload.py +++ b/src/infuse_iot/rpc_wrappers/zperf_upload.py @@ -6,7 +6,7 @@ import tabulate -import infuse_iot.generated.rpc_definitions as defs +import infuse_iot.definitions.rpc as defs from infuse_iot.commands import InfuseRpcCommand from infuse_iot.zephyr.errno import errno from infuse_iot.zephyr.net import AddressFamily, SockType diff --git a/src/infuse_iot/tdf.py b/src/infuse_iot/tdf.py index fc5c109..1e89d2d 100644 --- a/src/infuse_iot/tdf.py +++ b/src/infuse_iot/tdf.py @@ -6,7 +6,8 @@ import time from collections.abc import Generator -from infuse_iot.generated import tdf_base, tdf_definitions +from infuse_iot.definitions import tdf as tdf_defs +from infuse_iot.generated import tdf_base from infuse_iot.time import InfuseTime @@ -157,7 +158,7 @@ def decode(self, buffer: bytes, no_defs: bool = False) -> Generator[Reading, Non id_type = unknown_tdf_factory(tdf_id, header.len) else: try: - id_type = tdf_definitions.id_type_mapping[tdf_id] + id_type = tdf_defs.id_type_mapping[tdf_id] except KeyError: id_type = unknown_tdf_factory(tdf_id, header.len) diff --git a/src/infuse_iot/tools/credentials.py b/src/infuse_iot/tools/credentials.py index b688259..189d9e9 100644 --- a/src/infuse_iot/tools/credentials.py +++ b/src/infuse_iot/tools/credentials.py @@ -23,6 +23,7 @@ def add_parser(cls, parser): parser.add_argument("--api-key-print", action="store_true", help="Print Infuse-IoT API key") parser.add_argument("--network", type=ValidFile, help="Load network credentials from file") parser.add_argument("--custom-tools", type=ValidDir, help="Location of custom tools") + parser.add_argument("--custom-definitions", type=ValidDir, help="Location of custom definitions") def __init__(self, args): self.args = args @@ -44,3 +45,5 @@ def run(self): credentials.save_network(network_info["id"], content) if self.args.custom_tools: credentials.set_custom_tool_path(str(self.args.custom_tools.absolute())) + if self.args.custom_definitions: + credentials.set_custom_definitions_path(str(self.args.custom_definitions.absolute())) diff --git a/src/infuse_iot/tools/gateway.py b/src/infuse_iot/tools/gateway.py index 3910b3c..1d24d4f 100644 --- a/src/infuse_iot/tools/gateway.py +++ b/src/infuse_iot/tools/gateway.py @@ -19,9 +19,9 @@ import cryptography import cryptography.exceptions +import infuse_iot.definitions.rpc as defs +import infuse_iot.definitions.tdf as tdf_defs import infuse_iot.epacket.interface as interface -import infuse_iot.generated.rpc_definitions as defs -import infuse_iot.generated.tdf_definitions as tdf_defs from infuse_iot import rpc, tdf from infuse_iot.commands import InfuseCommand from infuse_iot.common import InfuseID, InfuseType diff --git a/src/infuse_iot/util/internal.py b/src/infuse_iot/util/internal.py new file mode 100644 index 0000000..7fa4aa2 --- /dev/null +++ b/src/infuse_iot/util/internal.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +import importlib +import os +import pathlib +import types + +import infuse_iot.credentials + + +def extension_load(name: str) -> None | types.ModuleType: + if os.environ.get("_ARGCOMPLETE") == "1": + # Skip expensive imports when running argcomplete + return None + + defs_path = infuse_iot.credentials.get_custom_definitions_path() + if defs_path is None: + return None + tdf_extensions = pathlib.Path(defs_path) / f"{name}.py" + if not tdf_extensions.exists(): + return None + + try: + # Import the extension file + spec = importlib.util.spec_from_file_location(f"infuse_iot.extension.{name}", str(tdf_extensions)) + if spec is None or spec.loader is None: + return None + file_module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(file_module) + except Exception as _: + return None + + # Return the loaded file + return file_module diff --git a/src/infuse_iot/zephyr/hci.py b/src/infuse_iot/zephyr/hci.py new file mode 100644 index 0000000..4e3ae68 --- /dev/null +++ b/src/infuse_iot/zephyr/hci.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 + +import enum + + +class error(enum.IntEnum): + """Error codes exported from Zephyr `hci_types.h`""" + + SUCCESS = (0x00, "Success") + UNKNOWN_CMD = (0x01, "UNKNOWN HCI COMMAND") + UNKNOWN_CONN_ID = (0x02, "UNKNOWN CONNECTION IDENTIFIER") + HW_FAILURE = (0x03, "HARDWARE FAILURE") + PAGE_TIMEOUT = (0x04, "PAGE TIMEOUT") + AUTH_FAIL = (0x05, "AUTHENTICATION FAILURE") + PIN_OR_KEY_MISSING = (0x06, "PIN OR KEY MISSING") + MEM_CAPACITY_EXCEEDED = (0x07, "MEMORY CAPACITY EXCEEDED") + CONN_TIMEOUT = (0x08, "CONNECTION TIMEOUT") + CONN_LIMIT_EXCEEDED = (0x09, "CONNECTION LIMIT EXCEEDED") + SYNC_CONN_LIMIT_EXCEEDED = (0x0A, "SYNCHRONOUS CONNECTION LIMIT TO A DEVICE EXCEEDED") + CONN_ALREADY_EXISTS = (0x0B, "CONNECTION ALREADY EXISTS") + CMD_DISALLOWED = (0x0C, "COMMAND DISALLOWED") + INSUFFICIENT_RESOURCES = (0x0D, "CONNECTION REJECTED DUE TO LIMITED RESOURCES") + INSUFFICIENT_SECURITY = (0x0E, "CONNECTION REJECTED DUE TO SECURITY REASONS") + BD_ADDR_UNACCEPTABLE = (0x0F, "CONNECTION REJECTED DUE TO UNACCEPTABLE BD_ADDR") + CONN_ACCEPT_TIMEOUT = (0x10, "CONNECTION ACCEPT TIMEOUT EXCEEDED") + UNSUPP_FEATURE_PARAM_VAL = (0x11, "UNSUPPORTED FEATURE OR PARAMETER VALUE") + INVALID_PARAM = (0x12, "INVALID HCI COMMAND PARAMETERS") + REMOTE_USER_TERM_CONN = (0x13, "REMOTE USER TERMINATED CONNECTION") + REMOTE_LOW_RESOURCES = (0x14, "REMOTE DEVICE TERMINATED CONNECTION DUE TO LOW RESOURCES") + REMOTE_POWER_OFF = (0x15, "REMOTE DEVICE TERMINATED CONNECTION DUE TO POWER OFF") + LOCALHOST_TERM_CONN = (0x16, "CONNECTION TERMINATED BY LOCAL HOST") + REPEATED_ATTEMPTS = (0x17, "REPEATED ATTEMPTS") + PAIRING_NOT_ALLOWED = (0x18, "PAIRING NOT ALLOWED") + UNKNOWN_LMP_PDU = (0x19, "UNKNOWN LMP PDU") + UNSUPP_REMOTE_FEATURE = (0x1A, "UNSUPPORTED REMOTE FEATURE") + SCO_OFFSET_REJECTED = (0x1B, "SCO OFFSET REJECTED") + SCO_INTERVAL_REJECTED = (0x1C, "SCO INTERVAL REJECTED") + SCO_AIR_MODE_REJECTED = (0x1D, "SCO AIR MODE REJECTED") + INVALID_LL_PARAM = (0x1E, "INVALID LL PARAMETERS") + UNSPECIFIED = (0x1F, "UNSPECIFIED ERROR") + UNSUPP_LL_PARAM_VAL = (0x20, "UNSUPPORTED LL PARAMETER VALUE") + ROLE_CHANGE_NOT_ALLOWED = (0x21, "ROLE CHANGE NOT ALLOWED") + LL_RESP_TIMEOUT = (0x22, "LL RESPONSE TIMEOUT") + LL_PROC_COLLISION = (0x23, "LL PROCEDURE COLLISION") + LMP_PDU_NOT_ALLOWED = (0x24, "LMP PDU NOT ALLOWED") + ENC_MODE_NOT_ACCEPTABLE = (0x25, "ENCRYPTION MODE NOT ACCEPTABLE") + LINK_KEY_CANNOT_BE_CHANGED = (0x26, "LINK KEY CANNOT BE CHANGED") + REQUESTED_QOS_NOT_SUPPORTED = (0x27, "REQUESTED QoS NOT SUPPORTED") + INSTANT_PASSED = (0x28, "INSTANT PASSED") + PAIRING_NOT_SUPPORTED = (0x29, "PAIRING WITH UNIT KEY NOT SUPPORTED") + DIFF_TRANS_COLLISION = (0x2A, "DIFFERENT TRANSACTION COLLISION") + QOS_UNACCEPTABLE_PARAM = (0x2C, "QoS UNACCEPTABLE PARAMETER") + QOS_REJECTED = (0x2D, "QoS REJECTED") + CHAN_ASSESS_NOT_SUPPORTED = (0x2E, "CHANNEL ASSESSMENT NOT SUPPORTED") + INSUFF_SECURITY = (0x2F, "INSUFFICIENT SECURITY") + PARAM_OUT_OF_MANDATORY_RANGE = (0x30, "PARAMETER OUT OF MANDATORY RANGE") + ROLE_SWITCH_PENDING = (0x32, "ROLE SWITCH PENDING") + RESERVED_SLOT_VIOLATION = (0x34, "RESERVED SLOT VIOLATION") + ROLE_SWITCH_FAILED = (0x35, "ROLE SWITCH FAILED") + EXT_INQ_RESP_TOO_LARGE = (0x36, "EXTENDED INQUIRY RESPONSE TOO LARGE") + SIMPLE_PAIR_NOT_SUPP_BY_HOST = (0x37, "SECURE SIMPLE PAIRING NOT SUPPORTED BY HOST") + HOST_BUSY_PAIRING = (0x38, "HOST BUSY–PAIRING") + CONN_REJECTED_DUE_TO_NO_CHAN = (0x39, "CONNECTION REJECTED DUE TO NO SUITABLE CHANNEL FOUND") + CONTROLLER_BUSY = (0x3A, "CONTROLLER BUSY") + UNACCEPT_CONN_PARAM = (0x3B, "UNACCEPTABLE CONNECTION PARAMETERS") + ADV_TIMEOUT = (0x3C, "ADVERTISING TIMEOUT") + TERM_DUE_TO_MIC_FAIL = (0x3D, "CONNECTION TERMINATED DUE TO MIC FAILURE") + CONN_FAIL_TO_ESTAB = (0x3E, "CONNECTION FAILED TO BE ESTABLISHED") + MAC_CONN_FAILED = (0x3F, "LEGACY ERROR") + CLOCK_ADJUST_REJECTED = (0x40, "COARSE CLOCK ADJUSTMENT REJECTED") + SUBMAP_NOT_DEFINED = (0x41, "TYPE0 SUBMAP NOT DEFINED") + UNKNOWN_ADV_IDENTIFIER = (0x42, "UNKNOWN ADVERTISING IDENTIFIER") + LIMIT_REACHED = (0x43, "LIMIT REACHED") + OP_CANCELLED_BY_HOST = (0x44, "OPERATION CANCELLED BY HOST") + PACKET_TOO_LONG = (0x45, "PACKET TOO LONG") + TOO_LATE = (0x46, "TOO LATE") + TOO_EARLY = (0x47, "TOO EARLY") + + description: str + + def __new__(cls, value: int, description: str = ""): + obj = int.__new__(cls, value) + obj._value_ = value + obj.description = description + return obj + + @classmethod + def strerror(cls, int) -> str: + return cls(int).description