/* * Copyright (c) 2018-2020 Atmosphère-NX * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #pragma once #include #include "htclow_ctrl_settings_holder.hpp" #include "htclow_ctrl_send_buffer.hpp" #include "htclow_ctrl_state.hpp" namespace ams::htclow { namespace ctrl { class HtcctrlPacketFactory; class HtcctrlStateMachine; } namespace mux { class Mux; } } namespace ams::htclow::ctrl { class HtcctrlService { private: SettingsHolder m_settings_holder; char m_beacon_response[0x1000]; char m_information_body[0x1000]; HtcctrlPacketFactory *m_packet_factory; HtcctrlStateMachine *m_state_machine; mux::Mux *m_mux; os::Event m_event; HtcctrlSendBuffer m_send_buffer; os::SdkMutex m_mutex; os::SdkConditionVariable m_condvar; char m_service_channels_packet[0x1000]; s16 m_version; private: const char *GetConnectionType(impl::DriverType driver_type) const; void UpdateBeaconResponse(const char *connection); void UpdateInformationBody(const char *status); void SendInformation(); Result ProcessReceiveConnectPacket(); Result ProcessReceiveReadyPacket(const void *body, size_t body_size); Result ProcessReceiveSuspendPacket(); Result ProcessReceiveResumePacket(); Result ProcessReceiveDisconnectPacket(); Result ProcessReceiveBeaconQueryPacket(); Result ProcessReceiveUnexpectedPacket(); void ProcessSendConnectPacket(); void ProcessSendReadyPacket(); void ProcessSendSuspendPacket(); void ProcessSendResumePacket(); void ProcessSendDisconnectPacket(); void UpdateServiceChannels(const void *body, size_t body_size); void PrintServiceChannels(char *dst, size_t dst_size); void TryReadyInternal(); void DisconnectInternal(); Result SetState(HtcctrlState state); void ReflectState(); public: HtcctrlService(HtcctrlPacketFactory *pf, HtcctrlStateMachine *sm, mux::Mux *mux); 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); void TryReady(); void Disconnect(); void Resume(); void Suspend(); void NotifyAwake(); void NotifyAsleep(); Result NotifyDriverConnected(); Result NotifyDriverDisconnected(); }; }