• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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