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 "pw_bluetooth_sapphire/internal/host/common/macros.h"
17 #include "pw_bluetooth_sapphire/internal/host/transport/control_packets.h"
18 
19 namespace bt::hci {
20 
21 // Convenience class for extracting the contents of a HCI LE Advertising Report
22 // Event.
23 class AdvertisingReportParser final {
24  public:
25   // |event| must represent a LE Meta Event containing a LE Advertising Report
26   // sub-event. The buffer that backs |event| must remain valid for the duration
27   // in which this parser instance will be used.
28   explicit AdvertisingReportParser(const EventPacket& event);
29 
30   // Populates the next LE Advertising report contained in this event in
31   // |out_data| and the RSSI in |out_rssi|. Returns false if there were no
32   // more reports to return or if a report is malformed.
33   bool GetNextReport(
34       pw::bluetooth::emboss::LEAdvertisingReportDataView* out_data,
35       int8_t* out_rssi);
36 
37   // Returns true if there are more reports to process.
38   bool HasMoreReports();
39 
40   // Returns true if the parsing stopped due to malformed packet contents. This
41   // is only possible in the very rare scenario in which the controller sent us
42   // a payload that could not be parsed correctly.
43   //
44   // Users should check this after iterating through the reports to make sure
45   // there was no error and avoid any further processing if necessary. This flag
46   // will be lazily set if-and-only-if GetNextReport() or HasMoreReports()
47   // returns false due to a parse error.
encountered_error()48   bool encountered_error() const { return encountered_error_; }
49 
50  private:
51   // True if we encountered an error while parsing the report.
52   bool encountered_error_;
53 
54   // The number remaining reports that have not been processed via a call to
55   // GetNextReport.
56   uint8_t remaining_reports_;
57 
58   // Number of unprocessed bytes left in the report.
59   size_t remaining_bytes_;
60 
61   // Pointer to the beginning of the next advertising report segment.
62   const uint8_t* ptr_;
63 
64   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(AdvertisingReportParser);
65 };
66 
67 }  // namespace bt::hci
68