• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <string>
19 
20 #include "hci/acl_manager.h"
21 #include "hci/address.h"
22 #include "l2cap/l2cap_packets.h"
23 #include "l2cap/le/dynamic_channel.h"
24 #include "l2cap/le/dynamic_channel_configuration_option.h"
25 #include "l2cap/le/dynamic_channel_service.h"
26 #include "l2cap/psm.h"
27 #include "l2cap/security_policy.h"
28 #include "os/handler.h"
29 
30 namespace bluetooth {
31 namespace l2cap {
32 namespace le {
33 
34 class L2capLeModule;
35 
36 namespace internal {
37 class LinkManager;
38 class DynamicChannelServiceManagerImpl;
39 }  // namespace internal
40 
41 class DynamicChannelManager {
42  public:
43   enum class ConnectionResultCode {
44     SUCCESS = 0,
45     FAIL_NO_SERVICE_REGISTERED = 1,  // No service is registered
46     FAIL_HCI_ERROR = 2,              // See hci_error
47     FAIL_L2CAP_ERROR = 3,            // See l2cap_connection_response_result
48   };
49 
50   struct ConnectionResult {
51     ConnectionResultCode connection_result_code = ConnectionResultCode::SUCCESS;
52     hci::ErrorCode hci_error = hci::ErrorCode::SUCCESS;
53     ConnectionResponseResult l2cap_connection_response_result = ConnectionResponseResult::SUCCESS;
54   };
55   /**
56    * OnConnectionFailureCallback(std::string failure_reason);
57    */
58   using OnConnectionFailureCallback = common::OnceCallback<void(ConnectionResult result)>;
59 
60   /**
61    * OnConnectionOpenCallback(DynamicChannel channel);
62    */
63   using OnConnectionOpenCallback = common::Callback<void(std::unique_ptr<DynamicChannel>)>;
64 
65   enum class RegistrationResult {
66     SUCCESS = 0,
67     FAIL_DUPLICATE_SERVICE = 1,  // Duplicate service registration for the same PSM
68     FAIL_INVALID_SERVICE = 2,    // Invalid PSM
69   };
70 
71   /**
72    * OnRegistrationFailureCallback(RegistrationResult result, DynamicChannelService service);
73    */
74   using OnRegistrationCompleteCallback =
75       common::OnceCallback<void(RegistrationResult, std::unique_ptr<DynamicChannelService>)>;
76 
77   /**
78    * Connect to a Dynamic channel on a remote device
79    *
80    * - This method is asynchronous
81    * - When false is returned, the connection fails immediately
82    * - When true is returned, method caller should wait for on_fail_callback or on_open_callback
83    * - If an LE connection does not exist, this method will create an LE connection
84    * - If HCI connection failed, on_fail_callback will be triggered with FAIL_HCI_ERROR
85    * - If Dynamic channel on a remote device is already reported as connected via on_open_callback, it won't be
86    *   reported again
87    *
88    * @param device: Remote device to make this connection.
89    * @param psm: Service PSM to connect. PSM is defined in Core spec Vol 3 Part A 4.2.
90    * @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
91    * @param on_fail_callback: A callback to indicate connection failure along with a status code.
92    * @param handler: The handler context in which to execute the @callback parameters.
93    * @param configuration_option: The configuration options for this channel
94    *
95    * Returns: true if connection was able to be initiated, false otherwise.
96    */
97   bool ConnectChannel(hci::AddressWithType device, DynamicChannelConfigurationOption configuration_option, Psm psm,
98                       OnConnectionOpenCallback on_connection_open, OnConnectionFailureCallback on_fail_callback,
99                       os::Handler* handler);
100 
101   /**
102    * Register a service to receive incoming connections bound to a specific channel.
103    *
104    * - This method is asynchronous.
105    * - When false is returned, the registration fails immediately.
106    * - When true is returned, method caller should wait for on_service_registered callback that contains a
107    *   DynamicChannelService object. The registered service can be managed from that object.
108    * - If a PSM is already registered or some other error happens, on_registration_complete will be triggered with a
109    *   non-SUCCESS value
110    * - After a service is registered, a DynamicChannel is delivered through on_open_callback when the remote
111    *   initiates a channel open and channel is opened successfully
112    * - on_open_callback, will only be triggered after on_service_registered callback
113    *
114    * @param security_policy: The security policy used for the connection.
115    * @param psm: Service PSM to register. PSM is defined in Core spec Vol 3 Part A 4.2.
116    * @param on_registration_complete: A callback to indicate the service setup has completed. If the return status is
117    *        not SUCCESS, it means service is not registered due to reasons like PSM already take
118    * @param on_open_callback: A callback to indicate success of a connection initiated from a remote device.
119    * @param handler: The handler context in which to execute the @callback parameter.
120    * @param configuration_option: The configuration options for this channel
121    */
122   bool RegisterService(Psm psm, DynamicChannelConfigurationOption configuration_option,
123                        const SecurityPolicy& security_policy, OnRegistrationCompleteCallback on_registration_complete,
124                        OnConnectionOpenCallback on_connection_open, os::Handler* handler);
125 
126   friend class L2capLeModule;
127 
128  private:
129   // The constructor is not to be used by user code
DynamicChannelManager(internal::DynamicChannelServiceManagerImpl * service_manager,internal::LinkManager * link_manager,os::Handler * l2cap_layer_handler)130   DynamicChannelManager(internal::DynamicChannelServiceManagerImpl* service_manager,
131                         internal::LinkManager* link_manager, os::Handler* l2cap_layer_handler)
132       : service_manager_(service_manager), link_manager_(link_manager), l2cap_layer_handler_(l2cap_layer_handler) {
133     ASSERT(service_manager_ != nullptr);
134     ASSERT(link_manager_ != nullptr);
135     ASSERT(l2cap_layer_handler_ != nullptr);
136   }
137   internal::DynamicChannelServiceManagerImpl* service_manager_ = nullptr;
138   internal::LinkManager* link_manager_ = nullptr;
139   os::Handler* l2cap_layer_handler_ = nullptr;
140   DISALLOW_COPY_AND_ASSIGN(DynamicChannelManager);
141 };
142 
143 }  // namespace le
144 }  // namespace l2cap
145 }  // namespace bluetooth
146