1 /*
2 * Copyright 2018 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 "phy_layer_factory.h"
18
19 #include <sstream>
20
21 namespace rootcanal {
22
PhyLayerFactory(Phy::Type phy_type,uint32_t factory_id)23 PhyLayerFactory::PhyLayerFactory(Phy::Type phy_type, uint32_t factory_id)
24 : phy_type_(phy_type), factory_id_(factory_id) {}
25
GetType()26 Phy::Type PhyLayerFactory::GetType() { return phy_type_; }
27
GetFactoryId()28 uint32_t PhyLayerFactory::GetFactoryId() { return factory_id_; }
29
GetPhyLayer(const std::function<void (model::packets::LinkLayerPacketView)> & device_receive,uint32_t device_id)30 std::shared_ptr<PhyLayer> PhyLayerFactory::GetPhyLayer(
31 const std::function<void(model::packets::LinkLayerPacketView)>&
32 device_receive,
33 uint32_t device_id) {
34 std::shared_ptr<PhyLayer> new_phy = std::make_shared<PhyLayerImpl>(
35 phy_type_, next_id_++, device_receive, device_id, this);
36 phy_layers_.push_back(new_phy);
37 return new_phy;
38 }
39
UnregisterPhyLayer(uint32_t id)40 void PhyLayerFactory::UnregisterPhyLayer(uint32_t id) {
41 for (auto phy : phy_layers_) {
42 if (phy->GetId() == id) {
43 phy_layers_.remove(phy);
44 return;
45 }
46 }
47 }
48
UnregisterAllPhyLayers()49 void PhyLayerFactory::UnregisterAllPhyLayers() {
50 while (!phy_layers_.empty()) {
51 if (phy_layers_.begin() != phy_layers_.end()) {
52 auto id = (*phy_layers_.begin())->GetId();
53 UnregisterPhyLayer(id);
54 }
55 }
56 }
57
Send(const std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet,uint32_t id,uint32_t device_id)58 void PhyLayerFactory::Send(
59 const std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet,
60 uint32_t id, [[maybe_unused]] uint32_t device_id) {
61 // Convert from a Builder to a View
62 auto bytes = std::make_shared<std::vector<uint8_t>>();
63 bluetooth::packet::BitInserter i(*bytes);
64 bytes->reserve(packet->size());
65 packet->Serialize(i);
66 auto packet_view =
67 bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian>(bytes);
68 auto link_layer_packet_view =
69 model::packets::LinkLayerPacketView::Create(packet_view);
70 ASSERT(link_layer_packet_view.IsValid());
71
72 Send(link_layer_packet_view, id, device_id);
73 }
74
Send(model::packets::LinkLayerPacketView packet,uint32_t id,uint32_t device_id)75 void PhyLayerFactory::Send(model::packets::LinkLayerPacketView packet,
76 uint32_t id, [[maybe_unused]] uint32_t device_id) {
77 for (const auto& phy : phy_layers_) {
78 if (id != phy->GetId()) {
79 phy->Receive(packet);
80 }
81 }
82 }
83
TimerTick()84 void PhyLayerFactory::TimerTick() {
85 for (auto& phy : phy_layers_) {
86 phy->TimerTick();
87 }
88 }
89
ToString() const90 std::string PhyLayerFactory::ToString() const {
91 std::stringstream factory;
92 switch (phy_type_) {
93 case Phy::Type::LOW_ENERGY:
94 factory << "LOW_ENERGY: ";
95 break;
96 case Phy::Type::BR_EDR:
97 factory << "BR_EDR: ";
98 break;
99 default:
100 factory << "Unknown: ";
101 }
102 for (auto& phy : phy_layers_) {
103 factory << phy->GetDeviceId();
104 factory << ",";
105 }
106
107 return factory.str();
108 }
109
PhyLayerImpl(Phy::Type phy_type,uint32_t id,const std::function<void (model::packets::LinkLayerPacketView)> & device_receive,uint32_t device_id,PhyLayerFactory * factory)110 PhyLayerImpl::PhyLayerImpl(
111 Phy::Type phy_type, uint32_t id,
112 const std::function<void(model::packets::LinkLayerPacketView)>&
113 device_receive,
114 uint32_t device_id, PhyLayerFactory* factory)
115 : PhyLayer(phy_type, id, device_receive, device_id), factory_(factory) {}
116
~PhyLayerImpl()117 PhyLayerImpl::~PhyLayerImpl() {}
118
Send(const std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet)119 void PhyLayerImpl::Send(
120 const std::shared_ptr<model::packets::LinkLayerPacketBuilder> packet) {
121 factory_->Send(packet, GetId(), GetDeviceId());
122 }
123
Send(model::packets::LinkLayerPacketView packet)124 void PhyLayerImpl::Send(model::packets::LinkLayerPacketView packet) {
125 factory_->Send(packet, GetId(), GetDeviceId());
126 }
127
Unregister()128 void PhyLayerImpl::Unregister() { factory_->UnregisterPhyLayer(GetId()); }
129
IsFactoryId(uint32_t id)130 bool PhyLayerImpl::IsFactoryId(uint32_t id) {
131 return factory_->GetFactoryId() == id;
132 }
133
Receive(model::packets::LinkLayerPacketView packet)134 void PhyLayerImpl::Receive(model::packets::LinkLayerPacketView packet) {
135 transmit_to_device_(packet);
136 }
137
TimerTick()138 void PhyLayerImpl::TimerTick() {}
139
140 } // namespace rootcanal
141