Merge "L2CAP: Delete more unused API"
diff --git a/gd/shim/advertising.cc b/gd/shim/advertising.cc
index b7e0b4e..0ac429a 100644
--- a/gd/shim/advertising.cc
+++ b/gd/shim/advertising.cc
@@ -30,18 +30,82 @@
 namespace shim {
 
 struct Advertising::impl {
-  hci::LeAdvertisingManager* module_{nullptr};
-
-  impl(hci::LeAdvertisingManager* module);
+  impl(hci::LeAdvertisingManager* module, os::Handler* handler);
   ~impl();
+
+  void StartAdvertising();
+  void StopAdvertising();
+
+  size_t GetNumberOfAdvertisingInstances() const;
+
+ private:
+  void OnScan(hci::Address address, hci::AddressType address_type);
+  void OnTerminated(hci::ErrorCode code, uint8_t handle, uint8_t num_events);
+
+  hci::AdvertiserId advertiser_id_{hci::LeAdvertisingManager::kInvalidId};
+
+  hci::LeAdvertisingManager* advertising_manager_{nullptr};
+  os::Handler* handler_;
 };
 
 const ModuleFactory Advertising::Factory = ModuleFactory([]() { return new Advertising(); });
 
-Advertising::impl::impl(hci::LeAdvertisingManager* advertising_manager) : module_(advertising_manager) {}
+Advertising::impl::impl(hci::LeAdvertisingManager* advertising_manager, os::Handler* handler)
+    : advertising_manager_(advertising_manager), handler_(handler) {}
 
 Advertising::impl::~impl() {}
 
+void Advertising::impl::StartAdvertising() {
+  if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
+    LOG_WARN("%s Already advertising; please stop prior to starting again", __func__);
+    return;
+  }
+
+  hci::AdvertisingConfig config;
+  advertiser_id_ =
+      advertising_manager_->CreateAdvertiser(config, common::Bind(&impl::OnScan, common::Unretained(this)),
+                                             common::Bind(&impl::OnTerminated, common::Unretained(this)), handler_);
+  if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
+    LOG_WARN("%s Unable to start advertising", __func__);
+    return;
+  }
+  LOG_DEBUG("%s Started advertising", __func__);
+}
+
+void Advertising::impl::StopAdvertising() {
+  if (advertiser_id_ == hci::LeAdvertisingManager::kInvalidId) {
+    LOG_WARN("%s No active advertising", __func__);
+    return;
+  }
+  advertising_manager_->RemoveAdvertiser(advertiser_id_);
+  advertiser_id_ = hci::LeAdvertisingManager::kInvalidId;
+  LOG_DEBUG("%s Stopped advertising", __func__);
+}
+
+void Advertising::impl::OnScan(hci::Address address, hci::AddressType address_type) {
+  LOG_INFO("%s UNIMPLEMENTED Received le advert from:%s", __func__, address.ToString().c_str());
+}
+
+void Advertising::impl::OnTerminated(hci::ErrorCode code, uint8_t handle, uint8_t num_events) {
+  LOG_INFO("%s UNIMPLEMENTED", __func__);
+}
+
+size_t Advertising::impl::GetNumberOfAdvertisingInstances() const {
+  return advertising_manager_->GetNumberOfAdvertisingInstances();
+}
+
+size_t Advertising::GetNumberOfAdvertisingInstances() const {
+  return pimpl_->GetNumberOfAdvertisingInstances();
+}
+
+void Advertising::StartAdvertising() {
+  pimpl_->StartAdvertising();
+}
+
+void Advertising::StopAdvertising() {
+  pimpl_->StopAdvertising();
+}
+
 /**
  * Module methods
  */
@@ -50,7 +114,7 @@
 }
 
 void Advertising::Start() {
-  pimpl_ = std::make_unique<impl>(GetDependency<hci::LeAdvertisingManager>());
+  pimpl_ = std::make_unique<impl>(GetDependency<hci::LeAdvertisingManager>(), GetHandler());
 }
 
 void Advertising::Stop() {
diff --git a/gd/shim/advertising.h b/gd/shim/advertising.h
index 17c094a..27f8e07 100644
--- a/gd/shim/advertising.h
+++ b/gd/shim/advertising.h
@@ -29,6 +29,11 @@
   Advertising() = default;
   ~Advertising() = default;
 
+  void StartAdvertising() override;
+  void StopAdvertising() override;
+
+  size_t GetNumberOfAdvertisingInstances() const override;
+
   static const ModuleFactory Factory;
 
  protected:
diff --git a/gd/shim/iadvertising.h b/gd/shim/iadvertising.h
index 85a75c6..3b90b37 100644
--- a/gd/shim/iadvertising.h
+++ b/gd/shim/iadvertising.h
@@ -15,6 +15,8 @@
  */
 #pragma once
 
+#include <cstddef>
+
 /**
  * The gd API exported to the legacy api
  */
@@ -22,6 +24,11 @@
 namespace shim {
 
 struct IAdvertising {
+  virtual void StartAdvertising() = 0;
+  virtual void StopAdvertising() = 0;
+
+  virtual size_t GetNumberOfAdvertisingInstances() const = 0;
+
   virtual ~IAdvertising() {}
 };
 
diff --git a/gd/shim/iscanning.h b/gd/shim/iscanning.h
index ddaabb6..f96f372 100644
--- a/gd/shim/iscanning.h
+++ b/gd/shim/iscanning.h
@@ -15,13 +15,45 @@
  */
 #pragma once
 
+#include <cstdint>
+#include <functional>
+
 /**
  * The gd API exported to the legacy api
  */
 namespace bluetooth {
 namespace shim {
 
+struct AdvertisingReport {
+  uint16_t extended_event_type;
+  std::string string_address;
+  uint8_t address_type;
+  int8_t rssi;
+  uint8_t* data;
+  size_t len;
+};
+
+struct DirectedAdvertisingReport : public AdvertisingReport {
+  DirectedAdvertisingReport(AdvertisingReport report) : AdvertisingReport(report) {}
+  uint8_t directed_advertising_type;
+};
+
+struct ExtendedAdvertisingReport : public DirectedAdvertisingReport {
+  ExtendedAdvertisingReport(AdvertisingReport report) : DirectedAdvertisingReport(report) {}
+};
+
+using AdvertisingReportCallback = std::function<void(AdvertisingReport report)>;
+using DirectedAdvertisingReportCallback = std::function<void(DirectedAdvertisingReport report)>;
+using ExtendedAdvertisingReportCallback = std::function<void(ExtendedAdvertisingReport report)>;
+using ScanningTimeoutCallback = std::function<void()>;
+
 struct IScanning {
+  virtual void StartScanning(bool set_active, AdvertisingReportCallback advertising_callback,
+                             DirectedAdvertisingReportCallback directed_advertising_callback,
+                             ExtendedAdvertisingReportCallback extended_advertising_callback,
+                             ScanningTimeoutCallback timeout_callback) = 0;
+  virtual void StopScanning() = 0;
+
   virtual ~IScanning() {}
 };
 
diff --git a/gd/shim/scanning.cc b/gd/shim/scanning.cc
index 5216937..7a34ed8 100644
--- a/gd/shim/scanning.cc
+++ b/gd/shim/scanning.cc
@@ -18,8 +18,10 @@
 #include <functional>
 #include <memory>
 
+#include "common/bind.h"
 #include "hci/address.h"
 #include "hci/hci_packets.h"
+#include "hci/le_report.h"
 #include "hci/le_scanning_manager.h"
 #include "module.h"
 #include "os/handler.h"
@@ -29,19 +31,195 @@
 namespace bluetooth {
 namespace shim {
 
-struct Scanning::impl {
-  hci::LeScanningManager* module_{nullptr};
+constexpr size_t kAdvertisingReportBufferSize = 1024;
 
-  impl(hci::LeScanningManager* module);
+struct Scanning::impl : public hci::LeScanningManagerCallbacks {
+  void StartScanning(bool set_active, AdvertisingReportCallback advertising_callback,
+                     DirectedAdvertisingReportCallback directed_advertising_callback,
+                     ExtendedAdvertisingReportCallback extended_advertising_callback,
+                     ScanningTimeoutCallback timeout_callback);
+  void StopScanning();
+
+  void on_advertisements(std::vector<std::shared_ptr<hci::LeReport>>) override;
+  void on_timeout() override;
+  os::Handler* Handler() override;
+
+  void OnStopped();
+
+  impl(hci::LeScanningManager* scanning_manager, os::Handler* handler);
   ~impl();
+
+ private:
+  hci::LeScanningManager* scanning_manager_{nullptr};
+  os::Handler* handler_;
+  bool active_scanning_{true};
+
+  AdvertisingReportCallback advertising_callback_;
+  DirectedAdvertisingReportCallback directed_advertising_callback_;
+  ExtendedAdvertisingReportCallback extended_advertising_callback_;
+  ScanningTimeoutCallback timeout_callback_;
 };
 
 const ModuleFactory Scanning::Factory = ModuleFactory([]() { return new Scanning(); });
 
-Scanning::impl::impl(hci::LeScanningManager* scanning_manager) : module_(scanning_manager) {}
+Scanning::impl::impl(hci::LeScanningManager* scanning_manager, os::Handler* handler)
+    : scanning_manager_(scanning_manager), handler_(handler) {}
 
 Scanning::impl::~impl() {}
 
+struct ExtendedEventTypeOptions {
+  bool connectable{false};
+  bool scannable{false};
+  bool directed{false};
+  bool scan_response{false};
+  bool legacy{false};
+  bool continuing{false};
+  bool truncated{false};
+};
+
+constexpr uint16_t kBleEventConnectableBit = (0x0001 << 0);   // BLE_EVT_CONNECTABLE_BIT
+constexpr uint16_t kBleEventScannableBit = (0x0001 << 1);     // BLE_EVT_SCANNABLE_BIT
+constexpr uint16_t kBleEventDirectedBit = (0x0001 << 2);      // BLE_EVT_DIRECTED_BIT
+constexpr uint16_t kBleEventScanResponseBit = (0x0001 << 3);  // BLE_EVT_SCAN_RESPONSE_BIT
+constexpr uint16_t kBleEventLegacyBit = (0x0001 << 4);        // BLE_EVT_LEGACY_BIT
+constexpr uint16_t kBleEventIncompleteContinuing = (0x0001 << 5);
+constexpr uint16_t kBleEventIncompleteTruncated = (0x0001 << 6);
+
+static void TransformToExtendedEventType(uint16_t* extended_event_type, ExtendedEventTypeOptions o) {
+  ASSERT(extended_event_type != nullptr);
+  *extended_event_type = (o.connectable ? kBleEventConnectableBit : 0) | (o.scannable ? kBleEventScannableBit : 0) |
+                         (o.directed ? kBleEventDirectedBit : 0) | (o.scan_response ? kBleEventScanResponseBit : 0) |
+                         (o.legacy ? kBleEventLegacyBit : 0) | (o.continuing ? kBleEventIncompleteContinuing : 0) |
+                         (o.truncated ? kBleEventIncompleteTruncated : 0);
+}
+
+void Scanning::impl::on_advertisements(std::vector<std::shared_ptr<hci::LeReport>> reports) {
+  for (auto le_report : reports) {
+    AdvertisingReport report{
+        .string_address = le_report->address_.ToString(),
+        .address_type = static_cast<uint8_t>(le_report->address_type_),
+        .rssi = le_report->rssi_,
+        .extended_event_type = 0,
+        .data = nullptr,
+        .len = 0,
+    };
+
+    uint8_t advertising_data_buffer[kAdvertisingReportBufferSize];
+    // Copy gap data, if any, into temporary buffer as payload for legacy stack.
+    if (!le_report->gap_data_.empty()) {
+      bzero(advertising_data_buffer, kAdvertisingReportBufferSize);
+      uint8_t* p = advertising_data_buffer;
+      for (auto gap_data : le_report->gap_data_) {
+        *p++ = gap_data.size() + sizeof(gap_data.data_type_);
+        *p++ = static_cast<uint8_t>(gap_data.data_type_);
+        p = (uint8_t*)memcpy(p, &gap_data.data_[0], gap_data.data_.size()) + gap_data.data_.size();
+      }
+      report.data = advertising_data_buffer;
+      report.len = p - report.data;
+    }
+
+    switch (le_report->GetReportType()) {
+      case hci::LeReport::ReportType::ADVERTISING_EVENT:
+        switch (le_report->advertising_event_type_) {
+          case hci::AdvertisingEventType::ADV_IND:
+            TransformToExtendedEventType(&report.extended_event_type,
+                                         {.connectable = true, .scannable = true, .legacy = true});
+            break;
+          case hci::AdvertisingEventType::ADV_DIRECT_IND:
+            TransformToExtendedEventType(&report.extended_event_type,
+                                         {.connectable = true, .directed = true, .legacy = true});
+            break;
+          case hci::AdvertisingEventType::ADV_SCAN_IND:
+            TransformToExtendedEventType(&report.extended_event_type, {.scannable = true, .legacy = true});
+            break;
+          case hci::AdvertisingEventType::ADV_NONCONN_IND:
+            TransformToExtendedEventType(&report.extended_event_type, {.legacy = true});
+            break;
+          case hci::AdvertisingEventType::ADV_DIRECT_IND_LOW:  // SCAN_RESPONSE
+            TransformToExtendedEventType(
+                &report.extended_event_type,
+                {.connectable = true, .scannable = true, .scan_response = true, .legacy = true});
+            break;
+          default:
+            LOG_WARN("%s Unsupported event type:%s", __func__,
+                     AdvertisingEventTypeText(le_report->advertising_event_type_).c_str());
+            return;
+        }
+        advertising_callback_(report);
+        break;
+
+      case hci::LeReport::ReportType::DIRECTED_ADVERTISING_EVENT: {
+        DirectedAdvertisingReport directed_report(report);
+        std::shared_ptr<hci::DirectedLeReport> directed_le_report =
+            std::static_pointer_cast<hci::DirectedLeReport>(le_report);
+        directed_report.directed_advertising_type = static_cast<uint8_t>(directed_le_report->direct_address_type_);
+        directed_advertising_callback_(directed_report);
+      } break;
+
+      case hci::LeReport::ReportType::EXTENDED_ADVERTISING_EVENT: {
+        ExtendedAdvertisingReport extended_report(report);
+        std::shared_ptr<hci::ExtendedLeReport> extended_le_report =
+            std::static_pointer_cast<hci::ExtendedLeReport>(le_report);
+        TransformToExtendedEventType(&report.extended_event_type, {.connectable = extended_le_report->connectable_,
+                                                                   .scannable = extended_le_report->scannable_,
+                                                                   .directed = extended_le_report->directed_,
+                                                                   .scan_response = extended_le_report->scan_response_,
+                                                                   .legacy = false,
+                                                                   .continuing = !extended_le_report->complete_,
+                                                                   .truncated = extended_le_report->truncated_});
+        extended_advertising_callback_(extended_report);
+      } break;
+    }
+  }
+}
+
+void Scanning::impl::on_timeout() {
+  timeout_callback_();
+}
+
+os::Handler* Scanning::impl::Handler() {
+  return handler_;
+}
+
+void Scanning::impl::StartScanning(bool set_active, AdvertisingReportCallback advertising_callback,
+                                   DirectedAdvertisingReportCallback directed_advertising_callback,
+                                   ExtendedAdvertisingReportCallback extended_advertising_callback,
+                                   ScanningTimeoutCallback timeout_callback) {
+  active_scanning_ = set_active;
+  advertising_callback_ = advertising_callback;
+  directed_advertising_callback_ = directed_advertising_callback;
+  extended_advertising_callback_ = extended_advertising_callback;
+  timeout_callback_ = timeout_callback;
+
+  scanning_manager_->StartScan(this);
+  LOG_DEBUG("%s Started le %s scanning", __func__, (active_scanning_) ? "active" : "passive");
+}
+
+void Scanning::impl::StopScanning() {
+  LOG_DEBUG("%s Stopping le %s scanning", __func__, (active_scanning_) ? "active" : "passive");
+  scanning_manager_->StopScan(common::Bind(&impl::OnStopped, common::Unretained(this)));
+  advertising_callback_ = {};
+  directed_advertising_callback_ = {};
+  extended_advertising_callback_ = {};
+  timeout_callback_ = {};
+}
+
+void Scanning::impl::OnStopped() {
+  LOG_DEBUG("%s Stopped le %s scanning", __func__, (active_scanning_) ? "active" : "passive");
+}
+
+void Scanning::StartScanning(bool set_active, AdvertisingReportCallback advertising_callback,
+                             DirectedAdvertisingReportCallback directed_advertising_callback,
+                             ExtendedAdvertisingReportCallback extended_advertising_callback,
+                             ScanningTimeoutCallback timeout_callback) {
+  pimpl_->StartScanning(set_active, advertising_callback, directed_advertising_callback, extended_advertising_callback,
+                        timeout_callback);
+}
+
+void Scanning::StopScanning() {
+  pimpl_->StopScanning();
+}
+
 /**
  * Module methods
  */
@@ -50,7 +228,7 @@
 }
 
 void Scanning::Start() {
-  pimpl_ = std::make_unique<impl>(GetDependency<hci::LeScanningManager>());
+  pimpl_ = std::make_unique<impl>(GetDependency<hci::LeScanningManager>(), GetHandler());
 }
 
 void Scanning::Stop() {
diff --git a/gd/shim/scanning.h b/gd/shim/scanning.h
index 8768ead..b19ca34 100644
--- a/gd/shim/scanning.h
+++ b/gd/shim/scanning.h
@@ -29,6 +29,12 @@
   Scanning() = default;
   ~Scanning() = default;
 
+  void StartScanning(bool set_active, AdvertisingReportCallback advertising_callback,
+                     DirectedAdvertisingReportCallback directed_advertisting_callback,
+                     ExtendedAdvertisingReportCallback extended_advertising_callback,
+                     ScanningTimeoutCallback timeout_callback) override;
+  void StopScanning() override;
+
   static const ModuleFactory Factory;
 
  protected: