1 // Copyright 2023 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 15 #pragma once 16 #include <lib/fit/function.h> 17 18 #include <cstddef> 19 #include <cstdint> 20 21 #include "pw_bluetooth_sapphire/internal/host/common/byte_buffer.h" 22 #include "pw_bluetooth_sapphire/internal/host/common/uuid.h" 23 24 namespace bt { 25 26 // EIR Data Type, Advertising Data Type (AD Type), OOB Data Type definitions. 27 // clang-format off 28 enum class DataType : uint8_t { 29 kFlags = 0x01, 30 kIncomplete16BitServiceUuids = 0x02, 31 kComplete16BitServiceUuids = 0x03, 32 kIncomplete32BitServiceUuids = 0x04, 33 kComplete32BitServiceUuids = 0x05, 34 kIncomplete128BitServiceUuids = 0x06, 35 kComplete128BitServiceUuids = 0x07, 36 kShortenedLocalName = 0x08, 37 kCompleteLocalName = 0x09, 38 kTxPowerLevel = 0x0A, 39 kClassOfDevice = 0x0D, 40 kSSPOOBHash = 0x0E, 41 kSSPOOBRandomizer = 0x0F, 42 kServiceData16Bit = 0x16, 43 kAppearance = 0x19, 44 kServiceData32Bit = 0x20, 45 kServiceData128Bit = 0x21, 46 kURI = 0x24, 47 kManufacturerSpecificData = 0xFF, 48 // TODO(armansito): Complete this list. 49 }; 50 // clang-format on 51 52 UUIDElemSize SizeForType(DataType type); 53 54 using UuidFunction = fit::function<bool(const UUID&)>; 55 56 // Parses `data` into `data.size()` / `uuid_size` UUIDs, calling `func` with 57 // each parsed UUID. Returns false without further parsing if `uuid_size` does 58 // not evenly divide `data.size()` or `func` returns false for any UUID, 59 // otherwise returns true. 60 bool ParseUuids(const BufferView& data, 61 UUIDElemSize uuid_size, 62 UuidFunction func); 63 64 // Convenience classes for reading and writing the contents 65 // of Advertising Data, Scan Response Data, or Extended Inquiry Response Data 66 // payloads. The format in which data is stored looks like the following: 67 // 68 // [1-octet LENGTH][1-octet TYPE][LENGTH-1 octets DATA] 69 // 70 // Used for parsing data in TLV-format as described at the beginning of the file 71 // above. 72 class SupplementDataReader { 73 public: 74 // |data| must point to a valid piece of memory for the duration in which this 75 // object is to remain alive. 76 explicit SupplementDataReader(const ByteBuffer& data); 77 78 // Returns false if the fields of |data| have been formatted incorrectly. For 79 // example, this could happen if the length of an advertising data structure 80 // would exceed the bounds of the buffer. is_valid()81 inline bool is_valid() const { return is_valid_; } 82 83 // Returns the data and type fields of the next advertising data structure in 84 // |out_data| and |out_type|. Returns false if there is no more data to read 85 // or if the data is formatted incorrectly. 86 bool GetNextField(DataType* out_type, BufferView* out_data); 87 88 // Returns true if there is more data to read. Returns false if the end of 89 // data has been reached or if the current segment is malformed in a way that 90 // would exceed the bounds of the data this reader was initialized with. 91 bool HasMoreData() const; 92 93 private: 94 bool is_valid_; 95 BufferView remaining_; 96 }; 97 98 // Used for writing data in TLV-format as described at the beginning of the file 99 // above. 100 class SupplementDataWriter { 101 public: 102 // |buffer| is the piece of memory on which this SupplementDataWriter should 103 // operate. The buffer must out-live this instance and must point to a valid 104 // piece of memory. 105 explicit SupplementDataWriter(MutableByteBuffer* buffer); 106 107 // Writes the given piece of type/tag and data into the next available segment 108 // in the underlying buffer. Returns false if there isn't enough space left in 109 // the buffer for writing. Returns true on success. 110 bool WriteField(DataType type, const ByteBuffer& data); 111 112 // The total number of bytes that have been written into the buffer. bytes_written()113 size_t bytes_written() const { return bytes_written_; } 114 115 private: 116 MutableByteBuffer* buffer_; 117 size_t bytes_written_; 118 }; 119 120 } // namespace bt 121