• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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 #include "model/controller/isochronous_connection_handler.h"
18 
19 #include "hci/address.h"
20 #include "log.h"
21 
22 namespace rootcanal {
23 
24 using bluetooth::hci::ErrorCode;
25 
26 std::unique_ptr<bluetooth::hci::LeSetCigParametersCompleteBuilder>
SetCigParameters(GroupParameters group_parameters,std::vector<StreamParameters> & streams,std::vector<uint16_t> handles)27 IsochronousConnectionHandler::SetCigParameters(
28     GroupParameters group_parameters, std::vector<StreamParameters>& streams,
29     std::vector<uint16_t> handles) {
30   if (groups_.count(group_parameters.id) != 0) {
31     if (groups_.at(group_parameters.id).HasStreams()) {
32       return bluetooth::hci::LeSetCigParametersCompleteBuilder::Create(
33           1, ErrorCode::COMMAND_DISALLOWED, group_parameters.id, {});
34     }
35     groups_.erase(group_parameters.id);
36   }
37 
38   // TODO: Limit groups and return ErrorCode::MEMORY_CAPACITY_EXCEEDED
39   // TODO: Limit connections return ErrorCode::CONNECTION_LIMIT_EXCEEDED
40 
41   std::vector<ConnectedIsochronousStream> created_streams;
42   for (size_t i = 0; i < streams.size(); i++) {
43     streams[i].handle = handles[i];
44     streams[i].group_id = group_parameters.id;
45     created_streams.emplace_back(streams[i]);
46     cis_to_group_.emplace(handles[i], group_parameters.id);
47   }
48 
49   groups_.emplace(std::piecewise_construct,
50                   std::forward_as_tuple(group_parameters.id),
51                   std::forward_as_tuple(group_parameters, created_streams));
52 
53   return bluetooth::hci::LeSetCigParametersCompleteBuilder::Create(
54       1, ErrorCode::SUCCESS, group_parameters.id, handles);
55 }
56 
RemoveCig(uint8_t cig_id)57 bluetooth::hci::ErrorCode IsochronousConnectionHandler::RemoveCig(
58     uint8_t cig_id) {
59   if (groups_.count(cig_id) != 0) {
60     return ErrorCode::UNKNOWN_CONNECTION;
61   }
62   if (groups_.at(cig_id).HasConnectedStream()) {
63     return ErrorCode::COMMAND_DISALLOWED;
64   }
65   groups_.erase(cig_id);
66   auto copy = cis_to_group_;
67   cis_to_group_.clear();
68   for (auto pair : cis_to_group_) {
69     if (pair.second != cig_id) {
70       cis_to_group_.emplace(pair.first, pair.second);
71     }
72   }
73   return ErrorCode::SUCCESS;
74 }
75 
HasHandle(uint16_t handle) const76 bool IsochronousConnectionHandler::HasHandle(uint16_t handle) const {
77   return cis_to_group_.count(handle) != 0;
78 }
79 
GetGroupId(uint16_t handle) const80 uint8_t IsochronousConnectionHandler::GetGroupId(uint16_t handle) const {
81   return cis_to_group_.at(handle);
82 }
83 
GetStreamParameters(uint16_t handle) const84 StreamParameters IsochronousConnectionHandler::GetStreamParameters(
85     uint16_t handle) const {
86   return groups_.at(cis_to_group_.at(handle)).GetStreamParameters(handle);
87 }
88 
GetGroupParameters(uint8_t id) const89 GroupParameters IsochronousConnectionHandler::GetGroupParameters(
90     uint8_t id) const {
91   return groups_.at(id).GetParameters();
92 }
93 
GetStreamIsConnected(uint16_t handle) const94 bool IsochronousConnectionHandler::GetStreamIsConnected(uint16_t handle) const {
95   return groups_.at(cis_to_group_.at(handle)).StreamIsConnected(handle);
96 }
97 
98 }  // namespace rootcanal
99