def gattc_cfg_indicate(bd_addr_type, bd_addr, enable, ccc_hdl): logging.debug("%s %r %r, %r, %r", gattc_cfg_indicate.__name__, bd_addr_type, bd_addr, enable, ccc_hdl) gap_wait_for_connection() if isinstance(ccc_hdl, str): ccc_hdl = int(ccc_hdl, 16) iutctl = get_iut() bd_addr_ba = addr2btp_ba(bd_addr) ccc_hdl_ba = struct.pack('H', ccc_hdl) data_ba = bytearray() data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(chr(enable).encode('utf-8')) data_ba.extend(ccc_hdl_ba) iutctl.btp_socket.send(*GATTC['cfg_indicate'], data=data_ba) tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_cfg_indicate.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_CFG_INDICATE)
def gattc_disc_chrc_uuid_rsp(store_rsp=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_chrc_uuid_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_CHRC_UUID) chrcs_list = gatt_dec_disc_rsp(tuple_data[0], "characteristic") logging.debug("%s %r", gattc_disc_chrc_uuid_rsp.__name__, chrcs_list) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] for chrc in chrcs_list: handle = "%04X" % (chrc[1], ) uuid = chrc[3] # add hyphens to long uuid: 0000-1157-0000-0000-0123-4567-89AB-CDEF if len(uuid) > 4: uuid = "-".join( [uuid[i:i + 4] for i in range(0, len(uuid), 4)]) VERIFY_VALUES.append(handle) VERIFY_VALUES.append(uuid) logging.debug("Set verify values to: %r", VERIFY_VALUES)
def gap_read_ctrl_info(): logging.debug("%s", gap_read_ctrl_info.__name__) iutctl = get_iut() iutctl.btp_socket.send(*GAP['read_ctrl_info']) tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GAP, defs.GAP_READ_CONTROLLER_INFO) fmt = '<6sII3s249s11s' if len(tuple_data[0]) < struct.calcsize(fmt): raise BTPError("Invalid data length") _addr, _supp_set, _curr_set, _cod, _name, _name_sh = \ struct.unpack_from(fmt, tuple_data[0]) _addr = binascii.hexlify(_addr[::-1]).lower() stack = get_stack() addr_type = Addr.le_random if \ (_curr_set & (1 << defs.GAP_SETTINGS_PRIVACY)) or \ (_curr_set & (1 << defs.GAP_SETTINGS_STATIC_ADDRESS)) else \ Addr.le_public stack.gap.iut_addr_set(_addr, addr_type) logging.debug("IUT address %r", stack.gap.iut_addr_get_str()) __gap_current_settings_update(_curr_set)
def gattc_find_included_rsp(store_rsp=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_find_included_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_FIND_INCLUDED) incls_tuple = gatt_dec_disc_rsp(tuple_data[0], "include") logging.debug("%s %r", gattc_find_included_rsp.__name__, incls_tuple) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] for incl in incls_tuple: att_handle = "%04X" % (incl[0][0], ) inc_svc_handle = "%04X" % (incl[1][0], ) end_grp_handle = "%04X" % (incl[1][1], ) uuid = incl[1][2] VERIFY_VALUES.append(att_handle) VERIFY_VALUES.append(inc_svc_handle) VERIFY_VALUES.append(end_grp_handle) VERIFY_VALUES.append(uuid) logging.debug("Set verify values to: %r", VERIFY_VALUES)
def gattc_disc_all_chrc_rsp(store_rsp=False): iutctl = get_iut() attrs = [] tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_all_chrc_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_ALL_CHRC) chrcs_list = gatt_dec_disc_rsp(tuple_data[0], "characteristic") logging.debug("%s %r", gattc_disc_all_chrc_rsp.__name__, chrcs_list) for chrc in chrcs_list: (handle, value_handle, prop, uuid) = chrc attrs.append( GattCharacteristic(handle=handle, perm=Perm.read, uuid=uuid, att_rsp=0, prop=prop, value_handle=value_handle)) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] for attr in attrs: VERIFY_VALUES.append("%04X" % attr.handle) logging.debug("Set verify values to: %r", VERIFY_VALUES) return attrs
def gatts_get_attr_val(bd_addr_type, bd_addr, handle): logging.debug("%s %r", gatts_get_attr_val.__name__, handle) iutctl = get_iut() data_ba = bytearray() bd_addr_ba = addr2btp_ba(bd_addr) if isinstance(handle, str): handle = int(handle, 16) hdl_ba = struct.pack('H', handle) data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(hdl_ba) iutctl.btp_socket.send(*GATTS['get_attr_val'], data=data_ba) tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_GET_ATTRIBUTE_VALUE) hdr = '<BH' hdr_len = struct.calcsize(hdr) data_len = tuple_hdr.data_len - hdr_len return struct.unpack(hdr + '%ds' % data_len, tuple_data[0])
def gattc_disc_all_prim_rsp(store_rsp=False): logging.debug("%s", gattc_disc_all_prim_rsp.__name__) iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_all_prim_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_ALL_PRIM) svcs_list = gatt_dec_disc_rsp(tuple_data[0], "service") logging.debug("%s %r", gattc_disc_all_prim_rsp.__name__, svcs_list) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] for svc in svcs_list: # Keep just UUID since PTS checks only UUID. uuid = svc[2].upper() # avoid repeated service uuid, it should be verified only once if uuid not in VERIFY_VALUES: VERIFY_VALUES.append(uuid) logging.debug("Set verify values to: %r", VERIFY_VALUES) return svcs_list
def gattc_read_uuid_rsp(store_rsp=False, store_val=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_read_uuid_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_READ_UUID) rsp, value = gatt_dec_read_rsp(tuple_data[0]) logging.debug("%s %r %r", gattc_read_uuid_rsp.__name__, rsp, value) if store_rsp or store_val: global VERIFY_VALUES VERIFY_VALUES = [] if store_rsp: VERIFY_VALUES.append(att_rsp_str[rsp]) if store_val: n = len(value[0]) value = (binascii.hexlify(value[0]).decode('utf-8')).upper() if len(value) > 0: chunks = [ value[i:i + len(value) // n] for i in range(0, len(value), len(value) // n) ] VERIFY_VALUES.extend(chunks)
def l2cap_command_rsp_succ(op=None): logging.debug("%s", l2cap_command_rsp_succ.__name__) iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_L2CAP, op)
def gatt_command_rsp_succ(): logging.debug("%s", gatt_command_rsp_succ.__name__) iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT)
def l2cap_conn_rsp(): logging.debug("%s", l2cap_conn_rsp.__name__) iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_L2CAP, defs.L2CAP_CONNECT) num = struct.unpack_from('<B', tuple_data[0])[0] channels = struct.unpack_from('%ds' % num, tuple_data[0], 1)[0] return list(channels)
def gatts_attr_value_changed_ev(): logging.debug("%s", gatts_attr_value_changed_ev.__name__) iutctl = get_iut() (tuple_hdr, tuple_data) = iutctl.btp_socket.read() btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_EV_ATTR_VALUE_CHANGED) (handle, data) = gatts_dec_attr_value_changed_ev_data(tuple_data[0]) logging.debug("%s %r %r", gatts_attr_value_changed_ev.__name__, handle, data) return handle, data
def gattc_write_long_rsp(store_rsp=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_write_long_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_WRITE_LONG) rsp = gatt_dec_write_rsp(tuple_data[0]) logging.debug("%s %r", gattc_write_long_rsp.__name__, rsp) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] VERIFY_VALUES.append(att_rsp_str[rsp])
def gap_oob_sc_get_local_data(): logging.debug("%s", gap_oob_sc_get_local_data.__name__) iutctl = get_iut() iutctl.btp_socket.send(*GAP['oob_sc_get_local_data'], data=bytearray()) tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gap_oob_sc_get_local_data.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GAP, defs.GAP_OOB_SC_GET_LOCAL_DATA) hdr = '<16s16s' r, c = struct.unpack_from(hdr, tuple_data[0]) r, c = bytes.hex(r[::-1]), bytes.hex(c[::-1]) logging.debug("r=%s c=%s", r, c) return r, c
def gattc_notification_ev(bd_addr, bd_addr_type, ev_type): logging.debug("%s %r %r %r", gattc_notification_ev.__name__, bd_addr, bd_addr_type, ev_type) iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_EV_NOTIFICATION) data_ba = bytearray() bd_addr_ba = addr2btp_ba(bd_addr) data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(chr(ev_type).encode('utf-8')) if tuple_data[0][0:len(data_ba)] != data_ba: raise BTPError("Error in notification event data")
def gattc_disc_prim_uuid_rsp(store_rsp=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_prim_uuid_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_PRIM_UUID) svcs_list = gatt_dec_disc_rsp(tuple_data[0], "service") logging.debug("%s %r", gattc_disc_prim_uuid_rsp.__name__, svcs_list) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] for svc in svcs_list: start_handle = "%04X" % (svc[0], ) end_handle = "%04X" % (svc[1], ) uuid = svc[2] # add hyphens to long uuid: 0000-1157-0000-0000-0123-4567-89AB-CDEF if len(uuid) > 4: uuid = "-".join( [uuid[i:i + 4] for i in range(0, len(uuid), 4)]) VERIFY_VALUES.append(start_handle) VERIFY_VALUES.append(end_handle) # avoid repeated service uuid, it should be verified only once, for # example: # gattc_disc_prim_uuid_rsp ((1, 3, ('\xc9N',)), # (48, 50, ('\xc9N',)), (64, 66, ('\xc9N',)), # (80, 82, ('\xc9N',)), (144, 150, ('\xc9N',))) if uuid not in VERIFY_VALUES: VERIFY_VALUES.append(uuid) logging.debug("Set verify values to: %r", VERIFY_VALUES)
def gattc_read_multiple_rsp(store_val=False, store_rsp=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_read_multiple_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_READ_MULTIPLE) rsp, values = gatt_dec_read_rsp(tuple_data[0]) logging.debug("%s %r %r", gattc_read_multiple_rsp.__name__, rsp, values) if store_rsp or store_val: global VERIFY_VALUES VERIFY_VALUES = [] if store_rsp: VERIFY_VALUES.append(att_rsp_str[rsp]) if store_val: VERIFY_VALUES.append((binascii.hexlify(values[0])).upper())
def gattc_disc_all_chrc_find_attrs_rsp(exp_chars, store_attrs=False): """Parse and find requested characteristics from rsp ATTRIBUTE FORMAT (CHARACTERISTIC) - (handle, val handle, props, uuid) """ iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_all_chrc_find_attrs_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_ALL_CHRC) chars_list = gatt_dec_disc_rsp(tuple_data[0], "characteristic") for char in chars_list: for exp_char in exp_chars: # Check if option expected attribute parameters match # TODO: Use class and a comparison method if ((exp_char[0] and exp_char[0] != char[0]) or (exp_char[1] and exp_char[1] != char[1]) or (exp_char[2] and exp_char[2] != char[2]) or (exp_char[3] and exp_char[3] != char[3])): logging.debug("gatt char not matched = %r != %r", char, exp_char) continue logging.debug("gatt char matched = %r == %r", char, exp_char) if store_attrs: global GATT_CHARS GATT_CHARS = [] GATT_CHARS.append(char)
def gatts_get_attrs(start_handle=0x0001, end_handle=0xffff, type_uuid=None): logging.debug("%s %r %r %r", gatts_get_attrs.__name__, start_handle, end_handle, type_uuid) iutctl = get_iut() data_ba = bytearray() if isinstance(start_handle, str): start_handle = int(start_handle, 16) start_hdl_ba = struct.pack('H', start_handle) data_ba.extend(start_hdl_ba) if isinstance(end_handle, str): end_handle = int(end_handle, 16) end_hdl_ba = struct.pack('H', end_handle) data_ba.extend(end_hdl_ba) if type_uuid: uuid_ba = bytes.fromhex(type_uuid.replace("-", "")) # uuid_ba has bytes in reverse order, must bew swapped uuid_ba = uuid_ba[::-1] data_ba.extend(chr(len(uuid_ba)).encode('utf-8')) data_ba.extend(uuid_ba) else: data_ba.extend(chr(0).encode('utf-8')) iutctl.btp_socket.send(*GATTS['get_attrs'], data=data_ba) tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("received %r %r", tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_GET_ATTRIBUTES) return dec_gatts_get_attrs_rp(tuple_data[0], tuple_hdr.data_len)
def gattc_disc_all_desc_rsp(store_rsp=False): iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_all_desc_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_ALL_DESC) descs_list = gatt_dec_disc_rsp(tuple_data[0], "descriptor") logging.debug("%s %r", gattc_disc_all_desc_rsp.__name__, descs_list) if store_rsp: global VERIFY_VALUES VERIFY_VALUES = [] for desc in descs_list: handle = "%04X" % (desc[0], ) uuid = desc[1] VERIFY_VALUES.append(handle) VERIFY_VALUES.append(uuid) logging.debug("Set verify values to: %r", VERIFY_VALUES)
def gattc_disc_prim_uuid_find_attrs_rsp(exp_svcs, store_attrs=False): """Parse and find requested services from rsp ATTRIBUTE FORMAT (PRIMARY SERVICE) - (start handle, end handle, uuid) """ iutctl = get_iut() tuple_hdr, tuple_data = iutctl.btp_socket.read() logging.debug("%s received %r %r", gattc_disc_prim_uuid_find_attrs_rsp.__name__, tuple_hdr, tuple_data) btp_hdr_check(tuple_hdr, defs.BTP_SERVICE_ID_GATT, defs.GATT_DISC_PRIM_UUID) svcs_list = gatt_dec_disc_rsp(tuple_data[0], "service") for svc in svcs_list: for exp_svc in exp_svcs: # Check if option expected attribute parameters match # TODO: Use class and a comparison method if ((exp_svc[0] and exp_svc[0] != svc[0]) or (exp_svc[1] and exp_svc[1] != svc[1]) or (exp_svc[2] and exp_svc[2] != svc[2])): logging.debug("gatt svc not matched = %r != %r", svc, exp_svc) continue logging.debug("gatt svc matched = %r == %r", svc, exp_svc) if store_attrs: global GATT_SVCS GATT_SVCS = [] GATT_SVCS.append(svc)