/* * Copyright 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "model/devices/baseband_sniffer.h" #include #include #include #include #include #include #include "log.h" #include "packets/link_layer_packets.h" #include "pcap.h" #include "phy.h" namespace rootcanal { #include "bredr_bb.h" BaseBandSniffer::BaseBandSniffer(const std::string& filename) { output_.open(filename, std::ios::binary); uint32_t linktype = 255; // http://www.tcpdump.org/linktypes.html // LINKTYPE_BLUETOOTH_BREDR_BB pcap::WriteHeader(output_, linktype); output_.flush(); } void BaseBandSniffer::AppendRecord( std::unique_ptr packet) { std::vector bytes = packet->SerializeToBytes(); pcap::WriteRecordHeader(output_, bytes.size()); output_.write((char*)bytes.data(), bytes.size()); output_.flush(); } static uint8_t ReverseByte(uint8_t b) { static uint8_t lookup[16] = { [0b0000] = 0b0000, [0b0001] = 0b1000, [0b0010] = 0b0100, [0b0011] = 0b1100, [0b0100] = 0b0010, [0b0101] = 0b1010, [0b0110] = 0b0110, [0b0111] = 0b1110, [0b1000] = 0b0001, [0b1001] = 0b1001, [0b1010] = 0b0101, [0b1011] = 0b1101, [0b1100] = 0b0011, [0b1101] = 0b1011, [0b1110] = 0b0111, [0b1111] = 0b1111, }; return (lookup[b & 0xF] << 4) | lookup[b >> 4]; } static uint8_t HeaderErrorCheck(uint8_t uap, uint32_t data) { // See Bluetooth Core, Vol 2, Part B, 7.1.1 uint8_t value = ReverseByte(uap); for (auto i = 0; i < 10; i++) { bool bit = (value ^ data) & 1; data >>= 1; value >>= 1; if (bit) { value ^= 0xe5; } } return value; } static uint32_t BuildBtPacketHeader(uint8_t uap, uint8_t lt_addr, uint8_t packet_type, bool flow, bool arqn, bool seqn) { // See Bluetooth Core, Vol2, Part B, 6.4 uint32_t header = (lt_addr & 0x7) | ((packet_type & 0xF) << 3) | (flow << 7) | (arqn << 8) | (seqn << 9); header |= (HeaderErrorCheck(uap, header) << 10); return header; } void BaseBandSniffer::ReceiveLinkLayerPacket( model::packets::LinkLayerPacketView packet, Phy::Type /*type*/, int8_t /*rssi*/) { auto packet_type = packet.GetType(); auto address = packet.GetSourceAddress(); // Bluetooth Core, Vol2, Part B, 1.2, Figure 1.5 uint32_t lap = address.data()[0] | (address.data()[1] << 8) | (address.data()[2] << 16); uint8_t uap = address.data()[3]; uint16_t nap = address.data()[4] | (address.data()[5] << 8); // http://www.whiterocker.com/bt/LINKTYPE_BLUETOOTH_BREDR_BB.html uint16_t flags = /* BT Packet Header and BR or EDR Payload are de-whitened */ 0x0001 | /* BR or EDR Payload is decrypted */ 0x0008 | /* Reference LAP is valid and led to this packet being captured */ 0x0010 | /* BR or EDR Payload is present and follows this field */ 0x0020 | /* Reference UAP field is valid for HEC and CRC checking */ 0x0080 | /* CRC portion of the BR or EDR Payload was checked */ 0x0400 | /* CRC portion of the BR or EDR Payload passed its check */ 0x0800; uint8_t lt_addr = 0; uint8_t rf_channel = 0; uint8_t signal_power = 0; uint8_t noise_power = 0; uint8_t access_code_offenses = 0; uint8_t corrected_header_bits = 0; uint16_t corrected_payload_bits = 0; uint8_t lower_address_part = lap; uint8_t reference_lap = lap; uint8_t reference_uap = uap; if (packet_type == model::packets::PacketType::PAGE) { auto page_view = model::packets::PageView::Create(packet); ASSERT(page_view.IsValid()); uint8_t bt_packet_type = 0b0010; // FHS AppendRecord(bredr_bb::FHSAclPacketBuilder::Create( rf_channel, signal_power, noise_power, access_code_offenses, corrected_header_bits, corrected_payload_bits, lower_address_part, reference_lap, reference_uap, BuildBtPacketHeader(uap, lt_addr, bt_packet_type, true, true, true), flags, 0, // parity_bits lap, 0, // eir 0, // sr 0, // sp uap, nap, page_view.GetClassOfDevice(), 1, // lt_addr 0, // clk 0, // page_scan_mode 0 // crc )); } else if (packet_type == model::packets::PacketType::LMP) { auto lmp_view = model::packets::LmpView::Create(packet); ASSERT(lmp_view.IsValid()); auto lmp_bytes = lmp_view.GetPayload(); uint8_t bt_packet_type = 0b0011; // DM1 AppendRecord(bredr_bb::DM1AclPacketBuilder::Create( rf_channel, signal_power, noise_power, access_code_offenses, corrected_header_bits, corrected_payload_bits, lower_address_part, reference_lap, reference_uap, BuildBtPacketHeader(uap, lt_addr, bt_packet_type, true, true, true), flags, 0x3, // llid 1, // flow std::move(lmp_bytes), 0 // crc )); } } } // namespace rootcanal