Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ed4f020 authored by Ajay Panicker's avatar Ajay Panicker Committed by android-build-merger
Browse files

Add packet classes needed for AVRCP Absolute Volume

am: 747f36ad

Change-Id: If186451077737dc05095c34f27795c329776a94e
parents 7fab1db3 747f36ad
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ cc_test {
        "tests/avrcp/pass_through_packet_test.cc",
        "tests/avrcp/play_item_packet_test.cc",
        "tests/avrcp/register_notification_packet_test.cc",
        "tests/avrcp/set_absolute_volume_packet_test.cc",
        "tests/avrcp/set_browsed_player_packet_test.cc",
        "tests/avrcp/vendor_packet_test.cc",
        "tests/base/iterator_test.cc",
+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ cc_library_static {
        "pass_through_packet.cc",
        "play_item.cc",
        "register_notification_packet.cc",
        "set_absolute_volume.cc",
        "set_browsed_player.cc",
        "vendor_packet.cc",
    ],
+1 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ enum class CommandPdu : uint8_t {
  GET_ELEMENT_ATTRIBUTES = 0x20,
  GET_PLAY_STATUS = 0x30,
  REGISTER_NOTIFICATION = 0x31,
  SET_ABSOLUTE_VOLUME = 0x50,
  SET_ADDRESSED_PLAYER = 0x60,
  PLAY_ITEM = 0x74,
};
+113 −16
Original line number Diff line number Diff line
@@ -21,6 +21,54 @@
namespace bluetooth {
namespace avrcp {

bool RegisterNotificationResponse::IsInterim() const {
  return GetCType() == CType::INTERIM;
}

Event RegisterNotificationResponse::GetEvent() const {
  auto value = *(begin() + VendorPacket::kMinSize());
  return static_cast<Event>(value);
}

uint8_t RegisterNotificationResponse::GetVolume() const {
  CHECK(GetEvent() == Event::VOLUME_CHANGED);
  auto it = begin() + VendorPacket::kMinSize() + static_cast<size_t>(1);
  return *it;
}

bool RegisterNotificationResponse::IsValid() const {
  if (!VendorPacket::IsValid()) return false;
  if (size() < kMinSize()) return false;
  if (GetCType() != CType::INTERIM && GetCType() != CType::CHANGED)
    return false;

  switch (GetEvent()) {
    case Event::VOLUME_CHANGED:
      return size() == (kMinSize() + 1);
    default:
      // TODO (apanicke): Add the remaining events when implementing AVRCP
      // Controller
      return false;
  }
}

std::string RegisterNotificationResponse::ToString() const {
  std::stringstream ss;
  ss << "RegisterNotificationResponse: " << std::endl;
  ss << "  └ cType = " << GetCType() << std::endl;
  ss << "  └ Subunit Type = " << loghex(GetSubunitType()) << std::endl;
  ss << "  └ Subunit ID = " << loghex(GetSubunitId()) << std::endl;
  ss << "  └ OpCode = " << GetOpcode() << std::endl;
  ss << "  └ Company ID = " << loghex(GetCompanyId()) << std::endl;
  ss << "  └ Command PDU = " << GetCommandPdu() << std::endl;
  ss << "  └ PacketType = " << GetPacketType() << std::endl;
  ss << "  └ Parameter Length = " << loghex(GetParameterLength()) << std::endl;
  ss << "  └ Event Registered = " << GetEvent() << std::endl;
  ss << std::endl;

  return ss.str();
}

std::unique_ptr<RegisterNotificationResponseBuilder>
RegisterNotificationResponseBuilder::MakePlaybackStatusBuilder(
    bool interim, uint8_t play_status) {
@@ -124,22 +172,43 @@ bool RegisterNotificationResponseBuilder::Serialize(
  VendorPacketBuilder::PushHeader(pkt, 1 + data_size);

  AddPayloadOctets1(pkt, static_cast<uint8_t>(event_));
  if (event_ == Event::PLAYBACK_STATUS_CHANGED) {
  switch (event_) {
    case Event::PLAYBACK_STATUS_CHANGED: {
      uint8_t playback_status = data_ & 0xFF;
      AddPayloadOctets1(pkt, playback_status);
  } else if (event_ == Event::TRACK_CHANGED) {
      break;
    }
    case Event::TRACK_CHANGED: {
      AddPayloadOctets8(pkt, base::ByteSwap(data_));
  } else if (event_ == Event::PLAYBACK_POS_CHANGED) {
      break;
    }
    case Event::PLAYBACK_POS_CHANGED: {
      uint32_t playback_pos = data_ & 0xFFFFFFFF;
      AddPayloadOctets4(pkt, base::ByteSwap(playback_pos));
  } else if (event_ == Event::ADDRESSED_PLAYER_CHANGED) {
      break;
    }
    case Event::PLAYER_APPLICATION_SETTING_CHANGED:
      break;  // No additional data
    case Event::NOW_PLAYING_CONTENT_CHANGED:
      break;  // No additional data
    case Event::AVAILABLE_PLAYERS_CHANGED:
      break;  // No additional data
    case Event::ADDRESSED_PLAYER_CHANGED: {
      uint16_t uid_counter = data_ & 0xFFFF;
      uint16_t player_id = (data_ >> 16) & 0xFFFF;
      AddPayloadOctets2(pkt, base::ByteSwap(player_id));
      AddPayloadOctets2(pkt, base::ByteSwap(uid_counter));
  } else if (event_ == Event::UIDS_CHANGED) {
      break;
    }
    case Event::UIDS_CHANGED: {
      uint16_t uid_counter = data_ & 0xFFFF;
      AddPayloadOctets2(pkt, base::ByteSwap(uid_counter));
      break;
    }
    default:
      // TODO (apanicke): Add Volume Changed builder for when we are controller.
      LOG(FATAL) << "Unhandled event for register notification";
      break;
  }

  return true;
@@ -177,5 +246,33 @@ std::string RegisterNotificationRequest::ToString() const {
  return ss.str();
}

std::unique_ptr<RegisterNotificationRequestBuilder>
RegisterNotificationRequestBuilder::MakeBuilder(Event event,
                                                uint32_t interval) {
  std::unique_ptr<RegisterNotificationRequestBuilder> builder(
      new RegisterNotificationRequestBuilder(event, interval));

  return builder;
}

size_t RegisterNotificationRequestBuilder::size() const {
  return RegisterNotificationRequest::kMinSize();
}

bool RegisterNotificationRequestBuilder::Serialize(
    const std::shared_ptr<::bluetooth::Packet>& pkt) {
  ReserveSpace(pkt, size());

  PacketBuilder::PushHeader(pkt);

  VendorPacketBuilder::PushHeader(pkt, size() - VendorPacket::kMinSize());

  AddPayloadOctets1(pkt, static_cast<uint8_t>(event_));

  AddPayloadOctets4(pkt, base::ByteSwap(interval_));

  return true;
}

}  // namespace avrcp
}  // namespace bluetooth
 No newline at end of file
+58 −3
Original line number Diff line number Diff line
@@ -21,17 +21,50 @@
namespace bluetooth {
namespace avrcp {

class RegisterNotificationResponse : public VendorPacket {
 public:
  virtual ~RegisterNotificationResponse() = default;

  /**
   *  Register Notificaiton Request Packet Layout
   *   AvrcpPacket:
   *     CType c_type_;
   *     uint8_t subunit_type_ : 5;
   *     uint8_t subunit_id_ : 3;
   *     Opcode opcode_;
   *   VendorPacket:
   *     uint8_t company_id[3];
   *     uint8_t command_pdu;
   *     uint8_t packet_type;
   *     uint16_t param_length;
   *   RegisterNotificationRequestPacket:
   *     uint8_t event_id;
   *     uint8_t[] data;  // Length changes based on the event_id
   */
  static constexpr size_t kMinSize() { return VendorPacket::kMinSize() + 1; }

  // TODO (apanicke): Add other getters when implementing AVRCP Controller
  bool IsInterim() const;
  Event GetEvent() const;
  uint8_t GetVolume() const;

  virtual bool IsValid() const override;
  virtual std::string ToString() const override;

 protected:
  using VendorPacket::VendorPacket;
};

class RegisterNotificationResponseBuilder : public VendorPacketBuilder {
 public:
  virtual ~RegisterNotificationResponseBuilder() = default;

  // Playback Status Changed Maker
  static std::unique_ptr<RegisterNotificationResponseBuilder>
  MakePlaybackStatusBuilder(bool interim, uint8_t play_status);
  // Track Changed Maker

  static std::unique_ptr<RegisterNotificationResponseBuilder>
  MakeTrackChangedBuilder(bool interim, uint64_t track_uid);
  // Playback Position Changed Maker

  static std::unique_ptr<RegisterNotificationResponseBuilder>
  MakePlaybackPositionBuilder(bool interim, uint32_t playback_pos);

@@ -97,5 +130,27 @@ class RegisterNotificationRequest : public VendorPacket {
  using VendorPacket::VendorPacket;
};

class RegisterNotificationRequestBuilder : public VendorPacketBuilder {
 public:
  virtual ~RegisterNotificationRequestBuilder() = default;

  static std::unique_ptr<RegisterNotificationRequestBuilder> MakeBuilder(
      Event event, uint32_t interval);

  virtual size_t size() const override;
  virtual bool Serialize(
      const std::shared_ptr<::bluetooth::Packet>& pkt) override;

 protected:
  Event event_;
  uint32_t interval_;

  RegisterNotificationRequestBuilder(Event event, uint32_t interval)
      : VendorPacketBuilder(CType::NOTIFY, CommandPdu::REGISTER_NOTIFICATION,
                            PacketType::SINGLE),
        event_(event),
        interval_(interval){};
};

}  // namespace avrcp
}  // namespace bluetooth
 No newline at end of file
Loading