Home | History | Annotate | Download | only in src
      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 
     32 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 
     54 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 
     73 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 
     96 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 
    102 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 
    116 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