1 /*
2  * Copyright (C) 2022 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 #include "../include/ble_scan_filter_lsf.h"
16 
17 namespace OHOS {
18 namespace bluetooth {
BleScanFilterLsf()19 BleScanFilterLsf::BleScanFilterLsf()
20 {
21     cmdTimer_ = std::make_unique<utility::Timer>(
22         std::bind(&BleScanFilterLsf::CommandTimeout, this));
23 }
24 
~BleScanFilterLsf()25 BleScanFilterLsf::~BleScanFilterLsf()
26 {
27     if (isReady_) {
28         HCIVIF_DeregisterVendorEventCallback(&VENDOR_EVENT_CALLBACK);
29         isReady_ = false;
30     }
31 }
32 
StartCommandTimer() const33 void BleScanFilterLsf::StartCommandTimer() const
34 {
35     cmdTimer_->Start(LSF_CMD_TIMEOUT_MS);
36     HILOGI("Start command timer!");
37 }
38 
StopCommandTimer() const39 void BleScanFilterLsf::StopCommandTimer() const
40 {
41     cmdTimer_->Stop();
42     HILOGI("Stop command timer!");
43 }
44 
CommandTimeout()45 void BleScanFilterLsf::CommandTimeout()
46 {
47     std::lock_guard<std::recursive_mutex> lk(mutex_);
48     if (!isBleScanFilterOngoing_) {
49         HILOGI("ble scan filter not ongoing.");
50         return;
51     }
52     switch (ongoingOpcode_) {
53         case LSF_OPCODE_ENABLE:
54             HandleEnableCommandResult(ongoingTag_, BLE_SCAN_FILTER_FAILD);
55             break;
56         case LSF_OPCODE_ADD:
57             HandleAddCommandResult(ongoingTag_, BLE_SCAN_FILTER_FAILD);
58             break;
59         case LSF_OPCODE_DELETE:
60             HandleDeleteCommandResult(ongoingTag_, BLE_SCAN_FILTER_FAILD);
61             break;
62         case LSF_OPCODE_CLEAR:
63             HandleClearCommandResult(ongoingTag_, BLE_SCAN_FILTER_FAILD);
64             break;
65         default:
66             HILOGI("unknow opcode.");
67             break;
68     }
69 }
70 
HandleEnableCommandResult(uint8_t tag,uint8_t status)71 void BleScanFilterLsf::HandleEnableCommandResult(uint8_t tag, uint8_t status)
72 {
73     HILOGI("tag:%{public}d, status:%{public}d", tag, status);
74     switch (tag) {
75         case LSF_PARAM_ENABLE:
76             StopCommandTimer();
77             FinishStartBleScanFilter(status);
78             break;
79         case LSF_PARAM_DISABLE:
80             StopCommandTimer();
81             FinishStopBleScanFilter(status);
82             break;
83         default:
84             HILOGI("unknow tag.");
85             break;
86     }
87 }
HandleAddCommandResult(uint8_t tag,uint8_t status)88 void BleScanFilterLsf::HandleAddCommandResult(uint8_t tag, uint8_t status)
89 {
90     HILOGI("tag:%{public}d, status:%{public}d", tag, status);
91     switch (tag) {
92         case LSF_TAG_SET_PARAMETERS:
93             StopCommandTimer();
94             FinishAddBleScanFilter(status);
95             break;
96         case LSF_TAG_ADDRESS:
97         case LSF_TAG_SERVICE_UUID:
98         case LSF_TAG_SOLICIT_UUID:
99         case LSF_TAG_NAME:
100         case LSF_TAG_MANUFACTURER_DATA:
101         case LSF_TAG_SERVICE_DATA:
102             if (status == BT_SUCCESS) {
103                 if (ContinueBleScanFilter() != BT_SUCCESS) {
104                     StopCommandTimer();
105                     FinishAddBleScanFilter(BLE_SCAN_FILTER_FAILD);
106                 }
107             } else {
108                 StopCommandTimer();
109                 FinishAddBleScanFilter(status);
110             }
111             break;
112         default:
113             HILOGI("unknow tag.");
114             break;
115     }
116 }
117 
HandleDeleteCommandResult(uint8_t tag,uint8_t status)118 void BleScanFilterLsf::HandleDeleteCommandResult(uint8_t tag, uint8_t status)
119 {
120     HILOGI("tag:%{public}d, status:%{public}d", tag, status);
121     switch (tag) {
122         case LSF_TAG_SET_PARAMETERS:
123             StopCommandTimer();
124             FinishDeleteBleScanFilter(status);
125             break;
126         default:
127             HILOGI("unknow tag.");
128             break;
129     }
130 }
131 
HandleClearCommandResult(uint8_t tag,uint8_t status)132 void BleScanFilterLsf::HandleClearCommandResult(uint8_t tag, uint8_t status)
133 {
134     HILOGI("tag:%{public}d, status:%{public}d", tag, status);
135     switch (tag) {
136         case LSF_TAG_SET_PARAMETERS:
137             StopCommandTimer();
138             if ((BleScanFilterEnable(LSF_PARAM_DISABLE) != BT_SUCCESS)) {
139                 StopCommandTimer();
140                 FinishStopBleScanFilter(BLE_SCAN_FILTER_FAILD);
141             }
142             break;
143         default:
144             HILOGI("unknow tag.");
145             break;
146     }
147 }
148 
IsReady()149 bool BleScanFilterLsf::IsReady()
150 {
151     if (!isReady_ && (HCIVIF_RegisterVendorEventCallback(&VENDOR_EVENT_CALLBACK, this) == BT_SUCCESS)) {
152         isReady_ = true;
153     }
154 
155     if (!isReady_) {
156         return false;
157     }
158 
159     return true;
160 }
161 
GetMaxFilterNumber()162 uint8_t BleScanFilterLsf::GetMaxFilterNumber()
163 {
164     if (!isSupportFilter_) {
165         HILOGI("not support filter.");
166         return 0;
167     }
168     if (maxFilterNumber_ > 0) {
169         return maxFilterNumber_;
170     }
171 
172     if (!IsReady()) {
173         HILOGI("ble scan filter not ready.");
174         return 0;
175     }
176     std::unique_lock<std::mutex> lock(mutexWaitCallback_);
177     if (BleScanFilterGetVendorCapabilities() != BT_SUCCESS) {
178         HILOGI("send vendor capabilities cmd faild.");
179         return 0;
180     }
181     if (cvfull_.wait_for(lock,
182         std::chrono::seconds(CAP_CMD_TIMEOUT_S)) == std::cv_status::timeout) {
183         HILOGI("GetMaxFilterNumber timeout");
184         return 0;
185     }
186 
187     return maxFilterNumber_;
188 }
189 
AddBleScanFilter(BleScanFilterParam filter,BleScanFilterCallback callback)190 int BleScanFilterLsf::AddBleScanFilter(BleScanFilterParam filter, BleScanFilterCallback callback)
191 {
192     std::lock_guard<std::recursive_mutex> lk(mutex_);
193     filterParam_ = filter;
194     filterFlag_ = filterParam_.filterFlag;
195     filtIndex_ = filterParam_.filtIndex;
196     callback_ = callback;
197 
198     if (!IsReady()) {
199         HILOGI("ble scan filter not ready.");
200     } else if (isBleScanFilterOngoing_) {
201         HILOGI("ble scan filter is ongoing.");
202     } else if ((maxFilterNumber_ > 0) && (filtIndex_ >= maxFilterNumber_)) {
203         HILOGI("filter index error.");
204     } else if (ContinueBleScanFilter() != BT_SUCCESS) {
205         HILOGI("ContinueBleScanFilter error.");
206         StopCommandTimer();
207     } else {
208         isBleScanFilterOngoing_ = true;
209         return BT_SUCCESS;
210     }
211 
212     FinishAddBleScanFilter(BLE_SCAN_FILTER_FAILD);
213     return RET_BAD_STATUS;
214 }
215 
DeleteBleScanFilter(BleScanFilterParam filter,BleScanFilterCallback callback)216 int BleScanFilterLsf::DeleteBleScanFilter(BleScanFilterParam filter, BleScanFilterCallback callback)
217 {
218     std::lock_guard<std::recursive_mutex> lk(mutex_);
219     filtIndex_ = filter.filtIndex;
220     callback_ = callback;
221 
222     if (!IsReady()) {
223         HILOGI("ble scan filter not ready.");
224     } else if (isBleScanFilterOngoing_) {
225         HILOGI("ble scan filter is ongoing.");
226     } else if (BleScanFilterSetParameters(0, LSF_OPCODE_DELETE) != BT_SUCCESS) {
227         HILOGI("BleScanFilterSetParameters error.");
228         StopCommandTimer();
229     } else {
230         isBleScanFilterOngoing_ = true;
231         return BT_SUCCESS;
232     }
233 
234     FinishDeleteBleScanFilter(BLE_SCAN_FILTER_FAILD);
235     return RET_BAD_STATUS;
236 }
237 
StartBleScanFilter(BleScanFilterCallback callback)238 int BleScanFilterLsf::StartBleScanFilter(BleScanFilterCallback callback)
239 {
240     std::lock_guard<std::recursive_mutex> lk(mutex_);
241     callback_ = callback;
242 
243     if (!IsReady()) {
244         HILOGI("ble scan filter not ready.");
245     } else if (isBleScanFilterOngoing_) {
246         HILOGI("ble scan filter is ongoing.");
247     } else if (BleScanFilterEnable(LSF_PARAM_ENABLE) != BT_SUCCESS) {
248         HILOGI("BleScanFilterEnable error.");
249         StopCommandTimer();
250     } else {
251         isBleScanFilterOngoing_ = true;
252         return BT_SUCCESS;
253     }
254 
255     FinishStartBleScanFilter(BLE_SCAN_FILTER_FAILD);
256     return RET_BAD_STATUS;
257 }
258 
StopBleScanFilter(BleScanFilterCallback callback)259 int BleScanFilterLsf::StopBleScanFilter(BleScanFilterCallback callback)
260 {
261     std::lock_guard<std::recursive_mutex> lk(mutex_);
262     callback_ = callback;
263 
264     if (!IsReady()) {
265         HILOGI("ble scan filter not ready.");
266     } else if (isBleScanFilterOngoing_) {
267         HILOGI("ble scan filter is ongoing.");
268     } else if (BleScanFilterSetParameters(0, LSF_OPCODE_CLEAR) != BT_SUCCESS) {
269         HILOGI("BleScanFilterSetParameters error.");
270         StopCommandTimer();
271     } else {
272         isBleScanFilterOngoing_ = true;
273         return BT_SUCCESS;
274     }
275 
276     FinishStopBleScanFilter(BLE_SCAN_FILTER_FAILD);
277     return RET_BAD_STATUS;
278 }
279 
ContinueBleScanFilter()280 int BleScanFilterLsf::ContinueBleScanFilter()
281 {
282     StopCommandTimer();
283     if ((filterFlag_ & FILTER_FLAG_ADDRESS) != 0) {
284         filterFlag_ &= ~FILTER_FLAG_ADDRESS;
285         return BleScanFilterAddressAdd(filterParam_.address);
286     } else if ((filterFlag_ & FILTER_FLAG_SERVICE_UUID) != 0) {
287         filterFlag_ &= ~FILTER_FLAG_SERVICE_UUID;
288         return BleScanFilterUuidAdd(filterParam_.serviceUuid, filterParam_.serviceUuidMask, LSF_TAG_SERVICE_UUID);
289     } else if ((filterFlag_ & FILTER_FLAG_SOLICIT_UUID) != 0) {
290         filterFlag_ &= ~FILTER_FLAG_SOLICIT_UUID;
291         return BleScanFilterUuidAdd(filterParam_.solicitationUuid, filterParam_.solicitationUuidMask,
292             LSF_TAG_SOLICIT_UUID);
293     } else if ((filterFlag_ & FILTER_FLAG_NAME) != 0) {
294         filterFlag_ &= ~FILTER_FLAG_NAME;
295         return BleScanFilterNameAdd(filterParam_.name);
296     } else if ((filterFlag_ & FILTER_FLAG_MANUFACTURER_DATA) != 0) {
297         filterFlag_ &= ~FILTER_FLAG_MANUFACTURER_DATA;
298         return BleScanFilterManufacturerDataAdd(filterParam_.manufacturerId, filterParam_.manufacturerIdMask,
299             filterParam_.manufacturerData, filterParam_.manufacturerDataMask);
300     } else if ((filterFlag_ & FILTER_FLAG_SERVICE_DATA) != 0) {
301         filterFlag_ &= ~FILTER_FLAG_SERVICE_DATA;
302         return BleScanFilterServiceDataAdd(filterParam_.serviceData, filterParam_.serviceDataMask);
303     } else {
304         filterFlag_ = 0;
305         return BleScanFilterSetParameters(filterParam_.filterFlag, LSF_OPCODE_ADD);
306     }
307 
308     return BT_SUCCESS;
309 }
310 
FinishAddBleScanFilter(int result)311 void BleScanFilterLsf::FinishAddBleScanFilter(int result)
312 {
313     if (callback_.addBleScanFilterResult != nullptr) {
314         callback_.addBleScanFilterResult(result, callback_.context);
315     }
316     ClearCommand();
317 }
318 
FinishDeleteBleScanFilter(int result)319 void BleScanFilterLsf::FinishDeleteBleScanFilter(int result)
320 {
321     if (callback_.deleteBleScanFilterResult != nullptr) {
322         callback_.deleteBleScanFilterResult(result, callback_.context);
323     }
324     ClearCommand();
325 }
326 
FinishStartBleScanFilter(int result)327 void BleScanFilterLsf::FinishStartBleScanFilter(int result)
328 {
329     if (callback_.startBleScanFilterResult != nullptr) {
330         callback_.startBleScanFilterResult(result, callback_.context);
331     }
332     ClearCommand();
333 }
334 
FinishStopBleScanFilter(int result)335 void BleScanFilterLsf::FinishStopBleScanFilter(int result)
336 {
337     if (callback_.stopBleScanFilterResult != nullptr) {
338         callback_.stopBleScanFilterResult(result, callback_.context);
339     }
340     ClearCommand();
341 }
342 
ClearCommand()343 void BleScanFilterLsf::ClearCommand()
344 {
345     isBleScanFilterOngoing_ = false;
346     ongoingOpcode_ = 0;
347     ongoingTag_ = 0;
348     filtIndex_ = 0;
349     filterParam_ = {};
350     callback_ = {};
351     filterFlag_ = 0;
352 }
353 
BleScanFilterGetVendorCapabilities() const354 int BleScanFilterLsf::BleScanFilterGetVendorCapabilities() const
355 {
356     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_GET_CAPABILITIES);
357     uint8_t version = 0;
358 
359     return HCIVIF_SendCmd(opCode, &version, 1);
360 }
361 
BleScanFilterEnable(uint8_t enable)362 int BleScanFilterLsf::BleScanFilterEnable(uint8_t enable)
363 {
364     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
365     VendorCmdParamLSFEnable param = {};
366     param.opcode = LSF_OPCODE_ENABLE;
367     param.enable = enable;
368     ongoingOpcode_ = param.opcode;
369     ongoingTag_ = param.enable;
370     StartCommandTimer();
371 
372     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), sizeof(VendorCmdParamLSFEnable));
373 }
374 
BleScanFilterSetParameters(uint16_t featureSelection,uint8_t opcode)375 int BleScanFilterLsf::BleScanFilterSetParameters(uint16_t featureSelection, uint8_t opcode)
376 {
377     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
378     size_t paramLength = LSF_CMD_HEAD_LENGTH;
379     VendorCmdParamLSFSetParameters param = {};
380     param.opcode = opcode;
381     param.tag = LSF_TAG_SET_PARAMETERS;
382     param.filtIndex = filtIndex_;
383     if (opcode == LSF_OPCODE_ADD) {
384         param.featureSelection = featureSelection;
385         param.listLogicType = LSF_CMD_LIST_LOGIC_TYPE;
386         param.logicType = LSF_CMD_LOGIC_TYPE;
387         paramLength = sizeof(VendorCmdParamLSFSetParameters);
388     }
389     ongoingOpcode_ = param.opcode;
390     ongoingTag_ = param.tag;
391     StartCommandTimer();
392 
393     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), paramLength);
394 }
395 
BleScanFilterAddressAdd(BtAddr address)396 int BleScanFilterLsf::BleScanFilterAddressAdd(BtAddr address)
397 {
398     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
399     VendorCmdParamLSFAddress param = {};
400     param.opcode = LSF_OPCODE_ADD;
401     param.tag = LSF_TAG_ADDRESS;
402     param.filtIndex = filtIndex_;
403     param.address = address;
404     ongoingOpcode_ = param.opcode;
405     ongoingTag_ = param.tag;
406     StartCommandTimer();
407 
408     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), sizeof(VendorCmdParamLSFAddress));
409 }
410 
BleScanFilterUuidAdd(Uuid uuid,Uuid uuidMask,uint8_t tag)411 int BleScanFilterLsf::BleScanFilterUuidAdd(Uuid uuid, Uuid uuidMask, uint8_t tag)
412 {
413     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
414     size_t paramLength = 0;
415     int uuidType = uuid.GetUuidType();
416     VendorCmdParamLSFUuid param = {};
417     param.opcode = LSF_OPCODE_ADD;
418     param.tag = tag;
419     param.filtIndex = filtIndex_;
420     paramLength = uuidType;
421     VendorCmdParamUuidData uuidData = {0};
422     VendorCmdParamUuidData uuidMaskData = {0};
423     if (uuidType == Uuid::UUID16_BYTES_TYPE) {
424         uuidData.uuid16 = uuid.ConvertTo16Bits();
425         uuidMaskData.uuid16 = uuidMask.ConvertTo16Bits();
426     } else if (uuidType == Uuid::UUID32_BYTES_TYPE) {
427         uuidData.uuid32 = uuid.ConvertTo32Bits();
428         uuidMaskData.uuid32 = uuidMask.ConvertTo32Bits();
429     } else if (uuidType == Uuid::UUID128_BYTES_TYPE) {
430         if (!uuid.ConvertToBytesLE(uuidData.uuid128)) {
431             HILOGI("get uuid faild.");
432             return RET_BAD_STATUS;
433         }
434         if (!uuidMask.ConvertToBytesLE(uuidMaskData.uuid128)) {
435             HILOGI("get uuid mask faild.");
436             return RET_BAD_STATUS;
437         }
438     } else {
439         HILOGI("error uuid type(%{public}d).", uuidType);
440         return RET_BAD_STATUS;
441     }
442     if (memcpy_s(param.uuidAndMask, sizeof(param.uuidAndMask), &uuidData, paramLength) != EOK) {
443         HILOGI("copy uuid faild.");
444         return RET_BAD_STATUS;
445     }
446     if (memcpy_s(param.uuidAndMask + paramLength, sizeof(param.uuidAndMask) - paramLength,
447         &uuidMaskData, paramLength) != EOK) {
448         HILOGI("copy uuid mask faild.");
449         return RET_BAD_STATUS;
450     }
451     paramLength += uuidType;
452     paramLength += LSF_CMD_HEAD_LENGTH;
453     ongoingOpcode_ = param.opcode;
454     ongoingTag_ = param.tag;
455     StartCommandTimer();
456 
457     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), paramLength);
458 }
459 
BleScanFilterNameAdd(std::string name)460 int BleScanFilterLsf::BleScanFilterNameAdd(std::string name)
461 {
462     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
463     size_t paramLength = 0;
464     VendorCmdParamLSFName param = {};
465     param.opcode = LSF_OPCODE_ADD;
466     param.tag = LSF_TAG_NAME;
467     param.filtIndex = filtIndex_;
468     if (name.size() > LSF_CMD_MAX_LENGTH) {
469         param.length = LSF_CMD_MAX_LENGTH;
470     } else {
471         param.length = name.size();
472     }
473     paramLength += param.length + 1;
474     if (param.length > 0) {
475         if (memcpy_s(param.name, sizeof(param.name), name.c_str(), param.length) != EOK) {
476             HILOGI("copy name faild.");
477             return RET_BAD_STATUS;
478         }
479     }
480     paramLength += LSF_CMD_HEAD_LENGTH;
481     ongoingOpcode_ = param.opcode;
482     ongoingTag_ = param.tag;
483     StartCommandTimer();
484     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), paramLength);
485 }
486 
BleScanFilterManufacturerDataAdd(uint16_t manufacturerId,uint16_t manufacturerIdMask,std::vector<uint8_t> manufacturerData,std::vector<uint8_t> manufacturerDataMask)487 int BleScanFilterLsf::BleScanFilterManufacturerDataAdd(uint16_t manufacturerId, uint16_t manufacturerIdMask,
488     std::vector<uint8_t> manufacturerData, std::vector<uint8_t> manufacturerDataMask)
489 {
490     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
491     size_t paramLength = 0;
492     uint8_t manufacturerIdLength = sizeof(uint16_t);
493     uint8_t manufacturerDataLength = 0;
494     VendorCmdParamLSFData param = {};
495     param.opcode = LSF_OPCODE_ADD;
496     param.tag = LSF_TAG_MANUFACTURER_DATA;
497     param.filtIndex = filtIndex_;
498     param.data[paramLength++] = manufacturerDataLength + manufacturerIdLength;
499 
500     if (memcpy_s(param.data, sizeof(param.data), &manufacturerId, manufacturerIdLength) != EOK) {
501         HILOGI("copy manufacturerId faild.");
502         return RET_BAD_STATUS;
503     }
504     paramLength += manufacturerIdLength;
505 
506     if (manufacturerData.size() > LSF_CMD_MAX_LENGTH - manufacturerIdLength) {
507         manufacturerDataLength = LSF_CMD_MAX_LENGTH - manufacturerIdLength;
508     } else {
509         manufacturerDataLength = manufacturerData.size();
510     }
511 
512     if (manufacturerDataLength > 0) {
513         if (memcpy_s(param.data + paramLength, sizeof(param.data) - paramLength,
514             manufacturerData.data(), manufacturerDataLength) != EOK) {
515             HILOGI("copy manufacturer data faild.");
516             return RET_BAD_STATUS;
517         }
518     }
519     paramLength += manufacturerDataLength;
520     param.data[paramLength++] = manufacturerDataLength + manufacturerIdLength;
521 
522     if (memcpy_s(param.data + paramLength, sizeof(param.data) - paramLength,
523         &manufacturerIdMask, manufacturerIdLength) != EOK) {
524         HILOGI("copy manufacturerId mask faild.");
525         return RET_BAD_STATUS;
526     }
527     paramLength += manufacturerIdLength;
528 
529     if (manufacturerDataLength > 0) {
530         if (memcpy_s(param.data + paramLength, sizeof(param.data) - paramLength,
531             manufacturerDataMask.data(), manufacturerDataLength) != EOK) {
532             HILOGI("copy manufacturer data mask faild.");
533             return RET_BAD_STATUS;
534         }
535     }
536     paramLength += manufacturerDataLength;
537 
538     paramLength += LSF_CMD_MAX_LENGTH;
539     ongoingOpcode_ = param.opcode;
540     ongoingTag_ = param.tag;
541     StartCommandTimer();
542 
543     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), paramLength);
544 }
545 
BleScanFilterServiceDataAdd(std::vector<uint8_t> serviceData,std::vector<uint8_t> serviceDataMask)546 int BleScanFilterLsf::BleScanFilterServiceDataAdd(
547     std::vector<uint8_t> serviceData, std::vector<uint8_t> serviceDataMask)
548 {
549     uint16_t opCode = MakeVendorOpCode(HCI_VENDOR_OCF_LSF);
550     size_t paramLength = 0;
551     uint8_t serviceDataLength = 0;
552     VendorCmdParamLSFData param = {};
553     param.opcode = LSF_OPCODE_ADD;
554     param.tag = LSF_TAG_SERVICE_DATA;
555     param.filtIndex = filtIndex_;
556 
557     if (serviceData.size() > LSF_CMD_MAX_LENGTH) {
558         serviceDataLength = LSF_CMD_MAX_LENGTH;
559     } else {
560         serviceDataLength = serviceData.size();
561     }
562     param.data[paramLength++] = serviceDataLength;
563     if (serviceDataLength > 0) {
564         if (memcpy_s(param.data, sizeof(param.data), serviceData.data(), serviceDataLength) != EOK) {
565             HILOGI("copy service data faild.");
566             return RET_BAD_STATUS;
567         }
568         paramLength += serviceDataLength;
569         param.data[paramLength++] = serviceDataLength;
570         if (memcpy_s(param.data + paramLength, sizeof(param.data) - paramLength, serviceDataMask.data(),
571             serviceDataLength) != EOK) {
572             HILOGI("copy service data mask faild.");
573             return RET_BAD_STATUS;
574         }
575         paramLength += serviceDataLength;
576     }
577 
578     paramLength += LSF_CMD_HEAD_LENGTH;
579     ongoingOpcode_ = param.opcode;
580     ongoingTag_ = param.tag;
581     StartCommandTimer();
582 
583     return HCIVIF_SendCmd(opCode, static_cast<void *>(&param), paramLength);
584 }
585 
MakeVendorOpCode(uint16_t ocf)586 uint16_t BleScanFilterLsf::MakeVendorOpCode(uint16_t ocf)
587 {
588     return (ocf | (HCI_COMMAND_OGF_VENDOR_SPECIFIC << HCI_OGF_OFFSET));
589 }
590 
VendEventCommandCompleteCallback(uint16_t opCode,const void * param,uint8_t paramLength,void * context)591 void BleScanFilterLsf::VendEventCommandCompleteCallback(
592     uint16_t opCode, const void *param, uint8_t paramLength, void *context)
593 {
594     if ((opCode != MakeVendorOpCode(HCI_VENDOR_OCF_GET_CAPABILITIES)) &&
595         (opCode != MakeVendorOpCode(HCI_VENDOR_OCF_LSF))) {
596         return;
597     }
598     BleScanFilterLsf *filter = static_cast<BleScanFilterLsf *>(context);
599     if (filter == nullptr) {
600         HILOGI("BleScanFilter is null.");
601         return;
602     }
603 
604     if (opCode == MakeVendorOpCode(HCI_VENDOR_OCF_GET_CAPABILITIES)) {
605         filter->BleScanFilterGetCapabilitiesComplete(param, paramLength);
606     } else {
607         filter->BleScanFilterCommandComplete(param, paramLength);
608     }
609 }
610 
HciVendorClosedCallback(void * context)611 void BleScanFilterLsf::HciVendorClosedCallback(void *context)
612 {
613     BleScanFilterLsf *filter = static_cast<BleScanFilterLsf *>(context);
614     if (filter == nullptr) {
615         HILOGI("BleScanFilter is null.");
616     } else {
617         std::lock_guard<std::recursive_mutex> lk(filter->mutex_);
618         filter->isReady_ = false;
619     }
620 }
621 
BleScanFilterGetCapabilitiesComplete(const void * param,uint8_t paramLength)622 void BleScanFilterLsf::BleScanFilterGetCapabilitiesComplete(const void *param, uint8_t paramLength)
623 {
624     std::lock_guard<std::mutex> lock(mutexWaitCallback_);
625     VendorEventParamCAP eventParam = {};
626     if (paramLength >= sizeof(VendorEventParamCAP)) {
627         if (memcpy_s(&eventParam, sizeof(VendorEventParamCAP), param, sizeof(VendorEventParamCAP)) != EOK) {
628             HILOGI("copy eventParam faild.");
629             cvfull_.notify_all();
630             return;
631         }
632     } else {
633         HILOGI("paramLength is error.");
634         cvfull_.notify_all();
635         return;
636     }
637     if (eventParam.featureTag != CAP_FEATURE_TAG_BLE_SCAN_FILTER) {
638         HILOGI("featureTag is error featureTag=%{public}d.", eventParam.featureTag);
639     } else if (eventParam.status != BT_SUCCESS) {
640         HILOGI("get capabilities failed status=%{public}d.", eventParam.status);
641     } else if (eventParam.featureSize != CAP_LSF_FEATURE_VALUE_LENGTH) {
642         HILOGI("featureSize is error size=%{public}d.", eventParam.featureSize);
643     } else {
644         isSupportFilter_ = eventParam.filterSupport;
645         maxFilterNumber_ = eventParam.maxFilter;
646     }
647 
648     cvfull_.notify_all();
649 }
650 
BleScanFilterCommandComplete(const void * param,uint8_t paramLength)651 void BleScanFilterLsf::BleScanFilterCommandComplete(const void *param, uint8_t paramLength)
652 {
653     std::lock_guard<std::recursive_mutex> lk(mutex_);
654     if (paramLength >= sizeof(VendorEventParamLSF) - 1) {
655         VendorEventParamLSF eventParam = {};
656         uint8_t length = (paramLength > sizeof(VendorEventParamLSF)) ? sizeof(VendorEventParamLSF) : paramLength;
657         if (memcpy_s(&eventParam, sizeof(VendorEventParamLSF), param, length) != EOK) {
658             HILOGI("copy eventParam faild.");
659             return;
660         }
661 
662         if (eventParam.status == BT_SUCCESS) {
663             BleScanFilterCommandCompleteSuccess(eventParam);
664         } else {
665             BleScanFilterCommandCompleteFaild(eventParam);
666         }
667     }
668 }
669 
BleScanFilterCommandCompleteSuccess(VendorEventParamLSF eventParam)670 void BleScanFilterLsf::BleScanFilterCommandCompleteSuccess(VendorEventParamLSF eventParam)
671 {
672     if ((eventParam.opcode != ongoingOpcode_) || (eventParam.tag != ongoingTag_)) {
673         HILOGI("not ongonging opcode.");
674         return;
675     }
676 
677     switch (eventParam.opcode) {
678         case LSF_OPCODE_ENABLE:
679             HandleEnableCommandResult(eventParam.tag, eventParam.status);
680             break;
681         case LSF_OPCODE_ADD:
682             HandleAddCommandResult(eventParam.tag, eventParam.status);
683             break;
684         case LSF_OPCODE_DELETE:
685             HandleDeleteCommandResult(eventParam.tag, eventParam.status);
686             break;
687         case LSF_OPCODE_CLEAR:
688             HandleClearCommandResult(eventParam.tag, eventParam.status);
689             break;
690         default:
691             HILOGI("unknow opcode.");
692             break;
693     }
694 }
695 
BleScanFilterCommandCompleteFaild(VendorEventParamLSF eventParam)696 void BleScanFilterLsf::BleScanFilterCommandCompleteFaild(VendorEventParamLSF eventParam)
697 {
698     if (eventParam.opcode != ongoingOpcode_) {
699         HILOGI("not ongonging opcode.");
700         return;
701     }
702 
703     switch (eventParam.opcode) {
704         case LSF_OPCODE_ENABLE:
705             HandleEnableCommandResult(ongoingTag_, eventParam.status);
706             break;
707         case LSF_OPCODE_ADD:
708             HandleAddCommandResult(ongoingTag_, eventParam.status);
709             break;
710         case LSF_OPCODE_DELETE:
711             HandleDeleteCommandResult(ongoingTag_, eventParam.status);
712             break;
713         case LSF_OPCODE_CLEAR:
714             HandleClearCommandResult(ongoingTag_, eventParam.status);
715             break;
716         default:
717             HILOGI("unknow opcode.");
718             break;
719     }
720 }
721 }  // namespace bluetooth
722 }  // namespace OHOS
723