1 /*
2 * Copyright (C) 2023 - 2024 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 "ndef_bt_data_parser.h"
16
17 #include <string>
18 #include "loghelper.h"
19 #include "nfc_sdk_common.h"
20
21 namespace OHOS {
22 namespace NFC {
23 namespace TAG {
24 #define RTD_TYPE_BT "application/vnd.bluetooth.ep.oob"
25 #define RTD_TYPE_BLE "application/vnd.bluetooth.le.oob"
26
27 #define UNSIGNED_BYTE_TO_INT_MASK 0xFF
28
29 #define CARRIER_PWR_STA_INACTIVE 0
30 #define CARRIER_PWR_STA_ACTIVE 1
31 #define CARRIER_PWR_STA_ACTIVATING 2
32 #define CARRIER_PWR_STA_UNKNOWN 3
33
34 #define TYPE_MAC 0x1B
35 #define TYPE_LE_ROLE 0x1C
36 #define TYPE_LONG_LOCAL_NAME 0x09
37 #define TYPE_SHORT_LOCAL_NAME 0x08
38 #define TYPE_16_BIT_UUIDS_PARTIAL 0x02
39 #define TYPE_16_BIT_UUIDS_COMPLETE 0x03
40 #define TYPE_32_BIT_UUIDS_PARTIAL 0x04
41 #define TYPE_32_BIT_UUIDS_COMPLETE 0x05
42 #define TYPE_128_BIT_UUIDS_PARTIAL 0x06
43 #define TYPE_128_BIT_UUIDS_COMPLETE 0x07
44 #define TYPE_CLASS_OF_DEVICE 0x0D
45 #define TYPE_SEC_MGR_TK 0x10
46 #define TYPE_APPEARANCE 0x19
47 #define TYPE_LE_SC_CONFIRMATION 0x22
48 #define TYPE_LE_SC_RANDOM 0x23
49 #define TYPE_VENDOR 0xFF
50
51 #define BLE_ROLE_CENTRAL_ONLY 0x01
52
53 #define SEC_MGR_TK_SIZE 16
54 #define SEC_MGR_LE_SC_C_SIZE 16
55 #define SEC_MGR_LE_SC_R_SIZE 16
56 #define CLASS_OF_DEVICE_SIZE 3
57 #define VENDOR_SERIAL_NUM_SIZE 2
58 #define MAC_ADDR_SIZE 6
59
60 #define UUID_SEPARATOR "-"
61 #define MAC_SEPARATOR ":"
62 #define SHIFT_ONE_BYTE 8
63
64 using namespace OHOS::NFC::KITS;
65
NdefBtDataParser()66 NdefBtDataParser::NdefBtDataParser()
67 {
68 }
69
FormatBtMacAddr(const std::string & orgBtMac)70 std::string NdefBtDataParser::FormatBtMacAddr(const std::string& orgBtMac)
71 {
72 std::string result = "";
73 for (uint32_t i = MAC_ADDR_SIZE - 1; i > 0; i--) {
74 result += orgBtMac.substr(i * HEX_BYTE_LEN, HEX_BYTE_LEN);
75 result += MAC_SEPARATOR;
76 }
77 result += orgBtMac.substr(0, HEX_BYTE_LEN);
78 return result;
79 }
80
GetOrgBtMacFromPayload(const std::string & payload,uint32_t & offset)81 std::string NdefBtDataParser::GetOrgBtMacFromPayload(const std::string& payload, uint32_t& offset)
82 {
83 if (payload.length() < (offset * HEX_BYTE_LEN)) {
84 ErrorLog("NdefBtDataParser::GetBtMacFromPayload, payload.length error");
85 return "";
86 }
87 if (MAC_ADDR_SIZE * HEX_BYTE_LEN > payload.length() - (offset * HEX_BYTE_LEN)) {
88 ErrorLog("NdefBtDataParser::GetBtMacFromPayload, data error, "
89 "payload len %{public}lu offset.%{public}d", payload.length(), offset);
90 return "";
91 }
92 std::string mac = payload.substr(offset * HEX_BYTE_LEN, MAC_ADDR_SIZE * HEX_BYTE_LEN);
93 offset += MAC_ADDR_SIZE;
94 return mac;
95 }
96
GetBtDevClass(const std::string & payload,uint32_t & offset,Bluetooth::BluetoothDeviceClass & btClass)97 bool NdefBtDataParser::GetBtDevClass(const std::string& payload, uint32_t& offset,
98 Bluetooth::BluetoothDeviceClass& btClass)
99 {
100 if (payload.length() == 0 || (payload.length() < (offset + CLASS_OF_DEVICE_SIZE) * HEX_BYTE_LEN)) {
101 return false;
102 }
103 unsigned char firstByte = KITS::NfcSdkCommon::GetByteFromHexStr(payload, offset++);
104 unsigned char secondByte = KITS::NfcSdkCommon::GetByteFromHexStr(payload, offset++);
105 unsigned char thirdByte = KITS::NfcSdkCommon::GetByteFromHexStr(payload, offset++);
106 int devClass = (firstByte << (SHIFT_ONE_BYTE * 2)) + (secondByte << SHIFT_ONE_BYTE) + thirdByte;
107 btClass = Bluetooth::BluetoothDeviceClass(devClass);
108 return true;
109 }
110
RevertUuidStr(const std::string & uuid)111 std::string NdefBtDataParser::RevertUuidStr(const std::string& uuid)
112 {
113 std::string res = "";
114 uint32_t len = uuid.length();
115 if (len % HEX_BYTE_LEN != 0) {
116 ErrorLog("uuid len not even");
117 return res;
118 }
119 for (uint32_t i = len; i >= HEX_BYTE_LEN; i -= HEX_BYTE_LEN) {
120 res += uuid.substr(i - HEX_BYTE_LEN, HEX_BYTE_LEN);
121 }
122 return res;
123 }
124
FormatUuidTo128Bit(const std::string & uuid)125 Bluetooth::UUID NdefBtDataParser::FormatUuidTo128Bit(const std::string& uuid)
126 {
127 const uint32_t uuidPrefixLen = 8;
128 const uint32_t separatorPoz1 = 8;
129 const uint32_t separatorPoz2 = 12;
130 const uint32_t separatorPoz3 = 16;
131 const uint32_t separatorPoz4 = 20;
132 std::string baseUuid = std::string(Bluetooth::BLUETOOTH_UUID_BASE_UUID);
133 std::string uuidSubfix = "";
134 if (baseUuid.length() > uuidPrefixLen) {
135 uuidSubfix = baseUuid.substr(uuidPrefixLen, baseUuid.length() - uuidPrefixLen);
136 }
137 std::string prefix16Bit = "0000";
138 std::string res = "";
139
140 if ((uuid.length() / HEX_BYTE_LEN) == Bluetooth::BLE_UUID_LEN_16) {
141 res = prefix16Bit + RevertUuidStr(uuid) + uuidSubfix;
142 } else if (uuid.length() == Bluetooth::BLE_UUID_LEN_32) {
143 res = RevertUuidStr(uuid) + uuidSubfix;
144 } else if (uuid.length() == Bluetooth::BLE_UUID_LEN_128) {
145 res = RevertUuidStr(uuid);
146 res.insert(separatorPoz4, UUID_SEPARATOR);
147 res.insert(separatorPoz3, UUID_SEPARATOR);
148 res.insert(separatorPoz2, UUID_SEPARATOR);
149 res.insert(separatorPoz1, UUID_SEPARATOR);
150 }
151 return Bluetooth::UUID::FromString(res);
152 }
153
GetDataFromPayload(const std::string & payload,uint32_t & offset,uint32_t dataLen)154 std::string NdefBtDataParser::GetDataFromPayload(const std::string& payload, uint32_t& offset, uint32_t dataLen)
155 {
156 if (dataLen * HEX_BYTE_LEN > (payload.length() - (offset * HEX_BYTE_LEN))) {
157 return "";
158 }
159 std::string data = payload.substr(offset * HEX_BYTE_LEN, dataLen * HEX_BYTE_LEN);
160 offset += dataLen;
161 return data;
162 }
163
GetUuidFromPayload(const std::string & payload,uint32_t & offset,uint32_t type,uint32_t len)164 std::vector<Bluetooth::UUID> NdefBtDataParser::GetUuidFromPayload(const std::string& payload, uint32_t& offset,
165 uint32_t type, uint32_t len)
166 {
167 // uuids can have several groups, uuidsSize is the size of each group
168 uint32_t uuidSize;
169 std::vector<Bluetooth::UUID> uuids;
170 switch (type) {
171 case TYPE_16_BIT_UUIDS_PARTIAL:
172 case TYPE_16_BIT_UUIDS_COMPLETE:
173 uuidSize = Bluetooth::BLE_UUID_LEN_16;
174 break;
175 case TYPE_32_BIT_UUIDS_PARTIAL:
176 case TYPE_32_BIT_UUIDS_COMPLETE:
177 uuidSize = Bluetooth::BLE_UUID_LEN_32;
178 break;
179 case TYPE_128_BIT_UUIDS_PARTIAL:
180 case TYPE_128_BIT_UUIDS_COMPLETE:
181 uuidSize = Bluetooth::BLE_UUID_LEN_128;
182 break;
183 default:
184 ErrorLog("NdefBtDataParser::GetUuidFromPayload, unknown type of UUID");
185 return uuids;
186 }
187 if (len == 0 || (len % uuidSize != 0) || len * HEX_BYTE_LEN > (payload.length() - (offset * HEX_BYTE_LEN))) {
188 return uuids;
189 }
190 uint32_t uuidNum = len / uuidSize;
191 for (uint32_t i = 0; i < uuidNum; i++) {
192 std::string uuid = payload.substr(offset * HEX_BYTE_LEN, uuidSize * HEX_BYTE_LEN);
193 offset += uuidSize;
194 uuids.push_back(FormatUuidTo128Bit(uuid));
195 }
196 return uuids;
197 }
198
199 /*
200 * BT RECORD STRUCTURE
201 * Len(2 BYTEs) | MacAddr(6 BYTES, reverted) | LTV data
202 * LTV data:
203 * LEN(1 BYTE) |TYPE(1 BYTE) |VALUE(LEN -1 BYTES)
204 */
ParseBtRecord(const std::string & payload)205 std::shared_ptr<BtData> NdefBtDataParser::ParseBtRecord(const std::string& payload)
206 {
207 std::shared_ptr<BtData> data = std::make_shared<BtData>();
208 data->isValid_ = false;
209 uint32_t offset = 0; // offset is for byte parse position, payload is hex string
210 // to compare need to * HEX_BYTE_LEN
211
212 uint32_t len = 2;
213 offset += len;
214 std::string macAddress = GetOrgBtMacFromPayload(payload, offset);
215 if (macAddress.empty()) {
216 ErrorLog("NdefBtDataParser::ParseBtRecord, macAddress error, "
217 "payload .len %{public}lu offset.%{public}d", payload.length(), offset);
218 return data;
219 }
220 data->macAddrOrg_ = macAddress;
221 data->macAddress_ = FormatBtMacAddr(macAddress);
222 data->isValid_ = true;
223
224 while ((offset * HEX_BYTE_LEN) < payload.length()) {
225 bool isValid = false;
226 std::string name;
227 uint32_t tvLen = NfcSdkCommon::GetByteFromHexStr(payload, offset++) & UNSIGNED_BYTE_TO_INT_MASK;
228 uint32_t type = NfcSdkCommon::GetByteFromHexStr(payload, offset++) & UNSIGNED_BYTE_TO_INT_MASK;
229 InfoLog("NdefBtDataParser::ParseBtRecord, len:%{public}d type:0x%{public}X", tvLen, type);
230 switch (type) {
231 case TYPE_SHORT_LOCAL_NAME: {
232 if (tvLen < 1) {
233 ErrorLog("NdefBtDataParser::ParseBtRecord, invalid local name len. ");
234 data->isValid_ = false;
235 return data;
236 }
237 name = GetDataFromPayload(payload, offset, tvLen - 1);
238 if (name.empty()) {
239 ErrorLog("NdefBtDataParser::ParseBtRecord, name error, "
240 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
241 break;
242 }
243 data->name_ = KITS::NfcSdkCommon::HexStringToAsciiString(name);
244 isValid = true;
245 break;
246 }
247 case TYPE_LONG_LOCAL_NAME: {
248 if (!data->name_.empty()) {
249 offset += (tvLen - 1);
250 break; // already contains short name
251 }
252 if (tvLen < 1) {
253 ErrorLog("NdefBtDataParser::ParseBtRecord, invalid long local name len. ");
254 data->isValid_ = false;
255 return data;
256 }
257 name = GetDataFromPayload(payload, offset, tvLen - 1);
258 if (name.empty()) {
259 ErrorLog("NdefBtDataParser::ParseBtRecord, name error, "
260 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
261 break;
262 }
263 data->name_ = KITS::NfcSdkCommon::HexStringToAsciiString(name);
264 isValid = true;
265 break;
266 }
267 case TYPE_16_BIT_UUIDS_PARTIAL:
268 case TYPE_16_BIT_UUIDS_COMPLETE:
269 case TYPE_32_BIT_UUIDS_PARTIAL:
270 case TYPE_32_BIT_UUIDS_COMPLETE:
271 case TYPE_128_BIT_UUIDS_PARTIAL:
272 case TYPE_128_BIT_UUIDS_COMPLETE: {
273 data->uuids_.clear();
274 data->uuids_ = GetUuidFromPayload(payload, offset, type, tvLen - 1);
275 if (!data->uuids_.empty()) {
276 isValid = true;
277 }
278 break;
279 }
280 case TYPE_CLASS_OF_DEVICE: {
281 if (tvLen - 1 != CLASS_OF_DEVICE_SIZE) {
282 ErrorLog("NdefBtDataParser::ParseBtRecord, invalid class of Device len");
283 break;
284 }
285 isValid = GetBtDevClass(payload, offset, data->btClass_);
286 break;
287 }
288 case TYPE_VENDOR: {
289 std::string vendorPayload = GetDataFromPayload(payload, offset, tvLen - 1);
290 if (vendorPayload.empty()) {
291 ErrorLog("NdefBtDataParser::ParseBtRecord, vendor error, "
292 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
293 break;
294 }
295 data->vendorPayload_ = vendorPayload;
296 isValid = true;
297 break;
298 }
299 default: {
300 ErrorLog("NdefBtDataParser::ParseBtRecord, unknown type = %{public}d", type);
301 if (tvLen < 1) {
302 ErrorLog("NdefBtDataParser::ParseBtRecord, invalid local name len. ");
303 return data;
304 }
305 offset += (tvLen - 1);
306 isValid = true;
307 break;
308 }
309 }
310 if (!isValid) {
311 ErrorLog("NdefBtDataParser::ParseBtRecord, vendor error, "
312 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
313 data->isValid_ = false;
314 return data;
315 }
316 }
317 return data;
318 }
319
ParseBleRecord(const std::string & payload)320 std::shared_ptr<BtData> NdefBtDataParser::ParseBleRecord(const std::string& payload)
321 {
322 std::shared_ptr<BtData> data = std::make_shared<BtData>();
323 data->isValid_ = false;
324 data->transport_ = Bluetooth::GATT_TRANSPORT_TYPE_LE;
325 uint32_t offset = 0; // offset is for byte parse position, payload is hex string
326 // to compare need to * HEX_BYTE_LEN
327
328 std::string bdaddr = "";
329 unsigned char role = 0xF; // invalid default
330 std::string leScC = "";
331 std::string leScR = "";
332 std::string name = "";
333 std::string secMgrTK = "";
334 std::string macAddress = "";
335 while ((offset * HEX_BYTE_LEN) < payload.length()) {
336 uint32_t len = NfcSdkCommon::GetByteFromHexStr(payload, offset++) & UNSIGNED_BYTE_TO_INT_MASK;
337 uint32_t type = NfcSdkCommon::GetByteFromHexStr(payload, offset++) & UNSIGNED_BYTE_TO_INT_MASK;
338 switch (type) {
339 case TYPE_MAC: {
340 uint32_t bdaddrLen = 7; // 6 bytes for mac, 1 for address type
341 bdaddr = GetDataFromPayload(payload, offset, bdaddrLen);
342 if (bdaddr.empty()) {
343 ErrorLog("NdefBtDataParser::ParseBleRecord, bdaddr error, "
344 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
345 break;
346 }
347 std::string mac = GetOrgBtMacFromPayload(payload, offset);
348 if (mac.empty()) {
349 ErrorLog("NdefBtDataParser::ParseBleRecord, macAddress error, "
350 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
351 break;
352 }
353 macAddress = FormatBtMacAddr(mac);
354 offset++; // advance over random byte
355 data->isValid_ = true;
356 break;
357 }
358 case TYPE_LE_ROLE: {
359 role = NfcSdkCommon::GetByteFromHexStr(payload, offset++) & UNSIGNED_BYTE_TO_INT_MASK;
360 if (role == BLE_ROLE_CENTRAL_ONLY) {
361 data->isValid_ = false;
362 return data;
363 }
364 break;
365 }
366 case TYPE_LONG_LOCAL_NAME: {
367 name = GetDataFromPayload(payload, offset, len - 1);
368 if (name.empty()) {
369 ErrorLog("NdefBtDataParser::ParseBleRecord, name error, "
370 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
371 break;
372 }
373 data->name_ = KITS::NfcSdkCommon::HexStringToAsciiString(name);
374 break;
375 }
376 case TYPE_SEC_MGR_TK: {
377 if (len - 1 != SEC_MGR_TK_SIZE) {
378 ErrorLog("NdefBtDataParser::ParseBleRecord, SM TK len error, should be %{public}d",
379 SEC_MGR_TK_SIZE);
380 break;
381 }
382 secMgrTK = GetDataFromPayload(payload, offset, len);
383 if (leScC.empty()) {
384 ErrorLog("NdefBtDataParser::ParseBleRecord, secMgrTK error, "
385 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
386 break;
387 }
388 break;
389 }
390 case TYPE_LE_SC_CONFIRMATION: {
391 if (len - 1 != SEC_MGR_LE_SC_C_SIZE) {
392 ErrorLog("NdefBtDataParser::ParseBleRecord, LE SC Confirmation len error, "
393 "should be %{public}d", SEC_MGR_LE_SC_C_SIZE);
394 break;
395 }
396 leScC = GetDataFromPayload(payload, offset, len - 1);
397 if (leScC.empty()) {
398 ErrorLog("NdefBtDataParser::ParseBleRecord, leScC Confirmation error, "
399 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
400 break;
401 }
402 break;
403 }
404 case TYPE_LE_SC_RANDOM: {
405 if (len - 1 != SEC_MGR_LE_SC_R_SIZE) {
406 ErrorLog("NdefBtDataParser::ParseBleRecord, LE SC Random len error, should be %{public}d",
407 SEC_MGR_LE_SC_R_SIZE);
408 break;
409 }
410 leScR = GetDataFromPayload(payload, offset, len - 1);
411 if (leScR.empty()) {
412 ErrorLog("NdefBtDataParser::ParseBleRecord, leScC Random error, "
413 "payload len.%{public}lu offset.%{public}d type.0x%{public}X", payload.length(), offset, type);
414 break;
415 }
416 break;
417 }
418 default: {
419 offset += (len - 1);
420 break;
421 }
422 }
423 }
424 return data;
425 }
426
CheckBtRecord(const std::string & msg)427 std::shared_ptr<BtData> NdefBtDataParser::CheckBtRecord(const std::string& msg)
428 {
429 if (msg.empty()) {
430 ErrorLog("NdefBtDataParser::CheckBtRecord: msg is empty");
431 return std::make_shared<BtData>();
432 }
433 std::shared_ptr<NdefMessage> ndef = NdefMessage::GetNdefMessage(msg);
434 if (ndef == nullptr || (ndef->GetNdefRecords().size() == 0)) {
435 ErrorLog("NdefBtDataParser::CheckBtRecord: ndef is null");
436 return std::make_shared<BtData>();
437 }
438 std::shared_ptr<NdefRecord> record = ndef->GetNdefRecords()[0];
439 if (record == nullptr) {
440 ErrorLog("NdefBtDataParser::CheckBtRecord: record is null");
441 return std::make_shared<BtData>();
442 }
443
444 if (record->payload_.length() == 0) {
445 ErrorLog("NdefBtDataParser::CheckBtRecord: payload.length is 0");
446 return std::make_shared<BtData>();
447 }
448
449 // Check BT
450 if (record->tnf_ == NdefMessage::TNF_MIME_MEDIA &&
451 (record->tagRtdType_.compare(NfcSdkCommon::StringToHexString(RTD_TYPE_BT)) == 0)) {
452 InfoLog("NdefBtDataParser::CheckBtRecord: is bt");
453 return ParseBtRecord(record->payload_);
454 }
455
456 // Check BLE
457 if (record->tnf_ == NdefMessage::TNF_MIME_MEDIA &&
458 (record->tagRtdType_.compare(NfcSdkCommon::StringToHexString(RTD_TYPE_BLE)) == 0)) {
459 InfoLog("NdefBtDataParser::CheckBtRecord: is ble, currently not supported");
460 return std::make_shared<BtData>();
461 }
462
463 std::string rtdHexStr =
464 NfcSdkCommon::StringToHexString(NdefMessage::GetTagRtdType(NdefMessage::RTD_HANDOVER_SELECT));
465 // Check Handover Select, followed by a BT record
466 if (record->tnf_ == NdefMessage::TNF_WELL_KNOWN &&
467 (record->tagRtdType_.compare(rtdHexStr) == 0)) {
468 InfoLog("NdefBtDataParser::CheckBtRecord: is handover select");
469 return ParseBtHandoverSelect(ndef);
470 }
471 InfoLog("NdefBtDataParser::CheckBtRecord : is not bt");
472 return std::make_shared<BtData>();
473 }
474
ParseBtHandoverSelect(std::shared_ptr<KITS::NdefMessage> & ndef)475 std::shared_ptr<BtData> NdefBtDataParser::ParseBtHandoverSelect(std::shared_ptr<KITS::NdefMessage> &ndef)
476 {
477 if (ndef == nullptr || (ndef->GetNdefRecords().size() == 0)) {
478 ErrorLog("NdefBtDataParser::ParseBtHandoverSelect: ndef is null");
479 return std::make_shared<BtData>();
480 }
481 std::vector<std::shared_ptr<NdefRecord>> records = ndef->GetNdefRecords();
482
483 for (size_t i = 0; i < records.size(); i++) {
484 std::shared_ptr<NdefRecord> record = records[i];
485
486 // Check BT
487 if (record->tnf_ == NdefMessage::TNF_MIME_MEDIA &&
488 (record->tagRtdType_.compare(NfcSdkCommon::StringToHexString(RTD_TYPE_BT)) == 0)) {
489 InfoLog("NdefBtDataParser::ParseBtHandoverSelect record[%{public}zu]: is bt", i);
490 return ParseBtRecord(record->payload_);
491 }
492
493 // Check BLE
494 if (record->tnf_ == NdefMessage::TNF_MIME_MEDIA &&
495 (record->tagRtdType_.compare(NfcSdkCommon::StringToHexString(RTD_TYPE_BLE)) == 0)) {
496 InfoLog("NdefBtDataParser::ParseBtHandoverSelect record[%{public}zu]: is ble, currently not supported", i);
497 return std::make_shared<BtData>();
498 }
499 }
500 InfoLog("NdefBtDataParser::ParseBtHandoverSelect : is not bt");
501 return std::make_shared<BtData>();
502 }
503
IsVendorPayloadValid(const std::string & payload)504 bool NdefBtDataParser::IsVendorPayloadValid(const std::string& payload)
505 {
506 size_t len = payload.length();
507 if (len % HEX_BYTE_LEN != 0) {
508 ErrorLog("BT vendor payload len invalid");
509 return false;
510 }
511 int bytesLen = static_cast<int>(len / HEX_BYTE_LEN);
512 if (bytesLen > VENDOR_PAYLOAD_MAX_LEN) {
513 ErrorLog("BT vendor payload len exceeds, bytesLen = %{public}d", bytesLen);
514 return false;
515 }
516 return true;
517 }
518 } // namespace TAG
519 } // namespace NFC
520 } // namespace OHOS