1 /*
2  * Copyright 2022 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 
17 #pragma once
18 
19 #include <memory>
20 #include <string>
21 
22 #include "common/contextual_callback.h"
23 #include "hci/address.h"
24 #include "module.h"
25 
26 namespace bluetooth {
27 namespace hci {
28 namespace acl_manager {
29 
30 // The AclScheduler is responsible for *scheduling* ACL connection-related operations (outgoing
31 // connections, incoming connections, and remote name requests). It maintains a queue of operations
32 // initiated by us, and tracks all incoming connections. We should never initiate a connection
33 // operation directly - instead, it should always pass through this class, so that we can be sure
34 // that it does not conflict with other operations.
35 //
36 // However, it does not perform any actual HCI operations itself - it simply takes in callbacks, and
37 // executes them at the appropriate time.
38 class AclScheduler : public bluetooth::Module {
39 public:
40   // Schedule an ACL Create Connection request
41   void EnqueueOutgoingAclConnection(Address address,
42                                     common::ContextualOnceCallback<void()> start_connection);
43 
44   // Inform the scheduler that we are handling an incoming connection. This will block all future
45   // outgoing ACL connection events until the incoming connection is deregistered.
46   void RegisterPendingIncomingConnection(Address address);
47 
48   // Report that an ACL connection has completed, and dispatch to the appropriate callback based on
49   // the internal state. Then, start the next operation.
50   virtual void ReportAclConnectionCompletion(
51           Address address, common::ContextualOnceCallback<void()> handle_outgoing_connection,
52           common::ContextualOnceCallback<void()> handle_incoming_connection,
53           common::ContextualOnceCallback<void(std::string)> handle_unknown_connection);
54 
55   // Same as above, but for the outgoing ACL connection in particular (and no callbacks)
56   void ReportOutgoingAclConnectionFailure();
57 
58   // Cancel an ACL connection. If the request is already outgoing, we will invoke cancel_connection,
59   // without clearing the outgoing request. Otherwise, we will remove the request from the queue,
60   // invoke cancel_connection_completed, and execute the next request in the queue.
61   void CancelAclConnection(Address address,
62                            common::ContextualOnceCallback<void()> cancel_connection,
63                            common::ContextualOnceCallback<void()> cancel_connection_completed);
64 
65   // Schedule a Remote Name Request. When the request is started, start_request will be invoked. If
66   // the request is cancelled before it is dequeued, cancel_request_completed will be invoked.
67   void EnqueueRemoteNameRequest(Address address,
68                                 common::ContextualOnceCallback<void()> start_request,
69                                 common::ContextualOnceCallback<void()> cancel_request_completed);
70 
71   // Report that a Remote Name Request connection has completed, so we can resume popping from the
72   // queue.
73   void ReportRemoteNameRequestCompletion(Address address);
74 
75   // Cancel an Remote Name Request. If the request is already outgoing, we will invoke
76   // cancel_request, without clearing the outgoing request. Otherwise, we will invoke the
77   // cancel_request_completed callback registered on the initial enqueue.
78   void CancelRemoteNameRequest(Address address,
79                                common::ContextualOnceCallback<void()> cancel_request);
80 
81 private:
82   struct impl;
83   std::unique_ptr<impl> pimpl_;
84 
85 protected:
86   void ListDependencies(ModuleList* list) const override;
87   void Start() override;
88   void Stop() override;
ToString()89   std::string ToString() const override { return std::string("AclSchedulerModule"); }
90 
91 public:
92   static const ModuleFactory Factory;
93   AclScheduler();
94   virtual ~AclScheduler();
95 };
96 
97 }  // namespace acl_manager
98 }  // namespace hci
99 }  // namespace bluetooth
100