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 
17 #include "pw_bluetooth_sapphire/internal/host/hci/low_energy_scanner.h"
18 
19 namespace bt::hci {
20 
21 class LocalAddressDelegate;
22 
23 // LegacyLowEnergyScanner implements the LowEnergyScanner interface for
24 // controllers that do not support the 5.0 Extended Advertising feature. This
25 // uses the legacy HCI LE scan commands and events:
26 //
27 //     - HCI_LE_Set_Scan_Parameters
28 //     - HCI_LE_Set_Scan_Enable
29 //     - HCI_LE_Advertising_Report event
30 class LegacyLowEnergyScanner final : public LowEnergyScanner {
31  public:
32   LegacyLowEnergyScanner(LocalAddressDelegate* local_addr_delegate,
33                          Transport::WeakPtr transport,
34                          pw::async::Dispatcher& pw_dispatcher);
35   ~LegacyLowEnergyScanner() override;
36 
37   bool StartScan(const ScanOptions& options,
38                  ScanStatusCallback callback) override;
39 
40   // Parse address field from |report| into |out_addr| and return whether or not
41   // it is a resolved address in |out_resolved|. Returns false if the address
42   // field was invalid.
43   static bool DeviceAddressFromAdvReport(
44       const pw::bluetooth::emboss::LEAdvertisingReportDataView& report,
45       DeviceAddress* out_addr,
46       bool* out_resolved);
47 
48  private:
49   // Build the HCI command packet to set the scan parameters for the flavor of
50   // low energy scanning being implemented.
51   CommandPacket BuildSetScanParametersPacket(
52       const DeviceAddress& local_address, const ScanOptions& options) override;
53 
54   // Build the HCI command packet to enable scanning for the flavor of low
55   // energy scanning being implemented.
56   CommandPacket BuildEnablePacket(
57       const ScanOptions& options,
58       pw::bluetooth::emboss::GenericEnableParam enable) override;
59 
60   // Called when a Scan Response is received during an active scan or when we
61   // time out waiting
62   void HandleScanResponse(const DeviceAddress& address,
63                           bool resolved,
64                           int8_t rssi,
65                           const ByteBuffer& data);
66 
67   std::vector<pw::bluetooth::emboss::LEAdvertisingReportDataView>
68   ParseAdvertisingReports(const EventPacket& event);
69 
70   // Event handler for HCI LE Advertising Report event.
71   void OnAdvertisingReportEvent(const EventPacket& event);
72 
73   // Our event handler ID for the LE Advertising Report event.
74   CommandChannel::EventHandlerId event_handler_id_;
75 
76   // Keep this as the last member to make sure that all weak pointers are
77   // invalidated before other members get destroyed
78   WeakSelf<LegacyLowEnergyScanner> weak_self_;
79 
80   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(LegacyLowEnergyScanner);
81 };
82 
83 }  // namespace bt::hci
84