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