cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

eir.h (2074B)


      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#include <asm/unaligned.h>
      9
     10void eir_create(struct hci_dev *hdev, u8 *data);
     11
     12u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
     13u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
     14
     15u8 eir_append_local_name(struct hci_dev *hdev, u8 *eir, u8 ad_len);
     16u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len);
     17u8 eir_append_service_data(u8 *eir, u16 eir_len, u16 uuid, u8 *data,
     18			   u8 data_len);
     19
     20static inline u16 eir_precalc_len(u8 data_len)
     21{
     22	return sizeof(u8) * 2 + data_len;
     23}
     24
     25static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type,
     26				  u8 *data, u8 data_len)
     27{
     28	eir[eir_len++] = sizeof(type) + data_len;
     29	eir[eir_len++] = type;
     30	memcpy(&eir[eir_len], data, data_len);
     31	eir_len += data_len;
     32
     33	return eir_len;
     34}
     35
     36static inline u16 eir_append_le16(u8 *eir, u16 eir_len, u8 type, u16 data)
     37{
     38	eir[eir_len++] = sizeof(type) + sizeof(data);
     39	eir[eir_len++] = type;
     40	put_unaligned_le16(data, &eir[eir_len]);
     41	eir_len += sizeof(data);
     42
     43	return eir_len;
     44}
     45
     46static inline u16 eir_skb_put_data(struct sk_buff *skb, u8 type, u8 *data, u8 data_len)
     47{
     48	u8 *eir;
     49	u16 eir_len;
     50
     51	eir_len	= eir_precalc_len(data_len);
     52	eir = skb_put(skb, eir_len);
     53	WARN_ON(sizeof(type) + data_len > U8_MAX);
     54	eir[0] = sizeof(type) + data_len;
     55	eir[1] = type;
     56	memcpy(&eir[2], data, data_len);
     57
     58	return eir_len;
     59}
     60
     61static inline void *eir_get_data(u8 *eir, size_t eir_len, u8 type,
     62				 size_t *data_len)
     63{
     64	size_t parsed = 0;
     65
     66	if (eir_len < 2)
     67		return NULL;
     68
     69	while (parsed < eir_len - 1) {
     70		u8 field_len = eir[0];
     71
     72		if (field_len == 0)
     73			break;
     74
     75		parsed += field_len + 1;
     76
     77		if (parsed > eir_len)
     78			break;
     79
     80		if (eir[1] != type) {
     81			eir += field_len + 1;
     82			continue;
     83		}
     84
     85		/* Zero length data */
     86		if (field_len == 1)
     87			return NULL;
     88
     89		if (data_len)
     90			*data_len = field_len - 1;
     91
     92		return &eir[2];
     93	}
     94
     95	return NULL;
     96}
     97
     98void *eir_get_service_data(u8 *eir, size_t eir_len, u16 uuid, size_t *len);