• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "link_layer_socket_device.h"
18 
19 #include <type_traits>  // for remove_extent_t
20 
21 #include "log.h"                  // for ASSERT, LOG_INFO, LOG_ERROR, LOG_WARN
22 #include "packet/bit_inserter.h"  // for BitInserter
23 #include "packet/iterator.h"      // for Iterator
24 #include "packet/packet_view.h"   // for PacketView, kLittleEndian
25 #include "packet/raw_builder.h"   // for RawBuilder
26 #include "packet/view.h"          // for View
27 #include "phy.h"                  // for Phy, Phy::Type
28 
29 using std::vector;
30 
31 namespace rootcanal {
32 
LinkLayerSocketDevice(std::shared_ptr<AsyncDataChannel> socket_fd,Phy::Type phy_type)33 LinkLayerSocketDevice::LinkLayerSocketDevice(
34     std::shared_ptr<AsyncDataChannel> socket_fd, Phy::Type phy_type)
35     : socket_(socket_fd),
36       phy_type_(phy_type),
37       size_bytes_(std::make_shared<std::vector<uint8_t>>(kSizeBytes)) {}
38 
Tick()39 void LinkLayerSocketDevice::Tick() {
40   if (receiving_size_) {
41     ssize_t bytes_received =
42         socket_->Recv(size_bytes_->data() + offset_, kSizeBytes);
43     if (bytes_received <= 0) {
44       if (errno == EAGAIN || errno == EWOULDBLOCK) {
45         // Nothing available yet.
46         // LOG_DEBUG("Nothing available yet...");
47         return;
48       }
49       LOG_INFO("Closing socket, received: %zd, %s", bytes_received,
50                strerror(errno));
51       Close();
52       return;
53     }
54     if ((size_t)bytes_received < bytes_left_) {
55       bytes_left_ -= bytes_received;
56       offset_ += bytes_received;
57       return;
58     }
59     bluetooth::packet::PacketView<bluetooth::packet::kLittleEndian> size(
60         {bluetooth::packet::View(size_bytes_, 0, kSizeBytes)});
61     bytes_left_ = size.begin().extract<uint32_t>();
62     received_ = std::make_shared<std::vector<uint8_t>>(bytes_left_);
63     offset_ = 0;
64     receiving_size_ = false;
65   }
66   ssize_t bytes_received =
67       socket_->Recv(received_->data() + offset_, bytes_left_);
68   if (bytes_received <= 0) {
69     if (errno == EAGAIN || errno == EWOULDBLOCK) {
70       // Nothing available yet.
71       // LOG_DEBUG("Nothing available yet...");
72       return;
73     }
74     LOG_INFO("Closing socket, received: %zd, %s", bytes_received,
75              strerror(errno));
76     Close();
77     return;
78   }
79   if ((size_t)bytes_received < bytes_left_) {
80     bytes_left_ -= bytes_received;
81     offset_ += bytes_received;
82     return;
83   }
84   bytes_left_ = kSizeBytes;
85   offset_ = 0;
86   receiving_size_ = true;
87   SendLinkLayerPacket(*received_, phy_type_);
88 }
89 
Close()90 void LinkLayerSocketDevice::Close() {
91   if (socket_) {
92     socket_->Close();
93   }
94   Device::Close();
95 }
96 
ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView packet,Phy::Type,int8_t)97 void LinkLayerSocketDevice::ReceiveLinkLayerPacket(
98     model::packets::LinkLayerPacketView packet, Phy::Type /*type*/,
99     int8_t /*rssi*/) {
100   auto size_packet = bluetooth::packet::RawBuilder();
101   size_packet.AddOctets4(packet.size());
102   std::vector<uint8_t> size_bytes;
103   bluetooth::packet::BitInserter bit_inserter(size_bytes);
104   size_packet.Serialize(bit_inserter);
105 
106   if (socket_->Send(size_bytes.data(), size_bytes.size()) == kSizeBytes) {
107     std::vector<uint8_t> payload_bytes{packet.begin(), packet.end()};
108     socket_->Send(payload_bytes.data(), payload_bytes.size());
109   }
110 }
111 
112 }  // namespace rootcanal
113