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