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_write(bd_addr_type, bd_addr, hdl, val, val_mtp=None): logging.debug("%s %r %r %r %r %r", gattc_write.__name__, bd_addr_type, bd_addr, hdl, val, val_mtp) iutctl = get_iut() gap_wait_for_connection() if isinstance(hdl, str): hdl = int(hdl, 16) if val_mtp: val *= int(val_mtp) data_ba = bytearray() bd_addr_ba = addr2btp_ba(bd_addr) hdl_ba = struct.pack('H', hdl) val_ba = binascii.unhexlify(val) val_len_ba = struct.pack('H', len(val_ba)) data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(hdl_ba) data_ba.extend(val_len_ba) data_ba.extend(val_ba) iutctl.btp_socket.send(*GATTC['write'], data=data_ba)
def gap_start_discov(transport='le', discov_type='active', mode='general'): """GAP Start Discovery function. Possible options (key: <values>): transport: <le, bredr> discov_type: <active, passive> mode: <general, limited, observe> """ logging.debug("%s", gap_start_discov.__name__) iutctl = get_iut() flags = 0 if transport == "le": flags |= defs.GAP_DISCOVERY_FLAG_LE else: flags |= defs.GAP_DISCOVERY_FLAG_BREDR if discov_type == "active": flags |= defs.GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN if mode == "limited": flags |= defs.GAP_DISCOVERY_FLAG_LIMITED elif mode == "observe": flags |= defs.GAP_DISCOVERY_FLAG_LE_OBSERVE stack = get_stack() stack.gap.reset_discovery() iutctl.btp_socket.send(*GAP['start_discov'], data=chr(flags)) gap_command_rsp_succ()
def gattc_write_long(bd_addr_type, bd_addr, hdl, off, val, length=None): logging.debug("%s %r %r %r %r %r", gattc_write_long.__name__, bd_addr_type, hdl, off, val, length) gap_wait_for_connection() if isinstance(hdl, str): hdl = int(hdl, 16) # convert string in hex format to int if isinstance(off, str): off = int(off, 16) if length: val *= int(length) iutctl = get_iut() bd_addr_ba = addr2btp_ba(bd_addr) hdl_ba = struct.pack('H', hdl) off_ba = struct.pack('H', off) val_ba = bytes.fromhex(val) val_len_ba = struct.pack('H', len(val_ba)) data_ba = bytearray() data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(hdl_ba) data_ba.extend(off_ba) data_ba.extend(val_len_ba) data_ba.extend(val_ba) iutctl.btp_socket.send(*GATTC['write_long'], data=data_ba)
def gap_reset(): logging.debug("%s", gap_reset.__name__) iutctl = get_iut() iutctl.btp_socket.send(*GAP['reset']) gap_command_rsp_succ()
def set_filter_accept_list(address_list=None): """ Send tuples (address, address_type) to IUT and save them to the filter accept list. If address_list=None PTS's (address,type) will be sent. Arguments: address_list -- addrs and their types as tuples: address_list = [('DB:F5:72:56:C9:EF', 0), ('DB:F5:72:56:C9:EF', 0)] """ logging.debug("%s %s", set_filter_accept_list.__name__, address_list) iutctl = get_iut() data_ba = bytearray() if not address_list: address_list = [(pts_addr_get(None), pts_addr_type_get(None))] addr_cnt_ba = chr(len(address_list)).encode('utf-8') data_ba.extend(addr_cnt_ba) for addr, type in address_list: bd_addr_ba = addr2btp_ba(addr) bd_addr_type_ba = chr(type).encode('utf-8') data_ba.extend(bd_addr_type_ba) data_ba.extend(bd_addr_ba) iutctl.btp_socket.send(*GAP['set_filter_accept_list'], data=data_ba) gap_command_rsp_succ()
def gap_direct_adv_on(addr, addr_type, high_duty=0, peer_rpa=0): logging.debug("%s %r %r", gap_direct_adv_on.__name__, addr, high_duty) stack = get_stack() if stack.gap.current_settings_get( gap_settings_btp2txt[defs.GAP_SETTINGS_ADVERTISING]): return iutctl = get_iut() data_ba = bytearray() bd_addr_ba = addr2btp_ba(addr) data_ba.extend(chr(addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) opts = 0 if high_duty: opts |= defs.GAP_START_DIRECT_ADV_HD if peer_rpa: opts |= defs.GAP_START_DIRECT_ADV_PEER_RPA data_ba.extend(struct.pack('H', opts)) iutctl.btp_socket.send(*GAP['start_direct_adv'], data=data_ba) tuple_data = gap_command_rsp_succ(defs.GAP_START_DIRECT_ADV) __gap_current_settings_update(tuple_data)
def l2cap_conn(bd_addr, bd_addr_type, psm, mtu=0, num=1, ecfc=0, hold_credit=0): logging.debug("%s %r %r %r", l2cap_conn.__name__, bd_addr, bd_addr_type, psm) iutctl = get_iut() gap_wait_for_connection() if isinstance(psm, str): psm = int(psm, 16) bd_addr = pts_addr_get(bd_addr) bd_addr_type = pts_addr_type_get(bd_addr_type) bd_addr_ba = addr2btp_ba(bd_addr) data_ba = bytearray(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(struct.pack('H', psm)) data_ba.extend(struct.pack('H', mtu)) data_ba.extend(struct.pack('B', num)) opts = 0 if ecfc: opts |= defs.L2CAP_CONNECT_OPT_ECFC if hold_credit: opts |= defs.L2CAP_CONNECT_OPT_HOLD_CREDIT data_ba.extend(struct.pack('B', opts)) iutctl.btp_socket.send(*L2CAP['connect'], data=data_ba) chan_ids = l2cap_conn_rsp() logging.debug("id %r", chan_ids)
def gap_conn_param_update(bd_addr, bd_addr_type, conn_itvl_min, conn_itvl_max, conn_latency, supervision_timeout): logging.debug("%s %r %r", gap_conn_param_update.__name__, bd_addr, bd_addr_type) iutctl = get_iut() gap_wait_for_connection() data_ba = bytearray() bd_addr_ba = addr2btp_ba(pts_addr_get(bd_addr)) data_ba.extend(chr(pts_addr_type_get(bd_addr_type)).encode('utf-8')) data_ba.extend(bd_addr_ba) conn_itvl_min_ba = struct.pack('H', conn_itvl_min) conn_itvl_max_ba = struct.pack('H', conn_itvl_max) conn_latency_ba = struct.pack('H', conn_latency) supervision_timeout_ba = struct.pack('H', supervision_timeout) data_ba.extend(conn_itvl_min_ba) data_ba.extend(conn_itvl_max_ba) data_ba.extend(conn_latency_ba) data_ba.extend(supervision_timeout_ba) iutctl.btp_socket.send(*GAP['conn_param_update'], data=data_ba) # Expected result gap_command_rsp_succ()
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_all_desc(bd_addr_type, bd_addr, start_hdl, stop_hdl): logging.debug("%s %r %r %r %r", gattc_disc_all_desc.__name__, bd_addr_type, bd_addr, start_hdl, stop_hdl) iutctl = get_iut() gap_wait_for_connection() if isinstance(start_hdl, str): start_hdl = int(start_hdl, 16) if isinstance(stop_hdl, str): stop_hdl = int(stop_hdl, 16) data_ba = bytearray() bd_addr_ba = addr2btp_ba(bd_addr) start_hdl_ba = struct.pack('H', start_hdl) stop_hdl_ba = struct.pack('H', stop_hdl) data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(start_hdl_ba) data_ba.extend(stop_hdl_ba) iutctl.btp_socket.send(*GATTC['disc_all_desc'], data=data_ba)
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_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 gatts_add_desc(hdl, perm, uuid): logging.debug("%s %r %r %r", gatts_add_desc.__name__, hdl, perm, uuid) iutctl = get_iut() if isinstance(hdl, str): hdl = int(hdl, 16) data_ba = bytearray() hdl_ba = struct.pack('H', hdl) uuid_ba = binascii.unhexlify(uuid.replace("-", ""))[::-1] data_ba.extend(hdl_ba) if isinstance(perm, int): data_ba.extend(bytes([perm])) else: data_ba.extend(chr(perm).encode('utf-8')) data_ba.extend(chr(len(uuid_ba)).encode('utf-8')) data_ba.extend(uuid_ba) iutctl.btp_socket.send(*GATTS['add_desc'], data=data_ba) gatt_command_rsp_succ()
def gatts_start_server(): logging.debug("%s", gatts_start_server.__name__) iutctl = get_iut() iutctl.btp_socket.send(*GATTS['start_server']) gatt_command_rsp_succ()
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 gatts_set_val(hdl, val): logging.debug("%s %r %r ", gatts_set_val.__name__, hdl, val) iutctl = get_iut() if isinstance(hdl, str): hdl = int(hdl, 16) data_ba = bytearray() hdl_ba = struct.pack('H', hdl) if isinstance(val, str): val_ba = binascii.unhexlify(bytearray(val, 'utf-8')) elif isinstance(val, bytes): val_ba = binascii.unhexlify(val) else: val_ba = binascii.unhexlify(bytearray(val.encode('utf-8'))) val_len_ba = struct.pack('H', len(val_ba)) data_ba.extend(hdl_ba) data_ba.extend(val_len_ba) data_ba.extend(val_ba) iutctl.btp_socket.send(*GATTS['set_val'], data=data_ba) gatt_command_rsp_succ()
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 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 mesh_net_send(ttl, src, dst, payload): logging.debug("%s %r %r %r %r", mesh_net_send.__name__, ttl, src, dst, payload) if ttl is None: ttl = 0xff # Use default TTL elif isinstance(ttl, str): ttl = int(ttl, 16) if isinstance(src, str): src = int(src, 16) if isinstance(dst, str): dst = int(dst, 16) payload = binascii.unhexlify(payload) payload_len = len(payload) if payload_len > 0xff: raise BTPError("Payload exceeds PDU") data = bytearray(struct.pack("<BHHB", ttl, src, dst, payload_len)) data.extend(payload) iutctl = get_iut() iutctl.btp_socket.send_wait_rsp(*MESH['net_send'], data=data)
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_long(bd_addr_type, bd_addr, hdl, off, modif_off=None): logging.debug("%s %r %r %r %r %r", gattc_read_long.__name__, bd_addr_type, bd_addr, hdl, off, modif_off) iutctl = get_iut() gap_wait_for_connection() data_ba = bytearray() if isinstance(off, str): off = int(off, 16) if modif_off: off += modif_off if isinstance(hdl, str): hdl = int(hdl, 16) bd_addr_ba = addr2btp_ba(bd_addr) hdl_ba = struct.pack('H', hdl) off_ba = struct.pack('H', off) data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(hdl_ba) data_ba.extend(off_ba) iutctl.btp_socket.send(*GATTC['read_long'], data=data_ba)
def gattc_read_uuid(bd_addr_type, bd_addr, start_hdl, end_hdl, uuid): logging.debug("%s %r %r %r %r %r", gattc_read_uuid.__name__, bd_addr_type, bd_addr, start_hdl, end_hdl, uuid) iutctl = get_iut() gap_wait_for_connection() if isinstance(start_hdl, str): start_hdl = int(start_hdl, 16) if isinstance(end_hdl, str): end_hdl = int(end_hdl, 16) data_ba = bytearray() bd_addr_ba = addr2btp_ba(bd_addr) start_hdl_ba = struct.pack('H', start_hdl) end_hdl_ba = struct.pack('H', end_hdl) if "-" in uuid: uuid = uuid.replace("-", "") if uuid.startswith("0x"): uuid = uuid.replace("0x", "") uuid_ba = binascii.unhexlify(uuid)[::-1] data_ba.extend(chr(bd_addr_type).encode('utf-8')) data_ba.extend(bd_addr_ba) data_ba.extend(start_hdl_ba) data_ba.extend(end_hdl_ba) data_ba.extend(chr(len(uuid_ba)).encode('utf-8')) data_ba.extend(uuid_ba) iutctl.btp_socket.send(*GATTC['read_uuid'], data=data_ba)
def gap_set_mitm_off(): logging.debug("%s", gap_set_mitm_off.__name__) iutctl = get_iut() iutctl.btp_socket.send(*GAP['set_mitm_off']) gap_command_rsp_succ()
def mesh_input_string(string): logging.debug("%s %s", mesh_input_string.__name__, string) iutctl = get_iut() data = bytearray(string) iutctl.btp_socket.send_wait_rsp(*MESH['input_str'], data=data)
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 gap_adv_ind_on(ad=None, sd=None, duration=AdDuration.forever, own_addr_type=OwnAddrType.le_identity_address): logging.debug("%s %r %r", gap_adv_ind_on.__name__, ad, sd) if ad is None: ad = {} if sd is None: sd = {} stack = get_stack() if stack.gap.current_settings_get( gap_settings_btp2txt[defs.GAP_SETTINGS_ADVERTISING]): return iutctl = get_iut() data_ba = bytearray() ad_ba = bytearray() sd_ba = bytearray() data = bytearray() for ad_type, ad_data in list(ad.items()): if isinstance(ad_data, str): data = bytes.fromhex(ad_data) elif isinstance(ad_data, bytes): data = ad_data ad_ba.extend(bytes([ad_type])) ad_ba.extend(chr(len(data)).encode('utf-8')) ad_ba.extend(data) for sd_type, sd_data in list(sd.items()): if not isinstance(sd_data, bytes): try: data = bytes.fromhex(sd_data) except TypeError: data = bytes.fromhex(sd_data.decode('utf-8')) else: data = sd_data sd_ba.extend(bytes([sd_type])) sd_ba.extend(chr(len(data)).encode('utf-8')) sd_ba.extend(data) data_ba.extend(chr(len(ad_ba)).encode('utf-8')) data_ba.extend(chr(len(sd_ba)).encode('utf-8')) data_ba.extend(ad_ba) data_ba.extend(sd_ba) data_ba.extend(struct.pack("<I", duration)) data_ba.extend(chr(own_addr_type).encode('utf-8')) iutctl.btp_socket.send(*GAP['start_adv'], data=data_ba) tuple_data = gap_command_rsp_succ(defs.GAP_START_ADVERTISING) __gap_current_settings_update(tuple_data)
def gap_set_powered_off(): logging.debug("%s", gap_set_powered_off.__name__) iutctl = get_iut() iutctl.btp_socket.send(*GAP['set_powered_off']) tuple_data = gap_command_rsp_succ() __gap_current_settings_update(tuple_data)
def gap_set_io_cap(io_cap): logging.debug("%s %r", gap_set_io_cap.__name__, io_cap) iutctl = get_iut() stack = get_stack() stack.gap.io_cap = io_cap iutctl.btp_socket.send(*GAP['set_io_cap'], data=chr(io_cap)) gap_command_rsp_succ()
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)