1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdint.h>
17 
18 #include "hci/hci.h"
19 
20 #include "btm_snoop_filter.h"
21 
22 #pragma pack(1)
23 typedef struct {
24     uint8_t eventCode;
25     uint8_t parameterTotalLength;
26 } HciEventHeader;
27 #pragma pack()
28 
29 typedef struct {
30     BtmFilterFunc evtFunc;
31     uint16_t EvtDataOffset;
32 } HciEventFilterFunc;
33 
HciCommonFilterAddress(uint8_t * param)34 static void HciCommonFilterAddress(uint8_t *param)
35 {
36     BtmFilterAddress(param, BT_ADDRESS_SIZE);
37 }
38 
HciLeAdvertisingReportEventFilter(uint8_t * param)39 static void HciLeAdvertisingReportEventFilter(uint8_t *param)
40 {
41     uint8_t offset = 0;
42     uint8_t *numReports = param + offset;
43     offset += sizeof(uint8_t);
44 
45     for (int ii = 0; ii < *numReports; ii++) {
46         HciLeAdvertisingReport *report = (HciLeAdvertisingReport *)(param + offset);
47         offset += offsetof(HciLeAdvertisingReport, data);
48         offset += report->lengthData;
49         offset += sizeof(report->rssi);
50         BtmFilterAddress((uint8_t *)&report->address, BT_ADDRESS_SIZE);
51     }
52 }
53 
HciLeEnhancedConnectionCompleteEventFilter(uint8_t * param)54 static void HciLeEnhancedConnectionCompleteEventFilter(uint8_t *param)
55 {
56     BtmFilterAddress((uint8_t *)&((HciLeEnhancedConnectionCompleteEventParam *)param)->peerAddress, BT_ADDRESS_SIZE);
57     BtmFilterAddress((uint8_t *)&((HciLeEnhancedConnectionCompleteEventParam *)param)->peerResolvablePrivateAddress,
58         BT_ADDRESS_SIZE);
59     BtmFilterAddress((uint8_t *)&((HciLeEnhancedConnectionCompleteEventParam *)param)->localResolvablePrivateAddress,
60         BT_ADDRESS_SIZE);
61 }
62 
HciLeDirectedAdvertisingReportEventFilter(uint8_t * param)63 static void HciLeDirectedAdvertisingReportEventFilter(uint8_t *param)
64 {
65     uint8_t offset = 0;
66     uint8_t *numReports = param + offset;
67     offset += sizeof(uint8_t);
68 
69     for (int ii = 0; ii < *numReports; ii++) {
70         HciLeDirectedAdvertisingReport *report = (HciLeDirectedAdvertisingReport *)(param + offset);
71         offset += sizeof(HciLeDirectedAdvertisingReport);
72         BtmFilterAddress((uint8_t *)&report->address, BT_ADDRESS_SIZE);
73         BtmFilterAddress((uint8_t *)&report->directAddress, BT_ADDRESS_SIZE);
74     }
75 }
76 
HciLeExtendedAdvertisingReportEventFilter(uint8_t * param)77 static void HciLeExtendedAdvertisingReportEventFilter(uint8_t *param)
78 {
79     uint8_t offset = 0;
80     uint8_t *numReports = param + offset;
81     offset += sizeof(uint8_t);
82 
83     for (int ii = 0; ii < *numReports; ii++) {
84         HciLeExtendedAdvertisingReport *report = (HciLeExtendedAdvertisingReport *)(param + offset);
85         offset += offsetof(HciLeExtendedAdvertisingReport, data);
86         offset += report->dataLength;
87         offset += report->rssi;
88         BtmFilterAddress((uint8_t *)&report->address, BT_ADDRESS_SIZE);
89         BtmFilterAddress((uint8_t *)&report->directAddress, BT_ADDRESS_SIZE);
90     }
91 }
92 
93 static const HciEventFilterFunc G_LE_EVT_FILTER_FUNC_MAP[HCI_LE_EVENT_MAX_NUM + 1] = {
94     {NULL, 0},
95     {HciCommonFilterAddress, offsetof(HciLeConnectionCompleteEventParam, peerAddress)},
96     {HciLeAdvertisingReportEventFilter, 0},
97     {NULL, 0},
98     {NULL, 0},
99     {NULL, 0},
100     {NULL, 0},
101     {NULL, 0},
102     {NULL, 0},
103     {NULL, 0},
104     {HciLeEnhancedConnectionCompleteEventFilter, 0},
105     {HciLeDirectedAdvertisingReportEventFilter, 0},
106     {NULL, 0},
107     {HciLeExtendedAdvertisingReportEventFilter, 0},
108     {NULL, 0},
109     {NULL, 0},
110     {NULL, 0},
111     {NULL, 0},
112     {NULL, 0},
113     {HciCommonFilterAddress, offsetof(HciLeScanRequestReceivedEventParam, scannerAddress)},
114     {NULL, 0},
115 };
116 
HciInquiryResultEventFilter(uint8_t * param)117 static void HciInquiryResultEventFilter(uint8_t *param)
118 {
119     uint8_t offset = 0;
120     uint8_t *numResponses = param + offset;
121     offset += sizeof(uint8_t);
122 
123     for (int ii = 0; ii < *numResponses; ii++) {
124         HciInquiryResult *result = (HciInquiryResult *)(param + offset);
125         offset += sizeof(HciInquiryResult);
126         BtmFilterAddress((uint8_t *)&result->bdAddr, BT_ADDRESS_SIZE);
127     }
128 }
129 
HciReturnLinkKeysEventFilter(uint8_t * param)130 static void HciReturnLinkKeysEventFilter(uint8_t *param)
131 {
132     uint8_t offset = 0;
133     uint8_t *numKeys = param + offset;
134     offset += sizeof(uint8_t);
135 
136     for (int ii = 0; ii < *numKeys; ii++) {
137         HciReturnLinkKeys *keys = (HciReturnLinkKeys *)(param + offset);
138         offset += sizeof(HciReturnLinkKeys);
139         BtmFilterAddress((uint8_t *)&keys->bdAddr, BT_ADDRESS_SIZE);
140     }
141 }
142 
HciInquiryResultWithRssiEventFilter(uint8_t * param)143 static void HciInquiryResultWithRssiEventFilter(uint8_t *param)
144 {
145     uint8_t offset = 0;
146     uint8_t *numResponses = param + offset;
147     offset += sizeof(uint8_t);
148 
149     for (int ii = 0; ii < *numResponses; ii++) {
150         HciInquiryResultWithRssi *result = (HciInquiryResultWithRssi *)(param + offset);
151         offset += sizeof(HciInquiryResultWithRssi);
152         BtmFilterAddress((uint8_t *)&result->bdAddr, BT_ADDRESS_SIZE);
153     }
154 }
155 
156 static const HciEventFilterFunc G_EVT_FILTER_FUNC_MAP[HCI_EVENT_MAX_NUM + 1] = {
157     {NULL, 0},
158     {NULL, 0},
159     {HciInquiryResultEventFilter, 0},
160     {HciCommonFilterAddress, offsetof(HciConnectionCompleteEventParam, bdAddr)},
161     {HciCommonFilterAddress, offsetof(HciConnectionRequestEventParam, bdAddr)},
162     {NULL, 0},
163     {NULL, 0},
164     {HciCommonFilterAddress, offsetof(HciRemoteNameRequestCompleteEventParam, bdAddr)},
165     {NULL, 0},
166     {NULL, 0},
167     {NULL, 0},
168     {NULL, 0},
169     {NULL, 0},
170     {NULL, 0},
171     {NULL, 0},
172     {NULL, 0},
173     {NULL, 0},
174     {NULL, 0},
175     {HciCommonFilterAddress, offsetof(HciRoleChangeEventParam, bdAddr)},
176     {NULL, 0},
177     {NULL, 0},
178     {HciReturnLinkKeysEventFilter, 0},
179     {HciCommonFilterAddress, offsetof(HciPinCodeRequestEventParam, bdAddr)},
180     {HciCommonFilterAddress, offsetof(HciLinkKeyRequestEventParam, bdAddr)},
181     {HciCommonFilterAddress, offsetof(HciLinkKeyNotificationEventParam, bdAddr)},
182     {NULL, 0},
183     {NULL, 0},
184     {NULL, 0},
185     {NULL, 0},
186     {NULL, 0},
187     {NULL, 0},
188     {NULL, 0},
189     {HciCommonFilterAddress, offsetof(HciPageScanRepetitionModeChangeEventParam, bdAddr)},
190     {NULL, 0},
191     {HciInquiryResultWithRssiEventFilter, 0},
192     {NULL, 0},
193     {NULL, 0},
194     {NULL, 0},
195     {NULL, 0},
196     {NULL, 0},
197     {NULL, 0},
198     {NULL, 0},
199     {NULL, 0},
200     {NULL, 0},
201     {HciCommonFilterAddress, offsetof(HciSynchronousConnectionCompleteEventParam, bdAddr)},
202     {NULL, 0},
203     {NULL, 0},
204     {HciCommonFilterAddress, offsetof(HciExtendedInquiryResultEventParam, bdAddr)},
205     {NULL, 0},
206     {HciCommonFilterAddress, offsetof(HciIoCapabilityRequestEventParam, bdAddr)},
207     {HciCommonFilterAddress, offsetof(HciIoCapabilityResponseEventParam, bdAddr)},
208     {HciCommonFilterAddress, offsetof(HciUserConfirmationRequestEventParam, bdAddr)},
209     {HciCommonFilterAddress, offsetof(HciUserPasskeyRequestEventParam, bdAddr)},
210     {HciCommonFilterAddress, offsetof(HciRemoteOobDataRequestEventParam, bdAddr)},
211     {HciCommonFilterAddress, offsetof(HciSimplePairingCompleteEventParam, bdAddr)},
212     {NULL, 0},
213     {NULL, 0},
214     {NULL, 0},
215     {NULL, 0},
216     {HciCommonFilterAddress, offsetof(HciUserPasskeyNotificationEventParam, bdAddr)},
217     {HciCommonFilterAddress, offsetof(HciKeypressNotificationEventParam, bdAddr)},
218     {HciCommonFilterAddress, offsetof(HciRemoteHostSupportedFeaturesNotificationEventParam, addr)},
219     {NULL, 0},
220     {NULL, 0},
221     {NULL, 0},
222     {NULL, 0},
223     {NULL, 0},
224     {NULL, 0},
225     {NULL, 0},
226     {NULL, 0},
227     {NULL, 0},
228     {NULL, 0},
229     {NULL, 0},
230     {NULL, 0},
231     {NULL, 0},
232     {NULL, 0},
233     {NULL, 0},
234     {NULL, 0},
235     {NULL, 0},
236     {NULL, 0},
237     {HciCommonFilterAddress, offsetof(HciSynchronizationTrainReceivedEventParam, bdAdddr)},
238     {HciCommonFilterAddress, offsetof(HciConnectionlessSlaveBroadcastReceiveEventParam, bdAddr)},
239     {HciCommonFilterAddress, offsetof(HciConnectionlessSlaveBroadcastTimeoutEventParam, bdAddr)},
240     {HciCommonFilterAddress, offsetof(HciTruncatedPageCompleteEventParam, bdAddr)},
241 };
242 
HciEvtFilter(const uint8_t ** data,uint16_t originalLength,uint16_t * includedLength)243 void HciEvtFilter(const uint8_t **data, uint16_t originalLength, uint16_t *includedLength)
244 {
245     if (originalLength < sizeof(HciEventHeader)) {
246         return;
247     }
248 
249     BtmFilterCheckAndSaveAclConnInfo(data, originalLength);
250 
251     uint8_t offset = 0;
252     HciEventHeader *header = (HciEventHeader *)(*data + offset);
253     offset += sizeof(HciEventHeader);
254     const HciEventFilterFunc *filterFuncInfo = NULL;
255 
256     if (header->eventCode == HCI_COMMAND_COMPLETE_EVENT) {
257         BtmFilterHciCmdCompleteEvt(data, originalLength, includedLength);
258     } else if (header->eventCode == HCI_LE_META_EVENT) {
259         const uint8_t *subEvtCode = *data + offset;
260         offset += sizeof(uint8_t);
261         filterFuncInfo = &G_LE_EVT_FILTER_FUNC_MAP[*subEvtCode];
262     } else {
263         filterFuncInfo = &G_EVT_FILTER_FUNC_MAP[header->eventCode];
264     }
265 
266     if (filterFuncInfo != NULL && filterFuncInfo->evtFunc != NULL) {
267         uint8_t *copyData = BtmCreateFilterBuffer(includedLength, *data);
268         filterFuncInfo->evtFunc(copyData + offset + filterFuncInfo->EvtDataOffset);
269         *data = copyData;
270     }
271 }