| /* |
| * Copyright 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <iostream> |
| #include <vector> |
| |
| #include "packet/avrcp/avrcp_packet.h" |
| |
| // These classes are temporary placeholders to easily switch between BT_HDR and |
| // packets. |
| class VectorPacket : public ::bluetooth::Packet { |
| public: |
| using Packet::Packet; // Inherit constructors |
| |
| static std::shared_ptr<VectorPacket> Make() { |
| return std::shared_ptr<VectorPacket>(new VectorPacket()); |
| }; |
| |
| static std::shared_ptr<VectorPacket> Make(std::vector<uint8_t> payload) { |
| auto pkt = VectorPacket::Make(); |
| pkt->packet_start_index_ = 0; |
| pkt->packet_end_index_ = payload.size(); |
| pkt->data_ = std::make_shared<std::vector<uint8_t>>(std::move(payload)); |
| return pkt; |
| }; |
| |
| const std::vector<uint8_t>& GetData() { return *data_; }; |
| |
| virtual std::string ToString() const { |
| std::stringstream ss; |
| ss << "VectorPacket:" << std::endl; |
| ss << " └ Payload ="; |
| for (auto it = begin(); it != end(); it++) { |
| ss << " " << loghex(*it); |
| } |
| ss << std::endl; |
| |
| return ss.str(); |
| }; |
| |
| virtual std::pair<size_t, size_t> GetPayloadIndecies() const override { |
| return std::pair<size_t, size_t>(packet_start_index_, packet_end_index_); |
| } |
| |
| virtual bool IsValid() const override { return true; } |
| }; |
| |
| // TODO (apanicke): When deleting the old AVRCP Stack, remove this class and |
| // instead create a BT_HDR Parsing packet. |
| class AvrcpMessageConverter { |
| public: |
| static std::shared_ptr<::bluetooth::Packet> Parse(tAVRC_MSG* m) { |
| std::vector<uint8_t> data; |
| |
| switch (m->hdr.opcode) { |
| case AVRC_OP_VENDOR: { |
| tAVRC_MSG_VENDOR* msg = (tAVRC_MSG_VENDOR*)m; |
| data.push_back(m->hdr.ctype); |
| data.push_back((m->hdr.subunit_type << 3) | m->hdr.subunit_id); |
| data.push_back(m->hdr.opcode); |
| for (int i = 2; i >= 0; i--) { |
| data.push_back((uint8_t)((msg->company_id >> i * 8) & 0xff)); |
| } |
| for (uint8_t i = 0; i < msg->vendor_len; i++) { |
| data.push_back(msg->p_vendor_data[i]); |
| } |
| } break; |
| case AVRC_OP_PASS_THRU: { |
| tAVRC_MSG_PASS* msg = (tAVRC_MSG_PASS*)m; |
| data.push_back(m->hdr.ctype); |
| data.push_back((m->hdr.subunit_type << 3) | m->hdr.subunit_id); |
| data.push_back(m->hdr.opcode); |
| data.push_back((msg->state << 7) | msg->op_id); |
| data.push_back(0x00); |
| } break; |
| case AVRC_OP_BROWSE: { |
| tAVRC_MSG_BROWSE* msg = (tAVRC_MSG_BROWSE*)m; |
| // The first 3 bytes are header bytes that aren't actually in AVRCP |
| // packets |
| for (int i = 0; i < msg->browse_len; i++) { |
| data.push_back(msg->p_browse_data[i]); |
| } |
| } break; |
| default: |
| LOG(ERROR) << "Unknown opcode for AVRCP message"; |
| break; |
| } |
| |
| return VectorPacket::Make(data); |
| } |
| }; |