1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2021 Intel Corporation 6 */ 7 8 void eir_create(struct hci_dev *hdev, u8 *data); 9 10 u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr); 11 u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr); 12 13 u8 eir_append_local_name(struct hci_dev *hdev, u8 *eir, u8 ad_len); 14 u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len); 15 16 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, 17 u8 *data, u8 data_len) 18 { 19 eir[eir_len++] = sizeof(type) + data_len; 20 eir[eir_len++] = type; 21 memcpy(&eir[eir_len], data, data_len); 22 eir_len += data_len; 23 24 return eir_len; 25 } 26 27 static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data) 28 { 29 eir[eir_len++] = sizeof(type) + sizeof(data); 30 eir[eir_len++] = type; 31 put_unaligned_le16(data, &eir[eir_len]); 32 eir_len += sizeof(data); 33 34 return eir_len; 35 } 36 37 static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type, 38 size_t *data_len) 39 { 40 size_t parsed = 0; 41 42 if (eir_len < 2) 43 return NULL; 44 45 while (parsed < eir_len - 1) { 46 u8 field_len = eir[0]; 47 48 if (field_len == 0) 49 break; 50 51 parsed += field_len + 1; 52 53 if (parsed > eir_len) 54 break; 55 56 if (eir[1] != type) { 57 eir += field_len + 1; 58 continue; 59 } 60 61 /* Zero length data */ 62 if (field_len == 1) 63 return NULL; 64 65 if (data_len) 66 *data_len = field_len - 1; 67 68 return &eir[2]; 69 } 70 71 return NULL; 72 } 73