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 "os/log.h"
20
21 #include "hci/address.h"
22
23 using std::shared_ptr;
24
25 namespace test_vendor_lib {
26
27 using bluetooth::hci::ErrorCode;
28
29 std::unique_ptr<bluetooth::hci::LeSetCigParametersCompleteBuilder>
SetCigParameters(GroupParameters group_parameters,std::vector<StreamParameters> & streams,std::vector<uint16_t> handles)30 IsochronousConnectionHandler::SetCigParameters(
31 GroupParameters group_parameters, std::vector<StreamParameters>& streams,
32 std::vector<uint16_t> handles) {
33 if (groups_.count(group_parameters.id) != 0) {
34 if (groups_.at(group_parameters.id).HasStreams()) {
35 return bluetooth::hci::LeSetCigParametersCompleteBuilder::Create(
36 1, ErrorCode::COMMAND_DISALLOWED, group_parameters.id, {});
37 }
38 groups_.erase(group_parameters.id);
39 }
40
41 // TODO: Limit groups and return ErrorCode::MEMORY_CAPACITY_EXCEEDED
42 // TODO: Limit connections return ErrorCode::CONNECTION_LIMIT_EXCEEDED
43
44 std::vector<ConnectedIsochronousStream> created_streams;
45 for (size_t i = 0; i < streams.size(); i++) {
46 streams[i].handle = handles[i];
47 streams[i].group_id = group_parameters.id;
48 created_streams.emplace_back(streams[i]);
49 cis_to_group_.emplace(handles[i], group_parameters.id);
50 }
51
52 groups_.emplace(std::piecewise_construct,
53 std::forward_as_tuple(group_parameters.id),
54 std::forward_as_tuple(group_parameters, created_streams));
55
56 return bluetooth::hci::LeSetCigParametersCompleteBuilder::Create(
57 1, ErrorCode::SUCCESS, group_parameters.id, handles);
58 }
59
RemoveCig(uint8_t cig_id)60 bluetooth::hci::ErrorCode IsochronousConnectionHandler::RemoveCig(
61 uint8_t cig_id) {
62 if (groups_.count(cig_id) != 0) {
63 return ErrorCode::UNKNOWN_CONNECTION;
64 }
65 if (groups_.at(cig_id).HasConnectedStream()) {
66 return ErrorCode::COMMAND_DISALLOWED;
67 }
68 groups_.erase(cig_id);
69 auto copy = cis_to_group_;
70 cis_to_group_.clear();
71 for (auto pair : cis_to_group_) {
72 if (pair.second != cig_id) {
73 cis_to_group_.emplace(pair.first, pair.second);
74 }
75 }
76 return ErrorCode::SUCCESS;
77 }
78
HasHandle(uint16_t handle) const79 bool IsochronousConnectionHandler::HasHandle(uint16_t handle) const {
80 return cis_to_group_.count(handle) != 0;
81 }
82
GetGroupId(uint16_t handle) const83 uint8_t IsochronousConnectionHandler::GetGroupId(uint16_t handle) const {
84 return cis_to_group_.at(handle);
85 }
86
GetStreamParameters(uint16_t handle) const87 StreamParameters IsochronousConnectionHandler::GetStreamParameters(
88 uint16_t handle) const {
89 return groups_.at(cis_to_group_.at(handle)).GetStreamParameters(handle);
90 }
91
GetGroupParameters(uint8_t id) const92 GroupParameters IsochronousConnectionHandler::GetGroupParameters(
93 uint8_t id) const {
94 return groups_.at(id).GetParameters();
95 }
96
GetStreamIsConnected(uint16_t handle) const97 bool IsochronousConnectionHandler::GetStreamIsConnected(uint16_t handle) const {
98 return groups_.at(cis_to_group_.at(handle)).StreamIsConnected(handle);
99 }
100
101 } // namespace test_vendor_lib
102