htc: send logic for HtcctrlService, bugfixes (thanks @misson20000)
This commit is contained in:
@@ -61,14 +61,14 @@ namespace ams::htclow::ctrl {
|
||||
std::unique_ptr<HtcctrlPacket, HtcctrlPacketDeleter> HtcctrlPacketFactory::MakeResumePacket() {
|
||||
auto packet = this->MakeSendPacketCommon(0);
|
||||
if (packet && packet->IsAllocationSucceeded()) {
|
||||
packet->GetHeader()->packet_type = HtcctrlPacketType_SuspendFromTarget;
|
||||
packet->GetHeader()->packet_type = HtcctrlPacketType_ResumeFromTarget;
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
std::unique_ptr<HtcctrlPacket, HtcctrlPacketDeleter> HtcctrlPacketFactory::MakeReadyPacket(const void *body, int body_size) {
|
||||
auto packet = this->MakeSendPacketCommon(0);
|
||||
auto packet = this->MakeSendPacketCommon(body_size);
|
||||
if (packet && packet->IsAllocationSucceeded()) {
|
||||
packet->GetHeader()->packet_type = HtcctrlPacketType_ReadyFromTarget;
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace ams::htclow::ctrl {
|
||||
}
|
||||
|
||||
std::unique_ptr<HtcctrlPacket, HtcctrlPacketDeleter> HtcctrlPacketFactory::MakeInformationPacket(const void *body, int body_size) {
|
||||
auto packet = this->MakeSendPacketCommon(0);
|
||||
auto packet = this->MakeSendPacketCommon(body_size);
|
||||
if (packet && packet->IsAllocationSucceeded()) {
|
||||
packet->GetHeader()->packet_type = HtcctrlPacketType_InformationFromTarget;
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace ams::htclow::ctrl {
|
||||
}
|
||||
|
||||
std::unique_ptr<HtcctrlPacket, HtcctrlPacketDeleter> HtcctrlPacketFactory::MakeConnectPacket(const void *body, int body_size) {
|
||||
auto packet = this->MakeSendPacketCommon(0);
|
||||
auto packet = this->MakeSendPacketCommon(body_size);
|
||||
if (packet && packet->IsAllocationSucceeded()) {
|
||||
packet->GetHeader()->packet_type = HtcctrlPacketType_ConnectFromTarget;
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace ams::htclow::ctrl {
|
||||
}
|
||||
|
||||
std::unique_ptr<HtcctrlPacket, HtcctrlPacketDeleter> HtcctrlPacketFactory::MakeBeaconResponsePacket(const void *body, int body_size) {
|
||||
auto packet = this->MakeSendPacketCommon(0);
|
||||
auto packet = this->MakeSendPacketCommon(body_size);
|
||||
if (packet && packet->IsAllocationSucceeded()) {
|
||||
packet->GetHeader()->packet_type = HtcctrlPacketType_BeaconResponse;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "htclow_ctrl_send_buffer.hpp"
|
||||
#include "htclow_ctrl_packet_factory.hpp"
|
||||
|
||||
namespace ams::htclow::ctrl {
|
||||
|
||||
@@ -30,6 +31,7 @@ namespace ams::htclow::ctrl {
|
||||
case HtcctrlPacketType_ResumeFromTarget:
|
||||
case HtcctrlPacketType_BeaconResponse:
|
||||
case HtcctrlPacketType_InformationFromTarget:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -51,4 +53,50 @@ namespace ams::htclow::ctrl {
|
||||
}
|
||||
}
|
||||
|
||||
void HtcctrlSendBuffer::RemovePacket(const HtcctrlPacketHeader &header) {
|
||||
/* Get the packet type. */
|
||||
const auto packet_type = header.packet_type;
|
||||
|
||||
/* Remove the front from the appropriate list. */
|
||||
HtcctrlPacket *packet;
|
||||
if (this->IsPriorPacket(packet_type)) {
|
||||
packet = std::addressof(m_prior_packet_list.front());
|
||||
m_prior_packet_list.pop_front();
|
||||
} else {
|
||||
AMS_ABORT_UNLESS(this->IsPosteriorPacket(packet_type));
|
||||
packet = std::addressof(m_posterior_packet_list.front());
|
||||
m_posterior_packet_list.pop_front();
|
||||
}
|
||||
|
||||
/* Delete the packet. */
|
||||
m_packet_factory->Delete(packet);
|
||||
}
|
||||
|
||||
bool HtcctrlSendBuffer::QueryNextPacket(HtcctrlPacketHeader *header, HtcctrlPacketBody *body, int *out_body_size) {
|
||||
if (!m_prior_packet_list.empty()) {
|
||||
this->CopyPacket(header, body, out_body_size, m_prior_packet_list.front());
|
||||
return true;
|
||||
} else if (!m_posterior_packet_list.empty()) {
|
||||
this->CopyPacket(header, body, out_body_size, m_posterior_packet_list.front());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void HtcctrlSendBuffer::CopyPacket(HtcctrlPacketHeader *header, HtcctrlPacketBody *body, int *out_body_size, const HtcctrlPacket &packet) {
|
||||
/* Get the body size. */
|
||||
const int body_size = packet.GetBodySize();
|
||||
AMS_ASSERT(0 <= body_size && body_size <= static_cast<int>(sizeof(*body)));
|
||||
|
||||
/* Copy the header. */
|
||||
std::memcpy(header, packet.GetHeader(), sizeof(*header));
|
||||
|
||||
/* Copy the body. */
|
||||
std::memcpy(body, packet.GetBody(), body_size);
|
||||
|
||||
/* Set the output body size. */
|
||||
*out_body_size = body_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,10 +31,15 @@ namespace ams::htclow::ctrl {
|
||||
private:
|
||||
bool IsPriorPacket(HtcctrlPacketType packet_type) const;
|
||||
bool IsPosteriorPacket(HtcctrlPacketType packet_type) const;
|
||||
|
||||
void CopyPacket(HtcctrlPacketHeader *header, HtcctrlPacketBody *body, int *out_body_size, const HtcctrlPacket &packet);
|
||||
public:
|
||||
HtcctrlSendBuffer(HtcctrlPacketFactory *pf) : m_packet_factory(pf), m_prior_packet_list(), m_posterior_packet_list() { /* ... */ }
|
||||
|
||||
void AddPacket(std::unique_ptr<HtcctrlPacket, HtcctrlPacketDeleter> ptr);
|
||||
void RemovePacket(const HtcctrlPacketHeader &header);
|
||||
|
||||
bool QueryNextPacket(HtcctrlPacketHeader *header, HtcctrlPacketBody *body, int *out_body_size);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -224,6 +224,41 @@ namespace ams::htclow::ctrl {
|
||||
return htclow::ResultHtcctrlReceiveUnexpectedPacket();
|
||||
}
|
||||
|
||||
void HtcctrlService::ProcessSendConnectPacket() {
|
||||
/* Set our state. */
|
||||
const Result result = this->SetState(HtcctrlState_Connected);
|
||||
R_ASSERT(result);
|
||||
}
|
||||
|
||||
void HtcctrlService::ProcessSendReadyPacket() {
|
||||
/* Set our state. */
|
||||
if (m_state_machine->GetHtcctrlState() == HtcctrlState_SentReadyFromHost) {
|
||||
const Result result = this->SetState(HtcctrlState_Ready);
|
||||
R_ASSERT(result);
|
||||
}
|
||||
|
||||
/* Update channel states. */
|
||||
m_mux->UpdateChannelState();
|
||||
}
|
||||
|
||||
void HtcctrlService::ProcessSendSuspendPacket() {
|
||||
/* Set our state. */
|
||||
const Result result = this->SetState(HtcctrlState_SentSuspendFromTarget);
|
||||
R_ASSERT(result);
|
||||
}
|
||||
|
||||
void HtcctrlService::ProcessSendResumePacket() {
|
||||
/* Set our state. */
|
||||
const Result result = this->SetState(HtcctrlState_SentResumeFromTarget);
|
||||
R_ASSERT(result);
|
||||
}
|
||||
|
||||
void HtcctrlService::ProcessSendDisconnectPacket() {
|
||||
/* Set our state. */
|
||||
const Result result = this->SetState(HtcctrlState_Disconnected);
|
||||
R_ASSERT(result);
|
||||
}
|
||||
|
||||
void HtcctrlService::UpdateServiceChannels(const void *body, size_t body_size) {
|
||||
/* Copy the packet body to our member. */
|
||||
std::memcpy(m_service_channels_packet, body, body_size);
|
||||
@@ -259,6 +294,45 @@ namespace ams::htclow::ctrl {
|
||||
}
|
||||
}
|
||||
|
||||
bool HtcctrlService::QuerySendPacket(HtcctrlPacketHeader *header, HtcctrlPacketBody *body, int *out_body_size) {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
return m_send_buffer.QueryNextPacket(header, body, out_body_size);
|
||||
}
|
||||
|
||||
void HtcctrlService::RemovePacket(const HtcctrlPacketHeader &header) {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
/* Remove the packet from our buffer. */
|
||||
m_send_buffer.RemovePacket(header);
|
||||
|
||||
/* Switch on the packet type. */
|
||||
switch (header.packet_type) {
|
||||
case HtcctrlPacketType_ConnectFromTarget:
|
||||
this->ProcessSendConnectPacket();
|
||||
break;
|
||||
case HtcctrlPacketType_ReadyFromTarget:
|
||||
this->ProcessSendReadyPacket();
|
||||
break;
|
||||
case HtcctrlPacketType_SuspendFromTarget:
|
||||
this->ProcessSendSuspendPacket();
|
||||
break;
|
||||
case HtcctrlPacketType_ResumeFromTarget:
|
||||
this->ProcessSendResumePacket();
|
||||
break;
|
||||
case HtcctrlPacketType_DisconnectFromTarget:
|
||||
this->ProcessSendDisconnectPacket();
|
||||
break;
|
||||
case HtcctrlPacketType_BeaconResponse:
|
||||
case HtcctrlPacketType_InformationFromTarget:
|
||||
break;
|
||||
default:
|
||||
AMS_ABORT("Send unsupported packet 0x%04x\n", static_cast<u32>(header.packet_type));
|
||||
}
|
||||
}
|
||||
|
||||
Result HtcctrlService::NotifyDriverConnected() {
|
||||
/* Lock ourselves. */
|
||||
std::scoped_lock lk(m_mutex);
|
||||
|
||||
@@ -65,6 +65,12 @@ namespace ams::htclow::ctrl {
|
||||
Result ProcessReceiveBeaconQueryPacket();
|
||||
Result ProcessReceiveUnexpectedPacket();
|
||||
|
||||
void ProcessSendConnectPacket();
|
||||
void ProcessSendReadyPacket();
|
||||
void ProcessSendSuspendPacket();
|
||||
void ProcessSendResumePacket();
|
||||
void ProcessSendDisconnectPacket();
|
||||
|
||||
void UpdateServiceChannels(const void *body, size_t body_size);
|
||||
void TryReadyInternal();
|
||||
|
||||
@@ -77,9 +83,14 @@ namespace ams::htclow::ctrl {
|
||||
|
||||
void SetDriverType(impl::DriverType driver_type);
|
||||
|
||||
os::EventType *GetSendPacketEvent() { return m_event.GetBase(); }
|
||||
|
||||
Result CheckReceivedHeader(const HtcctrlPacketHeader &header) const;
|
||||
Result ProcessReceivePacket(const HtcctrlPacketHeader &header, const void *body, size_t body_size);
|
||||
|
||||
bool QuerySendPacket(HtcctrlPacketHeader *header, HtcctrlPacketBody *body, int *out_body_size);
|
||||
void RemovePacket(const HtcctrlPacketHeader &header);
|
||||
|
||||
Result NotifyDriverConnected();
|
||||
Result NotifyDriverDisconnected();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user