OSDN Git Service

L2CAP: Add Classic Fixed Channel APIs
authorJack He <siyuanh@google.com>
Fri, 9 Aug 2019 22:10:44 +0000 (15:10 -0700)
committerHansong Zhang <hsz@google.com>
Fri, 9 Aug 2019 22:20:39 +0000 (15:20 -0700)
* Add ClassicFixedChannelManager
* Add ClassicFixedChannelService
* Add ClassicFixedChannel
* Modify cid and constants definition

Bug: 138261142
Test: bluetooth_test_gd
Change-Id: Iae4e398e938436c74d16b49834a4bd5146b03873

12 files changed:
gd/l2cap/Android.bp
gd/l2cap/cid.h
gd/l2cap/classic_fixed_channel.cc [new file with mode: 0644]
gd/l2cap/classic_fixed_channel.h [new file with mode: 0644]
gd/l2cap/classic_fixed_channel_manager.cc [new file with mode: 0644]
gd/l2cap/classic_fixed_channel_manager.h [new file with mode: 0644]
gd/l2cap/classic_fixed_channel_service.cc [new file with mode: 0644]
gd/l2cap/classic_fixed_channel_service.h [new file with mode: 0644]
gd/l2cap/constant.h
gd/l2cap/l2cap_layer.cc
gd/l2cap/l2cap_layer.h
gd/l2cap/security_policy.h [new file with mode: 0644]

index 223d5b6..d061305 100644 (file)
@@ -2,6 +2,9 @@ filegroup {
     name: "BluetoothL2capSources",
     srcs: [
         "l2cap_layer.cc",
+        "classic_fixed_channel.cc",
+        "classic_fixed_channel_manager.cc",
+        "classic_fixed_channel_service.cc",
     ],
 }
 
index 6c72a09..292131b 100644 (file)
@@ -29,5 +29,12 @@ constexpr Cid kLastFixedChannel = 63;
 constexpr Cid kFirstDynamicChannel = kLastFixedChannel + 1;
 constexpr Cid kLastDynamicChannel = (uint16_t)(0xffff + 1);
 
+constexpr Cid kClassicSignallingCid = 1;
+constexpr Cid kConnectionlessCid = 2;
+constexpr Cid kLeAttributeCid = 4;
+constexpr Cid kLeSignallingCid = 5;
+constexpr Cid kSmpCid = 6;
+constexpr Cid kSmpBrCid = 7;
+
 }  // namespace l2cap
 }  // namespace bluetooth
diff --git a/gd/l2cap/classic_fixed_channel.cc b/gd/l2cap/classic_fixed_channel.cc
new file mode 100644 (file)
index 0000000..6c08eec
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/classic_fixed_channel.h"
+
+namespace bluetooth {
+namespace l2cap {
+void ClassicFixedChannel::RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback callback) {}
+void ClassicFixedChannel::Acquire() {}
+void ClassicFixedChannel::Release() {}
+common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>*
+ClassicFixedChannel::GetQueueUpEnd() const {
+  return nullptr;
+}
+}  // namespace l2cap
+}  // namespace bluetooth
\ No newline at end of file
diff --git a/gd/l2cap/classic_fixed_channel.h b/gd/l2cap/classic_fixed_channel.h
new file mode 100644 (file)
index 0000000..1cc6117
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "common/bidi_queue.h"
+#include "common/callback.h"
+#include "os/handler.h"
+#include "packet/base_packet_builder.h"
+#include "packet/packet_view.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+/**
+ * L2CAP fixed channel object. When a new object is created, it must be
+ * acquired through calling {@link FixedChannel#Acquire()} within X seconds.
+ * Otherwise, {@link FixeChannel#Release()} will be called automatically.
+ *
+ */
+class ClassicFixedChannel {
+ public:
+  using OnCloseCallback = common::Callback<void()>;
+
+  /**
+   * Register close callback. If close callback is registered, when a channel is closed, the channel's resource will
+   * only be freed after on_close callback is invoked. Otherwise, if no on_close callback is registered, the channel's
+   * resource will be freed immediately after closing.
+   *
+   * @param on_close The callback invoked upon channel closing.
+   */
+  void RegisterOnCloseCallback(os::Handler* handler, OnCloseCallback on_close);
+
+  /**
+   * Indicate that this Fixed Channel is being used. This will prevent ACL
+   * connection from being disconnected.
+   */
+  void Acquire();
+
+  /**
+   * Indicate that this Fixed Channel is no longer being used. ACL connection
+   * will be disconnected after X seconds if no other DynamicChannel is connected
+   * or no other Fixed Channel is using this ACL connection. However a module can
+   * still receive data on this channel as long as it remains open.
+   */
+  void Release();
+
+  /**
+   * This method will retrieve the data channel queue to send and receive packets.
+   *
+   * {@see BidiQueueEnd}
+   *
+   * @return The upper end of a bi-directional queue.
+   */
+  common::BidiQueueEnd<packet::PacketView<packet::kLittleEndian>, packet::BasePacketBuilder>* GetQueueUpEnd() const;
+};
+
+}  // namespace l2cap
+}  // namespace bluetooth
diff --git a/gd/l2cap/classic_fixed_channel_manager.cc b/gd/l2cap/classic_fixed_channel_manager.cc
new file mode 100644 (file)
index 0000000..928bedb
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/classic_fixed_channel_manager.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+bool ClassicFixedChannelManager::ConnectServices(common::Address device,
+                                                 OnConnectionFailureCallback on_connection_failure,
+                                                 os::Handler* handler) {
+  return false;
+}
+
+bool ClassicFixedChannelManager::RegisterService(Cid cid, const SecurityPolicy& security_policy,
+                                                 OnRegistrationCompleteCallback on_registration_complete,
+                                                 OnConnectionOpenCallback on_connection_open, os::Handler* handler) {
+  return true;
+}
+
+}  // namespace l2cap
+}  // namespace bluetooth
\ No newline at end of file
diff --git a/gd/l2cap/classic_fixed_channel_manager.h b/gd/l2cap/classic_fixed_channel_manager.h
new file mode 100644 (file)
index 0000000..cacc368
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <string>
+
+#include "common/address.h"
+#include "l2cap/cid.h"
+#include "l2cap/classic_fixed_channel.h"
+#include "l2cap/classic_fixed_channel_service.h"
+#include "l2cap/security_policy.h"
+#include "os/handler.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+class ClassicFixedChannelManager {
+  /**
+   * OnConnectionFailureCallback(std::string failure_reason);
+   */
+  using OnConnectionFailureCallback = common::OnceCallback<void(std::string)>;
+
+  /**
+   * OnConnectionOpenCallback(ClassicFixedChannel channel);
+   */
+  using OnConnectionOpenCallback = common::OnceCallback<void(ClassicFixedChannel)>;
+
+  enum RegistrationResult { SUCCESS, FAIL };
+
+  /**
+   * OnRegistrationFailureCallback(RegistrationResult result, ClassicFixedChannelService service);
+   */
+  using OnRegistrationCompleteCallback = common::OnceCallback<void(RegistrationResult, ClassicFixedChannelService)>;
+
+  /**
+   * Connect to ALL fixed channels on a remote device
+   *
+   * - This method is asynchronous
+   * - When false is returned, the connection fails immediately
+   * - When true is returned, method caller should wait for on_fail_callback or on_open_callback registered through
+   *   RegisterService() API.
+   * - If an ACL connection does not exist, this method will create an ACL connection. As a result, on_open_callback
+   *   supplied through RegisterService() will be triggered to provide the actual ClassicFixedChannel objects
+   * - If fixed channel on a remote device is already reported as connected via on_open_callback and has been acquired
+   *   via ClassicFixedChannel#Acquire() API, it won't be reported again
+   * - If no service is registered, this call is a no-op and on on_fail_callback will be triggered
+   *
+   * NOTE:
+   * This call will initiate an effort to connect all fixed channel services on a remote device.
+   * Due to the connectionless nature of fixed channels, all fixed channels will be connected together.
+   * If a fixed channel service does not need a particular fixed channel. It should release the received
+   * channel immediately after receiving on_open_callback via ClassicFixedChannel#Release()
+   *
+   * A module calling ConnectServices() must have called RegisterService() before.
+   * The callback will come back from on_open_callback in the service that is registered
+   *
+   * @param device: Remote device to make this connection.
+   * @param on_fail_callback: A callback to indicate connection failure along with a status code.
+   * @param handler: The handler context in which to execute the @callback parameters.
+   *
+   * Returns: true if connection was able to be initiated, false otherwise.
+   */
+  bool ConnectServices(common::Address device, OnConnectionFailureCallback on_fail_callback, os::Handler* handler);
+
+  /**
+   * Register a service to receive incoming connections bound to a specific channel.
+   *
+   * - This method is asynchronous.
+   * - When false is returned, the registration fails immediately.
+   * - When true is returned, method caller should wait for on_service_registered callback that contains a
+   *   ClassicFixedChannelService object. The registered service can be managed from that object.
+   * - If a CID is already registered or some other error happens,
+   * - After a service is registered, any classic ACL connection will create a ClassicFixedChannel object that is
+   *   delivered through on_open_callback
+   * - on_open_callback, if any, must be triggered after on_service_registered callback
+   *
+   * @param cid: Classic cid used to receive incoming connections
+   * @param security_policy: The security policy used for the connection.
+   * @param on_registration_complete: A callback to indicate the service setup has completed. If the return status is
+   *        not SUCCESS, it means service is not registered due to reasons like CID already take
+   * @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
+   * @param handler: The handler context in which to execute the @callback parameter.
+   */
+  bool RegisterService(Cid cid, const SecurityPolicy& security_policy,
+                       OnRegistrationCompleteCallback on_registration_complete,
+                       OnConnectionOpenCallback on_connection_open, os::Handler* handler);
+};
+
+}  // namespace l2cap
+}  // namespace bluetooth
\ No newline at end of file
diff --git a/gd/l2cap/classic_fixed_channel_service.cc b/gd/l2cap/classic_fixed_channel_service.cc
new file mode 100644 (file)
index 0000000..8a08509
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "l2cap/classic_fixed_channel_service.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+void ClassicFixedChannelService::Unregister(OnUnregisteredCallback on_unregistered) {}
+
+}  // namespace l2cap
+}  // namespace bluetooth
\ No newline at end of file
diff --git a/gd/l2cap/classic_fixed_channel_service.h b/gd/l2cap/classic_fixed_channel_service.h
new file mode 100644 (file)
index 0000000..9fddeb6
--- /dev/null
@@ -0,0 +1,39 @@
+
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "common/address.h"
+#include "common/callback.h"
+
+namespace bluetooth {
+namespace l2cap {
+
+class ClassicFixedChannelService {
+ public:
+  using OnUnregisteredCallback = common::OnceCallback<void()>;
+
+  /**
+   * Unregister a service from L2CAP module. This operation cannot fail.
+   * All channels opened for this service will be invalidated.
+   *
+   * @param on_unregistered will be triggered when unregistration is complete
+   */
+  void Unregister(OnUnregisteredCallback on_unregistered);
+};
+
+}  // namespace l2cap
+}  // namespace bluetooth
\ No newline at end of file
index 59c8d44..51b07c5 100644 (file)
@@ -30,13 +30,6 @@ constexpr std::chrono::milliseconds bogus_link_wakeup_time = std::chrono::millis
 
 constexpr SignalId kInitialSignalId = SignalId(0x80);
 
-constexpr Cid kClassicSignallingCid = 1;
-constexpr Cid kConnectionlessCid = 2;
-constexpr Cid kLeAttributeCid = 4;
-constexpr Cid kLeSignallingCid = 5;
-constexpr Cid kSmpCid = 6;
-constexpr Cid kSmpBrCid = 7;
-
 // Time after last channels closes before link is torn down
 constexpr auto kLinkDisconnectTimeout = std::chrono::seconds(30);
 
index 899b780..a637998 100644 (file)
@@ -39,5 +39,11 @@ void L2capLayer::Start() {}
 
 void L2capLayer::Stop() {}
 
+std::unique_ptr<ClassicFixedChannelManager> L2capLayer::GetClassicFixedChannelManager() {
+  return std::make_unique<ClassicFixedChannelManager>();
+}
+
+struct L2capLayer::impl {};
+
 }  // namespace l2cap
 }  // namespace bluetooth
\ No newline at end of file
index db39569..2e2aa60 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <memory>
 
+#include "l2cap/classic_fixed_channel_manager.h"
 #include "module.h"
 
 namespace bluetooth {
@@ -36,7 +37,14 @@ class L2capLayer : public bluetooth::Module {
 
   void Stop() override;
 
+  /**
+   * Get the api to the classic channel l2cap module
+   */
+  std::unique_ptr<ClassicFixedChannelManager> GetClassicFixedChannelManager();
+
  private:
+  struct impl;
+  std::unique_ptr<impl> impl_;
   DISALLOW_COPY_AND_ASSIGN(L2capLayer);
 };
 
diff --git a/gd/l2cap/security_policy.h b/gd/l2cap/security_policy.h
new file mode 100644 (file)
index 0000000..5a06401
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+namespace bluetooth {
+namespace l2cap {
+
+class SecurityPolicy {};
+
+}  // namespace l2cap
+}  // namespace bluetooth
\ No newline at end of file