1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "EventPacket.h" 12 #include "ServiceBroker.h" 13 #include "Socket.h" 14 #include "settings/Settings.h" 15 #include "settings/SettingsComponent.h" 16 #include "threads/CriticalSection.h" 17 #include "threads/Thread.h" 18 19 #include <list> 20 #include <map> 21 #include <queue> 22 #include <utility> 23 24 namespace EVENTCLIENT 25 { 26 27 #define ES_FLAG_UNICODE 0x80000000 // new 16bit key flag to support real unicode over EventServer 28 29 class CEventAction 30 { 31 public: CEventAction()32 CEventAction() 33 { 34 actionType = 0; 35 } CEventAction(const char * action,unsigned char type)36 CEventAction(const char* action, unsigned char type): 37 actionName(action) 38 { 39 actionType = type; 40 } 41 42 std::string actionName; 43 unsigned char actionType; 44 }; 45 46 class CEventButtonState 47 { 48 public: CEventButtonState()49 CEventButtonState() 50 { 51 m_iKeyCode = 0; 52 m_fAmount = 0.0f; 53 m_bUseAmount = false; 54 m_bRepeat = false; 55 m_bActive = false; 56 m_bAxis = false; 57 m_iControllerNumber = 0; 58 m_iNextRepeat = 0; 59 } 60 CEventButtonState(unsigned int iKeyCode,std::string mapName,std::string buttonName,float fAmount,bool isAxis,bool bRepeat,bool bUseAmount)61 CEventButtonState(unsigned int iKeyCode, 62 std::string mapName, 63 std::string buttonName, 64 float fAmount, 65 bool isAxis, 66 bool bRepeat, 67 bool bUseAmount) 68 : m_buttonName(std::move(buttonName)), m_mapName(std::move(mapName)) 69 { 70 m_iKeyCode = iKeyCode; 71 m_fAmount = fAmount; 72 m_bUseAmount = bUseAmount; 73 m_bRepeat = bRepeat; 74 m_bActive = true; 75 m_bAxis = isAxis; 76 m_iControllerNumber = 0; 77 m_iNextRepeat = 0; 78 Load(); 79 } 80 Reset()81 void Reset() { m_bActive = false; } SetActive()82 void SetActive() { m_bActive = true; } Active()83 bool Active() const { return m_bActive; } Repeat()84 bool Repeat() const { return m_bRepeat; } ControllerNumber()85 int ControllerNumber() const { return m_iControllerNumber; } Axis()86 bool Axis() const { return m_bAxis; } KeyCode()87 unsigned int KeyCode() const { return m_iKeyCode; } Amount()88 float Amount() const { return m_fAmount; } 89 void Load(); JoystickName()90 const std::string& JoystickName() const { return m_joystickName; } CustomControllerName()91 const std::string& CustomControllerName() const { return m_customControllerName; } 92 93 // data 94 unsigned int m_iKeyCode; 95 unsigned short m_iControllerNumber; 96 std::string m_buttonName; 97 std::string m_mapName; 98 std::string m_joystickName; 99 std::string m_customControllerName; 100 float m_fAmount; 101 bool m_bUseAmount; 102 bool m_bRepeat; 103 bool m_bActive; 104 bool m_bAxis; 105 unsigned int m_iNextRepeat; 106 }; 107 108 109 /**********************************************************************/ 110 /* UDP EventClient Class */ 111 /**********************************************************************/ 112 // - clients timeout if they don't receive at least 1 ping in 1 minute 113 // - sequence packets timeout after 5 seconds 114 class CEventClient 115 { 116 public: CEventClient()117 CEventClient() 118 { 119 Initialize(); 120 } 121 CEventClient(SOCKETS::CAddress & addr)122 explicit CEventClient(SOCKETS::CAddress& addr): 123 m_remoteAddr(addr) 124 { 125 Initialize(); 126 } 127 Initialize()128 void Initialize() 129 { 130 m_bGreeted = false; 131 m_iMouseX = 0; 132 m_iMouseY = 0; 133 m_iCurrentSeqLen = 0; 134 m_lastPing = 0; 135 m_lastSeq = 0; 136 m_iRemotePort = 0; 137 m_bMouseMoved = false; 138 m_bSequenceError = false; 139 RefreshSettings(); 140 } 141 Name()142 const std::string& Name() const 143 { 144 return m_deviceName; 145 } 146 RefreshSettings()147 void RefreshSettings() 148 { 149 const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings(); 150 m_iRepeatDelay = settings->GetInt(CSettings::SETTING_SERVICES_ESINITIALDELAY); 151 m_iRepeatSpeed = settings->GetInt(CSettings::SETTING_SERVICES_ESCONTINUOUSDELAY); 152 } 153 Address()154 SOCKETS::CAddress& Address() 155 { 156 return m_remoteAddr; 157 } 158 ~CEventClient()159 virtual ~CEventClient() 160 { 161 FreePacketQueues(); 162 } 163 164 // add packet to queue 165 bool AddPacket(EVENTPACKET::CEventPacket *packet); 166 167 // return true if client received ping with the last 1 minute 168 bool Alive() const; 169 170 // process the packet queue 171 bool ProcessQueue(); 172 173 // process the queued up events (packets) 174 void ProcessEvents(); 175 176 // gets the next action in the action queue 177 bool GetNextAction(CEventAction& action); 178 179 // deallocate all packets in the queues 180 void FreePacketQueues(); 181 182 // return event states 183 unsigned int GetButtonCode(std::string& strMapName, bool& isAxis, float& amount, bool &isJoystick); 184 185 // update mouse position 186 bool GetMousePos(float& x, float& y); 187 188 protected: 189 bool ProcessPacket(EVENTPACKET::CEventPacket *packet); 190 191 // packet handlers 192 virtual bool OnPacketHELO(EVENTPACKET::CEventPacket *packet); 193 virtual bool OnPacketBYE(EVENTPACKET::CEventPacket *packet); 194 virtual bool OnPacketBUTTON(EVENTPACKET::CEventPacket *packet); 195 virtual bool OnPacketMOUSE(EVENTPACKET::CEventPacket *packet); 196 virtual bool OnPacketNOTIFICATION(EVENTPACKET::CEventPacket *packet); 197 virtual bool OnPacketLOG(EVENTPACKET::CEventPacket *packet); 198 virtual bool OnPacketACTION(EVENTPACKET::CEventPacket *packet); 199 bool CheckButtonRepeat(unsigned int &next); 200 201 // returns true if the client has received the HELO packet Greeted()202 bool Greeted() { return m_bGreeted; } 203 204 // reset the timeout counter ResetTimeout()205 void ResetTimeout() 206 { 207 m_lastPing = time(NULL); 208 } 209 210 // helper functions 211 212 // Parses a null terminated string from payload. 213 // After parsing successfully: 214 // 1. payload is incremented to end of string 215 // 2. psize is decremented by length of string 216 // 3. parsedVal contains the parsed string 217 // 4. true is returned 218 bool ParseString(unsigned char* &payload, int &psize, std::string& parsedVal); 219 220 // Parses a single byte (same behavior as ParseString) 221 bool ParseByte(unsigned char* &payload, int &psize, unsigned char& parsedVal); 222 223 // Parse a single 32-bit integer (converts from network order to host order) 224 bool ParseUInt32(unsigned char* &payload, int &psize, unsigned int& parsedVal); 225 226 // Parse a single 16-bit integer (converts from network order to host order) 227 bool ParseUInt16(unsigned char* &payload, int &psize, unsigned short& parsedVal); 228 229 std::string m_deviceName; 230 int m_iCurrentSeqLen; 231 time_t m_lastPing; 232 time_t m_lastSeq; 233 int m_iRemotePort; 234 bool m_bGreeted; 235 unsigned int m_iRepeatDelay; 236 unsigned int m_iRepeatSpeed; 237 unsigned int m_iMouseX; 238 unsigned int m_iMouseY; 239 bool m_bMouseMoved; 240 bool m_bSequenceError; 241 242 SOCKETS::CAddress m_remoteAddr; 243 244 EVENTPACKET::LogoType m_eLogoType; 245 CCriticalSection m_critSection; 246 247 std::map <unsigned int, EVENTPACKET::CEventPacket*> m_seqPackets; 248 std::queue <EVENTPACKET::CEventPacket*> m_readyPackets; 249 250 // button and mouse state 251 std::list<CEventButtonState> m_buttonQueue; 252 std::queue<CEventAction> m_actionQueue; 253 CEventButtonState m_currentButton; 254 }; 255 256 } 257 258