1*7dc08ffcSJunyu Lai% Scapy Bluetooth layer tests 2*7dc08ffcSJunyu Lai 3*7dc08ffcSJunyu Lai+ HCI Commands 4*7dc08ffcSJunyu Lai= LE Create Connection Cancel 5*7dc08ffcSJunyu Lai 6*7dc08ffcSJunyu Laiexpected_cmd_raw_data = hex_bytes("010e2000") 7*7dc08ffcSJunyu Laicmd_raw_data = raw(HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Create_Connection_Cancel()) 8*7dc08ffcSJunyu Laiassert(expected_cmd_raw_data == cmd_raw_data) 9*7dc08ffcSJunyu Lai 10*7dc08ffcSJunyu Lai= Disconnect 11*7dc08ffcSJunyu Laiexpected_cmd_raw_data = hex_bytes("01060403341213") 12*7dc08ffcSJunyu Laicmd_raw_data = raw(HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_Disconnect(handle=0x1234)) 13*7dc08ffcSJunyu Laiassert(expected_cmd_raw_data == cmd_raw_data) 14*7dc08ffcSJunyu Lai 15*7dc08ffcSJunyu Lai= LE Connection Update Command 16*7dc08ffcSJunyu Laiexpected_cmd_raw_data = hex_bytes("0113200e47000a00140001003c000100ffff") 17*7dc08ffcSJunyu Laicmd_raw_data = raw( 18*7dc08ffcSJunyu Lai HCI_Hdr() / HCI_Command_Hdr() / HCI_Cmd_LE_Connection_Update( 19*7dc08ffcSJunyu Lai handle=0x47, min_interval=10, max_interval=20, latency=1, timeout=60, 20*7dc08ffcSJunyu Lai min_ce=1, max_ce=0xffff)) 21*7dc08ffcSJunyu Laiassert(expected_cmd_raw_data == cmd_raw_data) 22*7dc08ffcSJunyu Lai 23*7dc08ffcSJunyu Lai 24*7dc08ffcSJunyu Lai+ HCI Events 25*7dc08ffcSJunyu Lai= LE Connection Update Event 26*7dc08ffcSJunyu Laievt_raw_data = hex_bytes("043e0a03004800140001003c00") 27*7dc08ffcSJunyu Laievt_pkt = HCI_Hdr(evt_raw_data) 28*7dc08ffcSJunyu Laiassert(evt_pkt[HCI_LE_Meta_Connection_Update_Complete].handle == 0x48) 29*7dc08ffcSJunyu Laiassert(evt_pkt[HCI_LE_Meta_Connection_Update_Complete].interval == 20) 30*7dc08ffcSJunyu Laiassert(evt_pkt[HCI_LE_Meta_Connection_Update_Complete].latency == 1) 31*7dc08ffcSJunyu Laiassert(evt_pkt[HCI_LE_Meta_Connection_Update_Complete].timeout == 60) 32*7dc08ffcSJunyu Lai 33*7dc08ffcSJunyu Lai 34*7dc08ffcSJunyu Lai+ Bluetooth LE Advertising / Scan Response Data Parsing 35*7dc08ffcSJunyu Lai= Parse EIR_Flags, EIR_CompleteList16BitServiceUUIDs, EIR_CompleteLocalName and EIR_TX_Power_Level 36*7dc08ffcSJunyu Lai 37*7dc08ffcSJunyu Laiad_report_raw_data = \ 38*7dc08ffcSJunyu Lai hex_bytes("043e2b020100016522c00181781f0201020303d9fe1409" \ 39*7dc08ffcSJunyu Lai "506562626c652054696d65204c452037314536020a0cde") 40*7dc08ffcSJunyu Laiscapy_packet = HCI_Hdr(ad_report_raw_data) 41*7dc08ffcSJunyu Lai 42*7dc08ffcSJunyu Laiassert(scapy_packet[EIR_Flags].flags == 0x02) 43*7dc08ffcSJunyu Laiassert(scapy_packet[EIR_CompleteList16BitServiceUUIDs].svc_uuids == [0xfed9]) 44*7dc08ffcSJunyu Laiassert(scapy_packet[EIR_CompleteLocalName].local_name == b'Pebble Time LE 71E6') 45*7dc08ffcSJunyu Laiassert(scapy_packet[EIR_TX_Power_Level].level == 12) 46*7dc08ffcSJunyu Lai 47*7dc08ffcSJunyu Lai= Parse EIR_Manufacturer_Specific_Data 48*7dc08ffcSJunyu Lai 49*7dc08ffcSJunyu Laiscan_resp_raw_data = \ 50*7dc08ffcSJunyu Lai hex_bytes("043e2302010401be5e0eb9f04f1716ff5401005f423331" \ 51*7dc08ffcSJunyu Lai "3134374432343631fc00030c0000de") 52*7dc08ffcSJunyu Laiscapy_packet = HCI_Hdr(scan_resp_raw_data) 53*7dc08ffcSJunyu Lai 54*7dc08ffcSJunyu Laiassert(scapy_packet[EIR_Manufacturer_Specific_Data].data == b'\x00_B31147D2461\xfc\x00\x03\x0c\x00\x00') 55*7dc08ffcSJunyu Laiassert(scapy_packet[EIR_Manufacturer_Specific_Data].company_id == 0x154) 56*7dc08ffcSJunyu Lai 57*7dc08ffcSJunyu Lai= Basic L2CAP dissect 58*7dc08ffcSJunyu Laia = L2CAP_Hdr(b'\x08\x00\x06\x00\t\x00\xf6\xe5\xd4\xc3\xb2\xa1') 59*7dc08ffcSJunyu Laiassert a[SM_Identity_Address_Information].address == 'a1:b2:c3:d4:e5:f6' 60*7dc08ffcSJunyu Laiassert a[SM_Identity_Address_Information].atype == 0 61*7dc08ffcSJunyu Laia.show() 62*7dc08ffcSJunyu Lai 63*7dc08ffcSJunyu Lai= Basic HCI_ACL_Hdr build & dissect 64*7dc08ffcSJunyu Laia = HCI_Hdr()/HCI_ACL_Hdr(handle=0xf4c, PB=2, BC=2, len=20)/L2CAP_Hdr(len=16)/L2CAP_CmdHdr(code=8, len=12)/Raw("A"*12) 65*7dc08ffcSJunyu Laiassert raw(a) == b'\x02L\xaf\x14\x00\x10\x00\x05\x00\x08\x00\x0c\x00AAAAAAAAAAAA' 66*7dc08ffcSJunyu Laib = HCI_Hdr(raw(a)) 67*7dc08ffcSJunyu Laiassert a == b 68*7dc08ffcSJunyu Lai 69*7dc08ffcSJunyu Lai= Complex HCI - L2CAP build 70*7dc08ffcSJunyu Laia = HCI_Hdr()/HCI_ACL_Hdr()/L2CAP_Hdr()/L2CAP_CmdHdr()/L2CAP_ConnReq(scid=1) 71*7dc08ffcSJunyu Laiassert raw(a) == b'\x02\x00\x00\x0c\x00\x08\x00\x05\x00\x02\x00\x04\x00\x00\x00\x01\x00' 72*7dc08ffcSJunyu Laia.show() 73*7dc08ffcSJunyu Lai 74*7dc08ffcSJunyu Lai= Complex HCI - L2CAP dissect 75*7dc08ffcSJunyu Laia = HCI_Hdr(b'\x02\x00\x00\x11\x00\r\x00\x05\x00\x0b\x00\t\x00\x01\x00\x00\x00debug') 76*7dc08ffcSJunyu Laiassert a[L2CAP_InfoResp].result == 0 77*7dc08ffcSJunyu Laiassert a[L2CAP_InfoResp].data == b"debug" 78*7dc08ffcSJunyu Lai 79*7dc08ffcSJunyu Lai= Answers 80*7dc08ffcSJunyu Laia = HCI_Hdr(b'\x02\x00\x00\x0c\x00\x08\x00\x05\x00\x02\x00\x04\x00\x00\x00\x9a;') 81*7dc08ffcSJunyu Laib = HCI_Hdr(b'\x02\x00\x00\x10\x00\x0c\x00\x05\x00\x03\x00\x08\x00\x9a;\x00\x00\x00\x00\x01\x00') 82*7dc08ffcSJunyu Laiassert b.answers(a) 83*7dc08ffcSJunyu Laiassert not a.answers(b) 84*7dc08ffcSJunyu Lai 85*7dc08ffcSJunyu Laia = HCI_Hdr(b'\x02\x00\x00\x0c\x00\x08\x00\x05\x00\x04\x00\x04\x00\x15\x00\x00\x00') 86*7dc08ffcSJunyu Laib = HCI_Hdr(b'\x02\x00\x00\x0e\x00\n\x00\x05\x00\x05\x00\x06\x00\x15\x00\x00\x00\x02\x00') 87*7dc08ffcSJunyu Laiassert b.answers(a) 88*7dc08ffcSJunyu Laiassert not a.answers(b) 89*7dc08ffcSJunyu Lai 90*7dc08ffcSJunyu Lai= EIR_Hdr - misc 91*7dc08ffcSJunyu Laia = HCI_Hdr()/HCI_Event_Hdr()/HCI_Event_LE_Meta()/HCI_LE_Meta_Advertising_Report(addr = "a1:b2:c3:d4:e5:f6", data=EIR_Hdr()/EIR_CompleteLocalName(local_name="scapy")) 92*7dc08ffcSJunyu Laiassert raw(a) == b'\x04>\x00\x02\x00\x00\x00\xf6\xe5\xd4\xc3\xb2\xa1\x07\x06\tscapy\x00' 93*7dc08ffcSJunyu Laib = HCI_Hdr(raw(a)) 94*7dc08ffcSJunyu Laiassert b.data[0][EIR_CompleteLocalName].local_name == b"scapy" 95*7dc08ffcSJunyu Laiassert b[HCI_LE_Meta_Advertising_Report].addr == "a1:b2:c3:d4:e5:f6" 96*7dc08ffcSJunyu Lai 97*7dc08ffcSJunyu Laiassert a.summary() == "HCI Event / HCI_Event_Hdr / HCI_Event_LE_Meta / HCI_LE_Meta_Advertising_Report" 98*7dc08ffcSJunyu Lai 99*7dc08ffcSJunyu Lai= ATT_Hdr - misc 100*7dc08ffcSJunyu Laia = HCI_Hdr()/HCI_ACL_Hdr()/L2CAP_Hdr()/ATT_Hdr()/ATT_Read_By_Type_Request_128bit(uuid1=0xa14, uuid2=0xa24) 101*7dc08ffcSJunyu Laia = HCI_Hdr(raw(a)) 102*7dc08ffcSJunyu Laia.show() 103*7dc08ffcSJunyu Laia.mysummary() 104*7dc08ffcSJunyu Laiassert ATT_Read_By_Type_Request_128bit in a 105*7dc08ffcSJunyu Laiassert not Raw in a 106*7dc08ffcSJunyu Lai 107*7dc08ffcSJunyu Laib = HCI_Hdr()/HCI_ACL_Hdr()/L2CAP_Hdr()/ATT_Hdr()/ATT_Read_By_Type_Request(uuid=0xa14) 108*7dc08ffcSJunyu Laib = HCI_Hdr(raw(b)) 109*7dc08ffcSJunyu Laib.show() 110*7dc08ffcSJunyu Laib.mysummary() 111*7dc08ffcSJunyu Laiassert ATT_Read_By_Type_Request in b 112*7dc08ffcSJunyu Laiassert not Raw in b 113