Merge "Initial Entry for le advertising shim"
diff --git a/gd/os/linux_generic/reactive_semaphore.cc b/gd/os/linux_generic/reactive_semaphore.cc
index 4cc0b4c..df0050a 100644
--- a/gd/os/linux_generic/reactive_semaphore.cc
+++ b/gd/os/linux_generic/reactive_semaphore.cc
@@ -16,6 +16,7 @@
 
 #include "reactive_semaphore.h"
 
+#include <error.h>
 #include <sys/eventfd.h>
 #include <unistd.h>
 #include <functional>
@@ -33,19 +34,19 @@
 ReactiveSemaphore::~ReactiveSemaphore() {
   int close_status;
   RUN_NO_INTR(close_status = close(fd_));
-  ASSERT(close_status != -1);
+  ASSERT_LOG(close_status != -1, "close failed: %s", strerror(errno));
 }
 
 void ReactiveSemaphore::Decrease() {
   uint64_t val = 0;
   auto read_result = eventfd_read(fd_, &val);
-  ASSERT(read_result != -1);
+  ASSERT_LOG(read_result != -1, "decrease failed: %s", strerror(errno));
 }
 
 void ReactiveSemaphore::Increase() {
   uint64_t val = 1;
   auto write_result = eventfd_write(fd_, val);
-  ASSERT(write_result != -1);
+  ASSERT_LOG(write_result != -1, "increase failed: %s", strerror(errno));
 }
 
 int ReactiveSemaphore::GetFd() {
diff --git a/main/shim/l2cap.cc b/main/shim/l2cap.cc
index fb4dd02..98db9cb 100644
--- a/main/shim/l2cap.cc
+++ b/main/shim/l2cap.cc
@@ -26,6 +26,7 @@
 constexpr size_t kBtHdrSize = sizeof(BT_HDR);
 constexpr uint16_t kInvalidConnectionInterfaceDescriptor = 0;
 constexpr bool kDisconnectResponseRequired = false;
+constexpr uint16_t kConnectionSuccess = 0;
 
 bool bluetooth::legacy::shim::PsmData::IsPsmAllocated(uint16_t psm) const {
   return psm_to_callback_map_.find(psm) != psm_to_callback_map_.end();
@@ -159,14 +160,34 @@
   auto completed = register_completed.get_future();
   bluetooth::shim::GetL2cap()->RegisterService(
       psm,
-      std::bind(&bluetooth::legacy::shim::L2cap::OnConnectionReady, this,
-                std::placeholders::_1, std::placeholders::_2,
-                std::placeholders::_3),
+      std::bind(
+          &bluetooth::legacy::shim::L2cap::OnRemoteInitiatedConnectionCreated,
+          this, std::placeholders::_1, std::placeholders::_2,
+          std::placeholders::_3),
       std::move(register_completed));
   completed.wait();
   LOG_DEBUG(LOG_TAG, "Successfully registered service on psm:%hd", psm);
 }
 
+void bluetooth::legacy::shim::L2cap::OnRemoteInitiatedConnectionCreated(
+    std::string string_address, uint16_t psm, uint16_t cid) {
+  RawAddress raw_address;
+  RawAddress::FromString(string_address, raw_address);
+
+  LOG_DEBUG(LOG_TAG,
+            "Sending connection indicator to upper stack from device:%s "
+            "psm:%hd cid:%hd",
+            string_address.c_str(), psm, cid);
+
+  CHECK(!ConnectionExists(cid));
+  cid_to_psm_map_[cid] = psm;
+  SetCallbacks(cid, Classic().Callbacks(psm));
+  const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(psm);
+  CHECK(callbacks != nullptr);
+  callbacks->pL2CA_ConnectInd_Cb(raw_address, cid, psm /* UNUSED */,
+                                 0 /* UNUSED */);
+}
+
 void bluetooth::legacy::shim::L2cap::UnregisterService(uint16_t psm) {
   if (!Classic().IsPsmRegistered(psm)) {
     LOG_WARN(LOG_TAG,
@@ -182,9 +203,6 @@
 
 uint16_t bluetooth::legacy::shim::L2cap::CreateConnection(
     uint16_t psm, const RawAddress& raw_address) {
-  LOG_DEBUG(LOG_TAG, "Requesting connection to psm:%hd address:%s", psm,
-            raw_address.ToString().c_str());
-
   if (!Classic().IsPsmRegistered(psm)) {
     LOG_WARN(LOG_TAG, "Service must be registered in order to connect psm:%hd",
              psm);
@@ -193,12 +211,18 @@
 
   std::promise<uint16_t> connect_completed;
   auto completed = connect_completed.get_future();
+  LOG_DEBUG(LOG_TAG,
+            "Starting local initiated connection to psm:%hd address:%s", psm,
+            raw_address.ToString().c_str());
+
   bluetooth::shim::GetL2cap()->CreateConnection(
       psm, raw_address.ToString(),
-      std::bind(&bluetooth::legacy::shim::L2cap::OnConnectionReady, this,
-                std::placeholders::_1, std::placeholders::_2,
-                std::placeholders::_3),
+      std::bind(
+          &bluetooth::legacy::shim::L2cap::OnLocalInitiatedConnectionCreated,
+          this, std::placeholders::_1, std::placeholders::_2,
+          std::placeholders::_3),
       std::move(connect_completed));
+
   uint16_t cid = completed.get();
   if (cid == kInvalidConnectionInterfaceDescriptor) {
     LOG_WARN(LOG_TAG,
@@ -209,33 +233,32 @@
               "Successfully started connection to psm:%hd address:%s"
               " connection_interface_descriptor:%hd",
               psm, raw_address.ToString().c_str(), cid);
-    CHECK(cid_to_psm_map_.find(cid) == cid_to_psm_map_.end());
+    CHECK(!ConnectionExists(cid));
     cid_to_psm_map_[cid] = psm;
     SetCallbacks(cid, Classic().Callbacks(psm));
-    const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(psm);
-    CHECK(callbacks != nullptr);
   }
   return cid;
 }
 
-void bluetooth::legacy::shim::L2cap::OnConnectionReady(
-    std::string address_string, uint16_t psm, uint16_t cid) {
-  LOG_DEBUG(
-      LOG_TAG,
-      "l2cap got new connection psm:%hd connection_interface_descriptor:%hd",
-      psm, cid);
+void bluetooth::legacy::shim::L2cap::OnLocalInitiatedConnectionCreated(
+    std::string string_address, uint16_t psm, uint16_t cid) {
+  LOG_DEBUG(LOG_TAG,
+            "Sending connection confirm to the upper stack but really "
+            "a connection to %s has already been done cid:%hd",
+            string_address.c_str(), cid);
+  // TODO(cmanton) Make sure the device is correct for locally initiated
   const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(psm);
-  if (callbacks == nullptr) {
-    return;
-  }
-  LOG_DEBUG(LOG_TAG, "%s Setting postable map for cid:%d", __func__, cid);
-}
+  CHECK(callbacks != nullptr);
+  callbacks->pL2CA_ConnectCfm_Cb(cid, kConnectionSuccess);
+};
 
 bool bluetooth::legacy::shim::L2cap::Write(uint16_t cid, BT_HDR* bt_hdr) {
-  CHECK(ConnectionExists(cid));
   CHECK(bt_hdr != nullptr);
   const uint8_t* data = bt_hdr->data + bt_hdr->offset;
   size_t len = bt_hdr->len;
+  if (!ConnectionExists(cid) || len == 0) {
+    return false;
+  }
   LOG_DEBUG(LOG_TAG, "Writing data cid:%hd len:%zd", cid, len);
   bluetooth::shim::GetL2cap()->Write(cid, data, len);
   return true;
@@ -243,20 +266,24 @@
 
 bool bluetooth::legacy::shim::L2cap::WriteFlushable(uint16_t cid,
                                                     BT_HDR* bt_hdr) {
-  CHECK(ConnectionExists(cid));
   CHECK(bt_hdr != nullptr);
   const uint8_t* data = bt_hdr->data + bt_hdr->offset;
   size_t len = bt_hdr->len;
+  if (!ConnectionExists(cid) || len == 0) {
+    return false;
+  }
   bluetooth::shim::GetL2cap()->WriteFlushable(cid, data, len);
   return true;
 }
 
 bool bluetooth::legacy::shim::L2cap::WriteNonFlushable(uint16_t cid,
                                                        BT_HDR* bt_hdr) {
-  CHECK(ConnectionExists(cid));
   CHECK(bt_hdr != nullptr);
   const uint8_t* data = bt_hdr->data + bt_hdr->offset;
   size_t len = bt_hdr->len;
+  if (!ConnectionExists(cid) || len == 0) {
+    return false;
+  }
   bluetooth::shim::GetL2cap()->WriteNonFlushable(cid, data, len);
   return true;
 }
@@ -278,6 +305,7 @@
             static_cast<BT_HDR*>(osi_calloc(data.size() + kBtHdrSize));
         std::copy(data.begin(), data.end(), bt_hdr->data);
         bt_hdr->len = data.size();
+        CHECK(cid_to_callback_map_.find(cid) != cid_to_callback_map_.end());
         cid_to_callback_map_[cid]->pL2CA_DataInd_Cb(cid, bt_hdr);
       });
 
@@ -307,14 +335,12 @@
 bool bluetooth::legacy::shim::L2cap::ConfigRequest(
     uint16_t cid, const tL2CAP_CFG_INFO* config_info) {
   CHECK(ConnectionExists(cid));
-  LOG_INFO(LOG_TAG, "Received config request from upper layer");
-  CHECK(cid_to_psm_map_.find(cid) != cid_to_psm_map_.end());
-  const tL2CAP_APPL_INFO* callbacks = Classic().Callbacks(cid_to_psm_map_[cid]);
-  CHECK(callbacks != nullptr);
-  CHECK(cid_to_postable_map_.count(cid) == 1);
+  LOG_INFO(LOG_TAG, "Received config request from upper layer cid:%hd", cid);
 
-  auto func = cid_to_postable_map_[cid];
-  func([&cid, &callbacks](uint16_t cid2) {
+  bluetooth::shim::GetL2cap()->SendLoopbackResponse([this, cid]() {
+    CHECK(ConnectionExists(cid));
+    const tL2CAP_APPL_INFO* callbacks = cid_to_callback_map_[cid];
+    CHECK(callbacks != nullptr);
     tL2CAP_CFG_INFO cfg_info{
         .result = L2CAP_CFG_OK,
         .mtu_present = false,
@@ -325,7 +351,6 @@
         .ext_flow_spec_present = false,
         .flags = 0,
     };
-    LOG_INFO(LOG_TAG, "Config request lambda");
     callbacks->pL2CA_ConfigCfm_Cb(cid, &cfg_info);
     callbacks->pL2CA_ConfigInd_Cb(cid, &cfg_info);
   });
@@ -344,8 +369,8 @@
 
 bool bluetooth::legacy::shim::L2cap::DisconnectRequest(uint16_t cid) {
   CHECK(ConnectionExists(cid));
-  bluetooth::shim::GetL2cap()->CloseConnection(cid);
   cid_to_callback_map_.erase(cid);
+  bluetooth::shim::GetL2cap()->CloseConnection(cid);
   return true;
 }
 
diff --git a/main/shim/l2cap.h b/main/shim/l2cap.h
index e0828d6..2fbe0d6 100644
--- a/main/shim/l2cap.h
+++ b/main/shim/l2cap.h
@@ -53,14 +53,18 @@
   void RegisterService(uint16_t psm, const tL2CAP_APPL_INFO* callbacks,
                        bool enable_snoop);
   void UnregisterService(uint16_t psm);
+
   uint16_t CreateConnection(uint16_t psm, const RawAddress& raw_address);
-  void OnConnectionReady(std::string address_string, uint16_t psm,
-                         uint16_t cid);
 
   bool Write(uint16_t cid, BT_HDR* bt_hdr);
   bool WriteFlushable(uint16_t cid, BT_HDR* bt_hdr);
   bool WriteNonFlushable(uint16_t cid, BT_HDR* bt_hdr);
 
+  void OnLocalInitiatedConnectionCreated(std::string string_address,
+                                         uint16_t psm, uint16_t cid);
+  void OnRemoteInitiatedConnectionCreated(std::string string_addresss,
+                                          uint16_t psm, uint16_t cid);
+
   uint16_t GetNextDynamicClassicPsm();
   uint16_t GetNextDynamicLePsm();
 
@@ -78,9 +82,6 @@
   bool DisconnectRequest(uint16_t cid);
   bool DisconnectResponse(uint16_t cid);
 
-  void Test(void* context);
-  void Test2();
-
   L2cap();
 
   PsmData& Classic();
diff --git a/main/shim/l2cap_test.cc b/main/shim/l2cap_test.cc
index a7dddde..bf28f3c 100644
--- a/main/shim/l2cap_test.cc
+++ b/main/shim/l2cap_test.cc
@@ -233,7 +233,9 @@
   CHECK(cid != 0);
 
   // Simulate a successful connection response
-  l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+  l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+  CHECK(cnt_.L2caConnectCfmCb == 1);
+
   CHECK(l2cap_->ConfigRequest(cid, nullptr));
 }
 
@@ -248,7 +250,9 @@
   CHECK(cid != 0);
 
   // Simulate a successful connection response
-  l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+  l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+  CHECK(cnt_.L2caConnectCfmCb == 1);
+
   CHECK(l2cap_->ConfigResponse(cid, nullptr));
 }
 
@@ -263,7 +267,9 @@
   CHECK(cid != 0);
 
   // Simulate a successful connection response
-  l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+  l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+  CHECK(cnt_.L2caConnectCfmCb == 1);
+
   CHECK(l2cap_->DisconnectRequest(cid));
 }
 
@@ -278,7 +284,9 @@
   CHECK(cid != 0);
 
   // Simulate a successful connection response
-  l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+  l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
+  CHECK(cnt_.L2caConnectCfmCb == 1);
+
   CHECK(l2cap_->DisconnectResponse(cid));
 }
 
@@ -293,11 +301,12 @@
   CHECK(cid != 0);
 
   // Simulate a successful connection response
-  l2cap_->OnConnectionReady("11:22:33:44:55:66", kPsm, kCid);
+  l2cap_->OnLocalInitiatedConnectionCreated("11:22:33:44:55:66", kPsm, kCid);
   CHECK(cnt_.L2caConnectCfmCb == 1);
 
   CHECK(l2cap_->ConfigRequest(cid, nullptr) == true);
   CHECK(cnt_.L2caConfigCfmCb == 1);
+  CHECK(cnt_.L2caConfigIndCb == 1);
 
   BT_HDR* bt_hdr = (BT_HDR*)bt_hdr_data;
 
diff --git a/main/shim/test_stack.cc b/main/shim/test_stack.cc
index bd3b8ff..7baad68 100644
--- a/main/shim/test_stack.cc
+++ b/main/shim/test_stack.cc
@@ -66,7 +66,9 @@
 void TestGdShimL2cap::WriteNonFlushable(uint16_t cid, const uint8_t* data,
                                         size_t len) {}
 
-void TestGdShimL2cap::SendLoopbackResponse(std::function<void()>) {}
+void TestGdShimL2cap::SendLoopbackResponse(std::function<void()> function) {
+  function();
+}
 
 void TestStack::Start() {}