802 lines
21 KiB
Python
802 lines
21 KiB
Python
from enum import IntEnum, unique
|
||
from typing import Optional, Dict, TypeVar, overload, Callable
|
||
|
||
from biopro.util.address import address_str
|
||
from ._type import *
|
||
|
||
T = TypeVar('T')
|
||
|
||
|
||
@unique
|
||
class ErrorCode(IntEnum):
|
||
SUCCESS = 0x00
|
||
FAILURE = 0x01
|
||
INVALID_PARAMETER = 0x02
|
||
INVALID_TASK = 0x03
|
||
MSG_BUFFER_NOT_AVAIL = 0x04
|
||
INVALID_MSG_POINTER = 0x05
|
||
INVALID_EVENT_ID = 0x06
|
||
INVALID_INTERRUPT_ID = 0x07
|
||
NO_TIMER_AVAIL = 0x08
|
||
NV_ITEM_UNINIT = 0x09
|
||
NV_OPER_FAILED = 0x0A
|
||
INVALID_MEM_SIZE = 0x0B
|
||
NV_BAD_ITEM_LEN = 0x0C
|
||
|
||
#######
|
||
# BLE #
|
||
#######
|
||
|
||
NotReady = 0x10
|
||
"""Not ready to perform task"""
|
||
AlreadyInRequestedMode = 0x11
|
||
"""Already performing that task"""
|
||
IncorrectMode = 0x12
|
||
"""Not setup properly to perform that task"""
|
||
MemAllocError = 0x13
|
||
"""Memory allocation error occurred"""
|
||
NotConnected = 0x14
|
||
"""Can't perform function when not in a connection"""
|
||
NoResources = 0x15
|
||
"""There are no resource available"""
|
||
Pending = 0x16
|
||
"""Waiting"""
|
||
Timeout = 0x17
|
||
"""Timed out performing function"""
|
||
InvalidRange = 0x18
|
||
"""A parameter is out of range"""
|
||
LinkEncrypted = 0x19
|
||
"""The link is already encrypted"""
|
||
ProcedureComplete = 0x1A
|
||
"""The Procedure is completed"""
|
||
|
||
UnspecifiedError = 0x1F
|
||
|
||
############################
|
||
# GAP Status Return Values #
|
||
############################
|
||
|
||
GAPUserCanceled = 0x30
|
||
"""The user canceled the task"""
|
||
GAPConnNotAcceptable = 0x31
|
||
"""The connection was not accepted"""
|
||
GAPBondRejected = 0x32
|
||
"""The bound information was rejected."""
|
||
|
||
############################
|
||
# ATT Status Return Values #
|
||
############################
|
||
|
||
InvalidPDU = 0x40
|
||
"""The attribute PDU is invalid"""
|
||
InsufficientAuthentication = 0x41
|
||
"""The attribute has insufficient authentication"""
|
||
InsufficientEncrypt = 0x42
|
||
"""The attribute has insufficient encryption"""
|
||
InsufficientKeySize = 0x43
|
||
"""The attribute has insufficient encryption key size"""
|
||
|
||
############################
|
||
# #
|
||
############################
|
||
|
||
InvalidTaskID = 0xFF
|
||
"""Task ID isn't setup properly"""
|
||
|
||
__slots__ = ()
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def error_str(error: uint8, default: None = None) -> Optional[str]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def error_str(error: uint8, default: T) -> Union[str, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def error_str(error: uint8, default=None):
|
||
try:
|
||
return ErrorCode(error).name
|
||
except ValueError:
|
||
return default
|
||
|
||
|
||
@unique
|
||
class HciErrorCode(IntEnum):
|
||
SUCCESS = 0x00
|
||
UNKNOWN_HCI_CMD = 0x01
|
||
UNKNOWN_CONN_ID = 0x02
|
||
HW_FAILURE = 0x03
|
||
PAGE_TIMEOUT = 0x04
|
||
AUTH_FAILURE = 0x05
|
||
PIN_KEY_MISSING = 0x06
|
||
MEM_CAP_EXCEEDED = 0x07
|
||
CONN_TIMEOUT = 0x08
|
||
CONN_LIMIT_EXCEEDED = 0x09
|
||
SYNCH_CONN_LIMIT_EXCEEDED = 0x0A
|
||
ACL_CONN_ALREADY_EXISTS = 0x0B
|
||
CMD_DISALLOWED = 0x0C
|
||
CONN_REJ_LIMITED_RESOURCES = 0x0D
|
||
CONN_REJECTED_SECURITY_REASONS = 0x0E
|
||
CONN_REJECTED_UNACCEPTABLE_BDADDR = 0x0F
|
||
CONN_ACCEPT_TIMEOUT_EXCEEDED = 0x10
|
||
UNSUPPORTED_FEATURE_PARAM_VALUE = 0x11
|
||
INVALID_HCI_CMD_PARAMS = 0x12
|
||
REMOTE_USER_TERM_CONN = 0x13
|
||
REMOTE_DEVICE_TERM_CONN_LOW_RESOURCES = 0x14
|
||
REMOTE_DEVICE_TERM_CONN_POWER_OFF = 0x15
|
||
CONN_TERM_BY_LOCAL_HOST = 0x16
|
||
REPEATED_ATTEMPTS = 0x17
|
||
PAIRING_NOT_ALLOWED = 0x18
|
||
UNKNOWN_LMP_PDU = 0x19
|
||
UNSUPPORTED_REMOTE_FEATURE = 0x1A
|
||
SCO_OFFSET_REJ = 0x1B
|
||
SCO_INTERVAL_REJ = 0x1C
|
||
SCO_AIR_MODE_REJ = 0x1D
|
||
INVALID_LMP_PARAMS = 0x1E
|
||
UNSPECIFIED_ERROR = 0x1F
|
||
UNSUPPORTED_LMP_PARAM_VAL = 0x20
|
||
ROLE_CHANGE_NOT_ALLOWED = 0x21
|
||
LMP_LL_RESP_TIMEOUT = 0x22
|
||
LMP_ERR_TRANSACTION_COLLISION = 0x23
|
||
LMP_PDU_NOT_ALLOWED = 0x24
|
||
ENCRYPT_MODE_NOT_ACCEPTABLE = 0x25
|
||
LINK_KEY_CAN_NOT_BE_CHANGED = 0x26
|
||
REQ_QOS_NOT_SUPPORTED = 0x27
|
||
INSTANT_PASSED = 0x28
|
||
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29
|
||
DIFFERENT_TRANSACTION_COLLISION = 0x2A
|
||
RESERVED1 = 0x2B
|
||
QOS_UNACCEPTABLE_PARAM = 0x2C
|
||
QOS_REJ = 0x2D
|
||
CHAN_ASSESSMENT_NOT_SUPPORTED = 0x2E
|
||
INSUFFICIENT_SECURITY = 0x2F
|
||
PARAM_OUT_OF_MANDATORY_RANGE = 0x30
|
||
RESERVED2 = 0x31
|
||
ROLE_SWITCH_PENDING = 0x32
|
||
RESERVED3 = 0x33
|
||
RESERVED_SLOT_VIOLATION = 0x34
|
||
ROLE_SWITCH_FAILED = 0x35
|
||
EXTENDED_INQUIRY_RESP_TOO_LARGE = 0x36
|
||
SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST = 0x37
|
||
HOST_BUSY_PAIRING = 0x38
|
||
CONN_REJ_NO_SUITABLE_CHAN_FOUND = 0x39
|
||
CONTROLLER_BUSY = 0x3A
|
||
UNACCEPTABLE_CONN_PARAMETERS = 0x3B
|
||
DIRECTED_ADV_TIMEOUT = 0x3C
|
||
CONN_TERM_MIC_FAILURE = 0x3D
|
||
CONN_FAILED_TO_ESTABLISH = 0x3E
|
||
MAC_CONN_FAILED = 0x3F
|
||
COARSE_CLOCK_ADJUST_REJECTED = 0x40
|
||
|
||
__slots__ = ()
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def error_str(error: uint8, default: None = None) -> Optional[str]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def error_str(error: uint8, default: T) -> Union[str, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def error_str(error: uint8, default=None):
|
||
try:
|
||
return HciErrorCode(error).name
|
||
except ValueError:
|
||
return default
|
||
|
||
|
||
AUTHENTICATION_REQUEST = {
|
||
0x00: 'Bonding – exchange and save key information',
|
||
# 0x01 :Reserved
|
||
0x02: 'Man-In-The-Middle protection'
|
||
# 0x03 : 0x07 Reserved
|
||
}
|
||
|
||
|
||
@unique
|
||
class AddressType(IntEnum):
|
||
PUBLIC = 0x00
|
||
STATIC = 0x01
|
||
PRIVATE_NON_RESOLVE = 0x02
|
||
PRIVATE_RESOLVE = 0x03
|
||
|
||
__slots__ = ()
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def type_str(address_type: uint8, default: None = None) -> Optional[str]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def type_str(address_type: uint8, default: T) -> Union[str, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def type_str(address_type: uint8, default=None):
|
||
try:
|
||
return AddressType(address_type).name
|
||
except ValueError:
|
||
return default
|
||
|
||
|
||
@unique
|
||
class ProfileRole(IntEnum):
|
||
BROADCASTER = 0x01
|
||
OBSERVER = 0x02
|
||
PERIPHERAL = 0x04
|
||
CENTRAL = 0x08
|
||
|
||
__slots__ = ()
|
||
|
||
@staticmethod
|
||
def mask_str(profile_role: uint8) -> str:
|
||
d = []
|
||
|
||
for name, value in ProfileRole.__members__.items():
|
||
if profile_role & value:
|
||
d.append(name)
|
||
|
||
return ','.join(d)
|
||
|
||
|
||
@unique
|
||
class AttributePermission(IntEnum):
|
||
READ = 0x01
|
||
WRITE = 0x02
|
||
AUTHEN_READ = 0x04
|
||
AUTHEN_WRITE = 0x08
|
||
AUTHOR_READ = 0x10
|
||
AUTHOR_WRITE = 0x20
|
||
ENCRYPT_READ = 0x40
|
||
ENCRYPT_WRITE = 0x80
|
||
|
||
__slots__ = ()
|
||
|
||
@staticmethod
|
||
def permission_str(permissions: uint8) -> str:
|
||
return ''.join([
|
||
'r' if (permissions & 0x40) else '-',
|
||
'w' if (permissions & 0x80) else '-',
|
||
'r' if (permissions & 0x10) else '-',
|
||
'w' if (permissions & 0x20) else '-',
|
||
'r' if (permissions & 0x04) else '-',
|
||
'w' if (permissions & 0x08) else '-',
|
||
'r' if (permissions & 0x01) else '-',
|
||
'w' if (permissions & 0x02) else '-',
|
||
])
|
||
|
||
|
||
@unique
|
||
class HciDisconnectReason(IntEnum):
|
||
AUTH_FAILURE = 0x05
|
||
"""Authentication Failure"""
|
||
|
||
REMOTE_USER_TERM_CONN = 0x13
|
||
"""Remote User Terminated Connection"""
|
||
|
||
REMOTE_DEVICE_TERM_CONN_LOW_RESOURCES = 0x14
|
||
"""Remote Device Terminated Connection Due To Low Resources"""
|
||
|
||
REMOTE_DEVICE_TERM_CONN_POWER_OFF = 0x15
|
||
"""Remote Device Terminated Connection due to Power Off"""
|
||
|
||
UNSUPPORTED_REMOTE_FEATURE = 0x1A
|
||
"""Unsupported Remote Feature"""
|
||
|
||
PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED = 0x29
|
||
"""Pairing With Unit Key Not Supported"""
|
||
|
||
UNACCEPTABLE_CONN_INTERVAL = 0x3B
|
||
"""Unacceptable Connection Interval"""
|
||
|
||
__slots__ = ()
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def reason_str(reason: uint8, default: None = None) -> Optional[str]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def reason_str(reason: uint8, default: T) -> Union[str, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def reason_str(reason: uint8, default=None):
|
||
try:
|
||
return HciDisconnectReason(reason).name
|
||
except ValueError:
|
||
return default
|
||
|
||
|
||
@unique
|
||
class GattUUID(IntEnum):
|
||
# GATT Services
|
||
|
||
GAP_SERVICE: BT_UUID = 0x1800
|
||
"""Generic Access Profile"""
|
||
GATT_SERVICE: BT_UUID = 0x1801
|
||
"""Generic Attribute Profile"""
|
||
|
||
IMMEDIATE_ALERT_SERV = 0x1802
|
||
"""Immediate Alert"""
|
||
LINK_LOSS_SERV = 0x1803
|
||
"""Link Loss"""
|
||
TX_PWR_LEVEL_SERV = 0x1804
|
||
"""Tx Power"""
|
||
CURRENT_TIME_SERV = 0x1805
|
||
"""Current Time Service"""
|
||
REF_TIME_UPDATE_SERV = 0x1806
|
||
"""Reference Time Update Service"""
|
||
NEXT_DST_CHANGE_SERV = 0x1807
|
||
"""Next DST Change Service"""
|
||
GLUCOSE_SERV = 0x1808
|
||
"""Glucose"""
|
||
THERMOMETER_SERV = 0x1809
|
||
"""Health Thermometer"""
|
||
DEVINFO_SERV = 0x180A
|
||
"""Device Information"""
|
||
NWA_SERV = 0x180B
|
||
"""Network Availability"""
|
||
HEARTRATE_SERV = 0x180D
|
||
"""Heart Rate"""
|
||
PHONE_ALERT_STS_SERV = 0x180E
|
||
"""Phone Alert Status Service"""
|
||
BATT_SERV = 0x180F
|
||
"""Battery Service"""
|
||
BLOODPRESSURE_SERV = 0x1810
|
||
"""Blood Pressure"""
|
||
ALERT_NOTIF_SERV = 0x1811
|
||
"""Alert Notification Service"""
|
||
HID_SERV = 0x1812
|
||
"""Human Interface Device"""
|
||
SCAN_PARAM_SERV = 0x1813
|
||
"""Scan Parameters"""
|
||
RSC_SERV = 0x1814
|
||
"""Running Speed and Cadence"""
|
||
CSC_SERV = 0x1816
|
||
"""Cycling Speed and Cadence"""
|
||
CYCPWR_SERV = 0x1818
|
||
"""Cycling Power"""
|
||
LOC_NAV_SERV = 0x1819
|
||
"""Location and Navigation"""
|
||
|
||
# GATT Unit
|
||
|
||
GATT_UNITLESS = 0x2700
|
||
"""<Symbol>, <Expressed in terms of SI base units>"""
|
||
GATT_UNIT_LENGTH_METER = 0x2701
|
||
"""m, m"""
|
||
GATT_UNIT_MASS_KGRAM = 0x2702
|
||
"""kg, kg"""
|
||
GATT_UNIT_TIME_SECOND = 0x2703
|
||
"""s, s"""
|
||
GATT_UNIT_ELECTRIC_CURRENT_A = 0x2704
|
||
"""A, A"""
|
||
GATT_UNIT_THERMODYN_TEMP_K = 0x2705
|
||
"""K, K"""
|
||
GATT_UNIT_AMOUNT_SUBSTANCE_M = 0x2706
|
||
"""mol, mol"""
|
||
GATT_UNIT_LUMINOUS_INTENSITY_C = 0x2707
|
||
"""cd, cd"""
|
||
GATT_UNIT_AREA_SQ_MTR = 0x2710
|
||
"""m^2, m^2"""
|
||
GATT_UNIT_VOLUME_CUBIC_MTR = 0x2711
|
||
"""m^3, m^3"""
|
||
GATT_UNIT_VELOCITY_MPS = 0x2712
|
||
"""m/s, m s^-1"""
|
||
GATT_UNIT_ACCELERATION_MPS_SQ = 0x2713
|
||
"""m/s^2, m s^-2"""
|
||
GATT_UNIT_WAVENUMBER_RM = 0x2714
|
||
"""ó, m^-1"""
|
||
GATT_UNIT_DENSITY_KGPCM = 0x2715
|
||
"""p, kg m^-3"""
|
||
GATT_UNIT_SURFACE_DENSITY_KGPSM = 0x2716
|
||
"""pA, kg m^-2"""
|
||
GATT_UNIT_SPECIFIC_VOLUME_CMPKG = 0x2717
|
||
"""v, m^3 kg^-1"""
|
||
GATT_UNIT_CURRENT_DENSITY_APSM = 0x2718
|
||
"""j, A m^-2"""
|
||
GATT_UNIT_MAG_FIELD_STRENGTH = 0x2719
|
||
"""H, A m"""
|
||
GATT_UNIT_AMOUNT_CONC_MPCM = 0x271A
|
||
"""c, mol m^-3"""
|
||
GATT_UNIT_MASS_CONC_KGPCM = 0x271B
|
||
"""c, kg m^-3"""
|
||
GATT_UNIT_LUMINANCE_CPSM = 0x271C
|
||
"""Lv, cd m^-2"""
|
||
GATT_UNIT_REFRACTIVE_INDEX = 0x271D
|
||
"""n, 1"""
|
||
GATT_UNIT_RELATIVE_PERMEABLILTY = 0x271E
|
||
"""u, 1"""
|
||
GATT_UNIT_PLANE_ANGLE_RAD = 0x2720
|
||
"""rad, m m-1"""
|
||
GATT_UNIT_SOLID_ANGLE_STERAD = 0x2721
|
||
"""sr, m2 m-2"""
|
||
GATT_UNIT_FREQUENCY_HTZ = 0x2722
|
||
"""Hz, s-1"""
|
||
GATT_UNIT_FORCE_NEWTON = 0x2723
|
||
"""N, m kg s-2"""
|
||
GATT_UNIT_PRESSURE_PASCAL = 0x2724
|
||
"""Pa, N/m2 = m2 kg s-2"""
|
||
GATT_UNIT_ENERGY_JOULE = 0x2725
|
||
"""J, N m = m2 kg s-2"""
|
||
GATT_UNIT_POWER_WATT = 0x2726
|
||
"""W, J/s = m2 kg s-3"""
|
||
GATT_UNIT_E_CHARGE_C = 0x2727
|
||
"""C, sA"""
|
||
GATT_UNIT_E_POTENTIAL_DIF_V = 0x2728
|
||
"""V, W/A = m2 kg s-3 A-1"""
|
||
GATT_UNIT_CELSIUS_TEMP_DC = 0x272F
|
||
"""oC, t/oC = T/K - 273.15"""
|
||
GATT_UNIT_TIME_MINUTE = 0x2760
|
||
"""min, 60 s"""
|
||
GATT_UNIT_TIME_HOUR = 0x2761
|
||
"""h, 3600 s"""
|
||
GATT_UNIT_TIME_DAY = 0x2762
|
||
"""d, 86400 s"""
|
||
GATT_UNIT_PLANE_ANGLE_DEGREE = 0x2763
|
||
"""o, (pi/180) rad"""
|
||
GATT_UNIT_PLANE_ANGLE_MINUTE = 0x2764
|
||
"""', (pi/10800) rad"""
|
||
GATT_UNIT_PLANE_ANGLE_SECOND = 0x2765
|
||
"""'', (pi/648000) rad"""
|
||
GATT_UNIT_AREA_HECTARE = 0x2766
|
||
"""ha, 10^4 m^2"""
|
||
GATT_UNIT_VOLUME_LITRE = 0x2767
|
||
"""l, 10^-3 m^3"""
|
||
GATT_UNIT_MASS_TONNE = 0x2768
|
||
"""t, 10^3 kg"""
|
||
|
||
GATT_UINT_LENGTH_YARD = 0x27A0
|
||
"""yd, 0.9144 m"""
|
||
GATT_UNIT_LENGTH_PARSEC = 0x27A1
|
||
"""pc, 3.085678 x 1016 m"""
|
||
GATT_UNIT_LENGTH_INCH = 0x27A2
|
||
"""in, 0.0254 m"""
|
||
GATT_UNIT_LENGTH_FOOT = 0x27A3
|
||
"""ft, 0.3048 m"""
|
||
GATT_UNIT_LENGTH_MILE = 0x27A4
|
||
"""mi, 1609.347 m"""
|
||
GATT_UNIT_PRESSURE_PFPSI = 0x27A5
|
||
"""psi, 6.894757 x 103 Pa"""
|
||
GATT_UNIT_VELOCITY_KMPH = 0x27A6
|
||
"""km/h, 0.2777778 m^s-1"""
|
||
GATT_UNIT_VELOCITY_MPH = 0x27A7
|
||
"""mi/h, 0.44704 m^ s-1"""
|
||
GATT_UNIT_ANGULAR_VELOCITY_RPM = 0x27A8
|
||
"""r/min, 0.1047198 rad s-1"""
|
||
GATT_UNIT_ENERGY_GCAL = 0x27A9
|
||
GATT_UNIT_ENERGY_KCAL = 0x27AA
|
||
"""kcal, 4190.02 J"""
|
||
GATT_UNIT_ENERGY_KWH = 0x27AB
|
||
"""kWh, 3600000 J"""
|
||
GATT_UNIT_THERMODYN_TEMP_DF = 0x27AC
|
||
"""oF, t/oF = T/K x 1.8 - 459.67"""
|
||
GATT_UNIT_PERCENTAGE = 0x27AD
|
||
"""%"""
|
||
GATT_UNIT_PER_MILE = 0x27AE
|
||
GATT_UNIT_PERIOD_BPM = 0x27AF
|
||
GATT_UNIT_E_CHARGE_AH = 0x27B0
|
||
GATT_UNIT_MASS_DENSITY_MGPD = 0x27B1
|
||
GATT_UNIT_MASS_DENSITY_MMPL = 0x27B2
|
||
GATT_UNIT_TIME_YEAR = 0x27B3
|
||
GATT_UNIT_TIME_MONTH = 0x27B4
|
||
|
||
# GATT Declarations
|
||
|
||
GATT_PRIMARY_SERVICE: BT_UUID = 0x2800
|
||
"""Primary Service"""
|
||
GATT_SECONDARY_SERVICE: BT_UUID = 0x2801
|
||
"""Secondary Service"""
|
||
GATT_INCLUDE: BT_UUID = 0x2802
|
||
"""Include"""
|
||
|
||
GATT_CHARACTER: BT_UUID = 0x2803
|
||
"""Characteristic"""
|
||
# uint8 Permissions
|
||
# uint16 handle
|
||
# bytes UUID
|
||
|
||
# GATT Descriptors
|
||
|
||
GATT_CHAR_EXT_PROPS: BT_UUID = 0x2900
|
||
"""Characteristic Extended Properties"""
|
||
GATT_CHAR_USER_DESC: BT_UUID = 0x2901
|
||
"""Characteristic User Description"""
|
||
GATT_CLIENT_CHAR_CFG: BT_UUID = 0x2902
|
||
"""Client Characteristic Configuration"""
|
||
GATT_SERV_CHAR_CFG: BT_UUID = 0x2903
|
||
"""Server Characteristic Configuration"""
|
||
GATT_CHAR_FORMAT: BT_UUID = 0x2904
|
||
"""Characteristic Presentation Format"""
|
||
GATT_CHAR_AGG_FORMAT: BT_UUID = 0x2905
|
||
"""Characteristic Aggregate Format"""
|
||
GATT_VALID_RANGE: BT_UUID = 0x2906
|
||
"""Valid Range"""
|
||
GATT_EXT_REPORT_REF: BT_UUID = 0x2907
|
||
"""External Report Reference Descriptor"""
|
||
GATT_REPORT_REF: BT_UUID = 0x2908
|
||
"""Report Reference Descriptor"""
|
||
|
||
# GATT Characteristics
|
||
|
||
DEVICE_NAME: BT_UUID = 0x2A00
|
||
"""Device Name"""
|
||
APPEARANCE: BT_UUID = 0x2A01
|
||
"""Appearance"""
|
||
PERI_PRIVACY_FLAG: BT_UUID = 0x2A02
|
||
"""Peripheral Privacy Flag"""
|
||
RECONNECT_ADDR: BT_UUID = 0x2A03
|
||
"""Reconnection Address"""
|
||
PERI_CONN_PARAM: BT_UUID = 0x2A04
|
||
"""Peripheral Preferred Connection Parameters"""
|
||
SERVICE_CHANGED: BT_UUID = 0x2A05
|
||
"""Service Changed"""
|
||
|
||
ALERT_LEVEL = 0x2A06
|
||
"""Alert Level"""
|
||
TX_PWR_LEVEL = 0x2A07
|
||
"""Tx Power Level"""
|
||
DATE_TIME = 0x2A08
|
||
"""Date Time"""
|
||
DAY_OF_WEEK = 0x2A09
|
||
"""Day of Week"""
|
||
DAY_DATE_TIME = 0x2A0A
|
||
"""Day Date Time"""
|
||
EXACT_TIME_256 = 0x2A0C
|
||
"""Exact Time 256"""
|
||
DST_OFFSET = 0x2A0D
|
||
"""DST Offset"""
|
||
TIME_ZONE = 0x2A0E
|
||
"""Time Zone"""
|
||
LOCAL_TIME_INFO = 0x2A0F
|
||
"""Local Time Information"""
|
||
TIME_WITH_DST = 0x2A11
|
||
"""Time with DST"""
|
||
TIME_ACCURACY = 0x2A12
|
||
"""Time Accuracy"""
|
||
TIME_SOURCE = 0x2A13
|
||
"""Time Source"""
|
||
REF_TIME_INFO = 0x2A14
|
||
"""Reference Time Information"""
|
||
TIME_UPDATE_CTRL_PT = 0x2A16
|
||
"""Time Update Control Point"""
|
||
TIME_UPDATE_STATE = 0x2A17
|
||
"""Time Update State"""
|
||
GLUCOSE_MEAS = 0x2A18
|
||
"""Glucose Measurement"""
|
||
BATT_LEVEL = 0x2A19
|
||
"""Battery Level"""
|
||
TEMP_MEAS = 0x2A1C
|
||
"""Temperature Measurement"""
|
||
TEMP_TYPE = 0x2A1D
|
||
"""Temperature Type"""
|
||
IMEDIATE_TEMP = 0x2A1E
|
||
"""Intermediate Temperature"""
|
||
MEAS_INTERVAL = 0x2A21
|
||
"""Measurement Interval"""
|
||
BOOT_KEY_INPUT = 0x2A22
|
||
"""Boot Keyboard Input Report"""
|
||
SYSTEM_ID = 0x2A23
|
||
"""System ID"""
|
||
MODEL_NUMBER = 0x2A24
|
||
"""Model Number String"""
|
||
SERIAL_NUMBER = 0x2A25
|
||
"""Serial Number String"""
|
||
FIRMWARE_REV = 0x2A26
|
||
"""Firmware Revision String"""
|
||
HARDWARE_REV = 0x2A27
|
||
"""Hardware Revision String"""
|
||
SOFTWARE_REV = 0x2A28
|
||
"""Software Revision String"""
|
||
MANUFACTURER_NAME = 0x2A29
|
||
"""Manufacturer Name String"""
|
||
IEEE_11073_CERT_DATA = 0x2A2A
|
||
"""IEEE 11073-20601 Regulatory Certification Data List"""
|
||
CURRENT_TIME = 0x2A2B
|
||
"""Current Time"""
|
||
SCAN_REFRESH = 0x2A31
|
||
"""Scan Refresh"""
|
||
BOOT_KEY_OUTPUT = 0x2A32
|
||
"""Boot Keyboard Output Report"""
|
||
BOOT_MOUSE_INPUT = 0x2A33
|
||
"""Boot Mouse Input Report"""
|
||
GLUCOSE_CONTEXT = 0x2A34
|
||
"""Glucose Measurement Context"""
|
||
BLOODPRESSURE_MEAS = 0x2A35
|
||
"""Blood Pressure Measurement"""
|
||
IMEDIATE_CUFF_PRESSURE = 0x2A36
|
||
"""Intermediate Cuff Pressure"""
|
||
HEARTRATE_MEAS = 0x2A37
|
||
"""Heart Rate Measurement"""
|
||
BODY_SENSOR_LOC = 0x2A38
|
||
"""Body Sensor Location"""
|
||
HEARTRATE_CTRL_PT = 0x2A39
|
||
"""Heart Rate Control Point"""
|
||
NETWORK_AVAIL = 0x2A3E
|
||
"""Network Availability"""
|
||
ALERT_STATUS = 0x2A3F
|
||
"""Alert Status"""
|
||
RINGER_CTRL_PT = 0x2A40
|
||
"""Ringer Control Point"""
|
||
RINGER_SETTING = 0x2A41
|
||
"""Ringer Setting"""
|
||
ALERT_CAT_ID_BMASK = 0x2A42
|
||
"""Alert Category ID Bit Mask"""
|
||
ALERT_CAT_ID = 0x2A43
|
||
"""Alert Category ID"""
|
||
ALERT_NOTIF_CTRL_PT = 0x2A44
|
||
"""Alert Notification Control Point"""
|
||
UNREAD_ALERT_STATUS = 0x2A45
|
||
"""Unread Alert Status"""
|
||
NEW_ALERT = 0x2A46
|
||
"""New Alert"""
|
||
SUP_NEW_ALERT_CAT = 0x2A47
|
||
"""Supported New Alert Category"""
|
||
SUP_UNREAD_ALERT_CAT = 0x2A48
|
||
"""Supported Unread Alert Category"""
|
||
BLOODPRESSURE_FEATURE = 0x2A49
|
||
"""Blood Pressure Feature"""
|
||
HID_INFORMATION = 0x2A4A
|
||
"""HID Information"""
|
||
REPORT_MAP = 0x2A4B
|
||
"""Report Map"""
|
||
HID_CTRL_PT = 0x2A4C
|
||
"""HID Control Point"""
|
||
REPORT = 0x2A4D
|
||
"""Report"""
|
||
PROTOCOL_MODE = 0x2A4E
|
||
"""Protocol Mode"""
|
||
SCAN_INTERVAL_WINDOW = 0x2A4F
|
||
"""Scan Interval Window"""
|
||
PNP_ID = 0x2A50
|
||
"""PnP ID"""
|
||
GLUCOSE_FEATURE = 0x2A51
|
||
"""Glucose Feature"""
|
||
RECORD_CTRL_PT = 0x2A52
|
||
"""Record Access Control Point"""
|
||
RSC_MEAS = 0x2A53
|
||
"""RSC Measurement"""
|
||
RSC_FEATURE = 0x2A54
|
||
"""RSC Feature"""
|
||
SC_CTRL_PT = 0x2A55
|
||
"""SC Control Point"""
|
||
CSC_MEAS = 0x2A5B
|
||
"""CSC Measurement"""
|
||
CSC_FEATURE = 0x2A5C
|
||
"""CSC Feature"""
|
||
SENSOR_LOC = 0x2A5D
|
||
"""Sensor Location"""
|
||
CYCPWR_MEAS = 0x2A63
|
||
"""Cycling Power Measurement"""
|
||
CYCPWR_VECTOR = 0x2A64
|
||
"""Cycling Power Vector"""
|
||
CYCPWR_FEATURE = 0x2A65
|
||
"""Cycling Power Feature"""
|
||
CYCPWR_CTRL_PT = 0x2A66
|
||
"""Cycling Power Control Point"""
|
||
LOC_SPEED = 0x2A67
|
||
"""Location and Speed"""
|
||
NAV = 0x2A68
|
||
"""Navigation"""
|
||
POS_QUALITY = 0x2A69
|
||
"""Position Quality"""
|
||
LN_FEATURE = 0x2A6A
|
||
"""LN Feature"""
|
||
LN_CTRL_PT = 0x2A6B
|
||
"""LN Control Point"""
|
||
|
||
__slots__ = ()
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def att_str(uuid: BT_UUID, default: None = None) -> Optional[str]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def att_str(uuid: BT_UUID, default: T) -> Union[str, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def att_str(uuid: BT_UUID, default=None):
|
||
try:
|
||
return GattUUID(uuid).name
|
||
except ValueError:
|
||
return default
|
||
|
||
@staticmethod
|
||
def uuid_str(u: ATT_UUID) -> str:
|
||
if isinstance(u, int):
|
||
_u = GattUUID.att_str(u, None)
|
||
if _u is None:
|
||
return x16(u)
|
||
else:
|
||
return _u
|
||
else:
|
||
return address_str(u)
|
||
|
||
|
||
_INSTRUCTION: Dict[int, str] = {}
|
||
|
||
|
||
def instruction(code: uint16):
|
||
def _instruction_inner(f):
|
||
if code in _INSTRUCTION:
|
||
raise RuntimeError('instruction code collision : ' + x16(code))
|
||
|
||
_INSTRUCTION[code] = f.__name__
|
||
f.EVENT_CODE = code
|
||
|
||
return f
|
||
|
||
return _instruction_inner
|
||
|
||
|
||
class CC2650Instruction:
|
||
__slots__ = ()
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def code_str(code: uint16, default: None = None) -> Optional[str]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def code_str(code: uint16, default: T) -> Union[str, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def code_str(code: uint16, default=None):
|
||
return _INSTRUCTION.get(code, default)
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def call_code(call: Callable, default: None = None) -> Optional[uint16]:
|
||
pass
|
||
|
||
# recognized by run-setup-modify @overload
|
||
@staticmethod
|
||
@overload
|
||
def call_code(call: Callable, default: T) -> Union[uint16, T]:
|
||
pass
|
||
|
||
@staticmethod
|
||
def call_code(call, default=None):
|
||
if not callable(call):
|
||
raise RuntimeError('not a callable : ' + str(call))
|
||
|
||
code = getattr(call, 'EVENT_CODE', None)
|
||
|
||
if code is not None:
|
||
return code
|
||
|
||
name = call.__name__
|
||
|
||
for c, n in _INSTRUCTION.items():
|
||
if n == name:
|
||
return c
|
||
|
||
return default
|