1 //
2 // Copyright 2015 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 #define LOG_TAG "packet_stream"
18
19 #include "packet_stream.h"
20
21 #include <base/logging.h>
22
23 #include <errno.h>
24 #include <unistd.h>
25
26 #include "osi/include/log.h"
27
28 using std::vector;
29
30 namespace test_vendor_lib {
31
ReceiveCommand(int fd) const32 std::unique_ptr<CommandPacket> PacketStream::ReceiveCommand(int fd) const {
33 vector<uint8_t> header;
34 vector<uint8_t> params_size;
35 vector<uint8_t> payload;
36
37 if (!ReceiveAll(header, CommandPacket::kCommandHeaderSize, fd)) {
38 LOG_ERROR(LOG_TAG, "Error: receiving command header.");
39 return std::unique_ptr<CommandPacket>(nullptr);
40 }
41
42 if (!ReceiveAll(params_size, 1, fd)) {
43 LOG_ERROR(LOG_TAG, "Error: receiving params size.");
44 return std::unique_ptr<CommandPacket>(nullptr);
45 }
46
47 if (!ReceiveAll(payload, params_size[0], fd)) {
48 LOG_ERROR(LOG_TAG, "Error: receiving command payload.");
49 return std::unique_ptr<CommandPacket>(nullptr);
50 }
51 return std::unique_ptr<CommandPacket>(new CommandPacket(header, payload));
52 }
53
ReceivePacketType(int fd) const54 serial_data_type_t PacketStream::ReceivePacketType(int fd) const {
55 vector<uint8_t> raw_type_octet;
56
57 if (!ReceiveAll(raw_type_octet, 1, fd)) {
58 // TODO(dennischeng): Proper error handling.
59 LOG_ERROR(LOG_TAG, "Error: Could not receive packet type.");
60 }
61
62 // Check that the type octet received is in the valid range, i.e. the packet
63 // must be a command or data packet.
64 const serial_data_type_t type =
65 static_cast<serial_data_type_t>(raw_type_octet[0]);
66 if (!ValidateTypeOctet(type)) {
67 // TODO(dennischeng): Proper error handling.
68 LOG_ERROR(LOG_TAG, "Error: Received invalid packet type.");
69 }
70 return type;
71 }
72
SendEvent(std::unique_ptr<EventPacket> event,int fd) const73 bool PacketStream::SendEvent(std::unique_ptr<EventPacket> event, int fd) const {
74 if (event->GetPayload()[0] != event->GetPayloadSize() - 1)
75 LOG_WARN(LOG_TAG, "Malformed event: 0x%04X, payload size %zu, reported %u",
76 event->GetEventCode(), event->GetPacketSize(),
77 event->GetPayload()[0]);
78
79 if (!SendAll({static_cast<uint8_t>(event->GetType())}, 1, fd)) {
80 LOG_ERROR(LOG_TAG, "Error: Could not send event type.");
81 return false;
82 }
83
84 if (!SendAll(event->GetHeader(), event->GetHeaderSize(), fd)) {
85 LOG_ERROR(LOG_TAG, "Error: Could not send event header.");
86 return false;
87 }
88
89 if (!SendAll(event->GetPayload(), event->GetPayloadSize(), fd)) {
90 LOG_ERROR(LOG_TAG, "Error: Could not send event payload.");
91 return false;
92 }
93 return true;
94 }
95
ValidateTypeOctet(serial_data_type_t type) const96 bool PacketStream::ValidateTypeOctet(serial_data_type_t type) const {
97 // The only types of packets that should be received from the HCI are command
98 // packets and data packets.
99 return (type >= DATA_TYPE_COMMAND) && (type <= DATA_TYPE_SCO);
100 }
101
ReceiveAll(vector<uint8_t> & destination,size_t num_octets_to_receive,int fd) const102 bool PacketStream::ReceiveAll(vector<uint8_t>& destination,
103 size_t num_octets_to_receive, int fd) const {
104 destination.resize(num_octets_to_receive);
105 size_t octets_remaining = num_octets_to_receive;
106 while (octets_remaining > 0) {
107 const int num_octets_received =
108 read(fd, &destination[num_octets_to_receive - octets_remaining],
109 octets_remaining);
110 if (num_octets_received < 0) return false;
111 octets_remaining -= num_octets_received;
112 }
113 return true;
114 }
115
SendAll(const vector<uint8_t> & source,size_t num_octets_to_send,int fd) const116 bool PacketStream::SendAll(const vector<uint8_t>& source,
117 size_t num_octets_to_send, int fd) const {
118 CHECK(source.size() >= num_octets_to_send);
119 size_t octets_remaining = num_octets_to_send;
120 while (octets_remaining > 0) {
121 const int num_octets_sent = write(
122 fd, &source[num_octets_to_send - octets_remaining], octets_remaining);
123 if (num_octets_sent < 0) return false;
124 octets_remaining -= num_octets_sent;
125 }
126 return true;
127 }
128
129 } // namespace test_vendor_lib
130