1 /*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "model/devices/baseband_sniffer.h"
18
19 #include <cstdint>
20 #include <ios>
21 #include <memory>
22 #include <string>
23 #include <utility>
24 #include <vector>
25
26 #include "log.h"
27 #include "packets/link_layer_packets.h"
28 #include "pcap.h"
29 #include "phy.h"
30
31 namespace rootcanal {
32
33 #include "bredr_bb.h"
34
BaseBandSniffer(const std::string & filename)35 BaseBandSniffer::BaseBandSniffer(const std::string& filename) {
36 output_.open(filename, std::ios::binary);
37
38 uint32_t linktype = 255; // http://www.tcpdump.org/linktypes.html
39 // LINKTYPE_BLUETOOTH_BREDR_BB
40
41 pcap::WriteHeader(output_, linktype);
42 output_.flush();
43 }
44
AppendRecord(std::unique_ptr<bredr_bb::BaseBandPacketBuilder> packet)45 void BaseBandSniffer::AppendRecord(
46 std::unique_ptr<bredr_bb::BaseBandPacketBuilder> packet) {
47 std::vector<uint8_t> bytes = packet->SerializeToBytes();
48 pcap::WriteRecordHeader(output_, bytes.size());
49 output_.write((char*)bytes.data(), bytes.size());
50 output_.flush();
51 }
52
ReverseByte(uint8_t b)53 static uint8_t ReverseByte(uint8_t b) {
54 static uint8_t lookup[16] = {
55 [0b0000] = 0b0000, [0b0001] = 0b1000, [0b0010] = 0b0100,
56 [0b0011] = 0b1100, [0b0100] = 0b0010, [0b0101] = 0b1010,
57 [0b0110] = 0b0110, [0b0111] = 0b1110, [0b1000] = 0b0001,
58 [0b1001] = 0b1001, [0b1010] = 0b0101, [0b1011] = 0b1101,
59 [0b1100] = 0b0011, [0b1101] = 0b1011, [0b1110] = 0b0111,
60 [0b1111] = 0b1111,
61 };
62
63 return (lookup[b & 0xF] << 4) | lookup[b >> 4];
64 }
65
HeaderErrorCheck(uint8_t uap,uint32_t data)66 static uint8_t HeaderErrorCheck(uint8_t uap, uint32_t data) {
67 // See Bluetooth Core, Vol 2, Part B, 7.1.1
68
69 uint8_t value = ReverseByte(uap);
70
71 for (auto i = 0; i < 10; i++) {
72 bool bit = (value ^ data) & 1;
73 data >>= 1;
74 value >>= 1;
75 if (bit) {
76 value ^= 0xe5;
77 }
78 }
79
80 return value;
81 }
82
BuildBtPacketHeader(uint8_t uap,uint8_t lt_addr,uint8_t packet_type,bool flow,bool arqn,bool seqn)83 static uint32_t BuildBtPacketHeader(uint8_t uap, uint8_t lt_addr,
84 uint8_t packet_type, bool flow, bool arqn,
85 bool seqn) {
86 // See Bluetooth Core, Vol2, Part B, 6.4
87
88 uint32_t header = (lt_addr & 0x7) | ((packet_type & 0xF) << 3) | (flow << 7) |
89 (arqn << 8) | (seqn << 9);
90
91 header |= (HeaderErrorCheck(uap, header) << 10);
92
93 return header;
94 }
95
ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView packet,Phy::Type,int8_t)96 void BaseBandSniffer::ReceiveLinkLayerPacket(
97 model::packets::LinkLayerPacketView packet, Phy::Type /*type*/,
98 int8_t /*rssi*/) {
99 auto packet_type = packet.GetType();
100 auto address = packet.GetSourceAddress();
101
102 // Bluetooth Core, Vol2, Part B, 1.2, Figure 1.5
103 uint32_t lap =
104 address.data()[0] | (address.data()[1] << 8) | (address.data()[2] << 16);
105 uint8_t uap = address.data()[3];
106 uint16_t nap = address.data()[4] | (address.data()[5] << 8);
107
108 // http://www.whiterocker.com/bt/LINKTYPE_BLUETOOTH_BREDR_BB.html
109 uint16_t flags =
110 /* BT Packet Header and BR or EDR Payload are de-whitened */ 0x0001 |
111 /* BR or EDR Payload is decrypted */ 0x0008 |
112 /* Reference LAP is valid and led to this packet being captured */
113 0x0010 |
114 /* BR or EDR Payload is present and follows this field */ 0x0020 |
115 /* Reference UAP field is valid for HEC and CRC checking */ 0x0080 |
116 /* CRC portion of the BR or EDR Payload was checked */ 0x0400 |
117 /* CRC portion of the BR or EDR Payload passed its check */ 0x0800;
118
119 uint8_t lt_addr = 0;
120
121 uint8_t rf_channel = 0;
122 uint8_t signal_power = 0;
123 uint8_t noise_power = 0;
124 uint8_t access_code_offenses = 0;
125 uint8_t corrected_header_bits = 0;
126 uint16_t corrected_payload_bits = 0;
127 uint8_t lower_address_part = lap;
128 uint8_t reference_lap = lap;
129 uint8_t reference_uap = uap;
130
131 if (packet_type == model::packets::PacketType::PAGE) {
132 auto page_view = model::packets::PageView::Create(packet);
133 ASSERT(page_view.IsValid());
134
135 uint8_t bt_packet_type = 0b0010; // FHS
136
137 AppendRecord(bredr_bb::FHSAclPacketBuilder::Create(
138 rf_channel, signal_power, noise_power, access_code_offenses,
139 corrected_header_bits, corrected_payload_bits, lower_address_part,
140 reference_lap, reference_uap,
141 BuildBtPacketHeader(uap, lt_addr, bt_packet_type, true, true, true),
142 flags,
143 0, // parity_bits
144 lap,
145 0, // eir
146 0, // sr
147 0, // sp
148 uap, nap, page_view.GetClassOfDevice(),
149 1, // lt_addr
150 0, // clk
151 0, // page_scan_mode
152 0 // crc
153 ));
154 } else if (packet_type == model::packets::PacketType::LMP) {
155 auto lmp_view = model::packets::LmpView::Create(packet);
156 ASSERT(lmp_view.IsValid());
157 auto lmp_bytes = lmp_view.GetPayload();
158 uint8_t bt_packet_type = 0b0011; // DM1
159
160 AppendRecord(bredr_bb::DM1AclPacketBuilder::Create(
161 rf_channel, signal_power, noise_power, access_code_offenses,
162 corrected_header_bits, corrected_payload_bits, lower_address_part,
163 reference_lap, reference_uap,
164 BuildBtPacketHeader(uap, lt_addr, bt_packet_type, true, true, true),
165 flags,
166 0x3, // llid
167 1, // flow
168 std::move(lmp_bytes),
169 0 // crc
170 ));
171 }
172 }
173
174 } // namespace rootcanal
175