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