]> git.vomp.tv Git - vompclient.git/blob - inputudp.cc
Windows fixes
[vompclient.git] / inputudp.cc
1 /*
2     Copyright 2006-2020 Chris Tallon
3
4     This file is part of VOMP.
5
6     VOMP is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     VOMP is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <fcntl.h>
21 #ifndef WIN32
22 #include <unistd.h>
23 #endif
24
25 #include "log.h"
26
27 #include "inputudp.h"
28
29 const char* InputUDP::myModName = "InputUDP";
30
31 bool InputUDP::init()
32 {
33   if (initted) return false;
34   initted = true;
35   log = Log::getInstance();
36   log->log("InputUDP", Log::DEBUG, "Starting InputUDP command server");
37
38   if (!udp4.init(2000))
39   {
40     log->log("InputUDP", Log::DEBUG, "UDP4 init error");
41     initted = false;
42     return false;
43   }
44
45 #ifdef WIN32
46   quitPipe = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
47   if (quitPipe == INVALID_SOCKET)
48   {
49     Log::getInstance()->log("InputUDP", Log::ERR, "Win32 socket fail");
50 #else
51   if (pipe2(pfds, O_NONBLOCK) == -1)
52   {
53     Log::getInstance()->log("InputUDP", Log::ERR, "pipe2() fail");
54 #endif
55     udp4.shutdown();
56     initted = false;
57     return false;
58   }
59
60   return true;
61 }
62
63 void InputUDP::shutdown()
64 {
65 #ifdef WIN32
66   CLOSESOCKET(quitPipe);
67 #endif
68
69   udp4.shutdown();
70
71 #ifndef WIN32
72   CLOSESOCKET(pfds[1]);
73   CLOSESOCKET(pfds[0]);
74 #endif
75
76   initted = false;
77 }
78
79 bool InputUDP::start()
80 {
81   threadStartProtect.lock(); // Make sure listenThread is fully initted before start returns
82   listenThread = std::thread( [this]
83   {
84     threadStartProtect.lock();
85     threadStartProtect.unlock();
86     listenLoop();
87   });
88   threadStartProtect.unlock();
89
90   log->log("InputUDP", Log::DEBUG, "InputUDP command server started");
91   return true;
92 }
93
94 void InputUDP::stop()
95 {
96   std::lock_guard<std::mutex> lg(threadStartProtect); // Also use it to protect against starting while stopping
97
98   if (!initted) return;
99
100   if (listenThread.joinable())
101   {
102 #ifdef WIN32
103     Log::getInstance()->log("InputUDP", Log::DEBUG, "Calling CLOSESOCKET on WIN32 quitPipe");
104
105     CLOSESOCKET(quitPipe);
106 #else
107     write(pfds[1], "1", 1); // break the select in listenLoop
108 #endif
109     listenThread.join();
110   }
111 }
112
113 void InputUDP::listenLoop()
114 {
115   int retval;
116   while(1)
117   {
118 #ifdef WIN32
119     retval = udp4.waitforMessage(3, quitPipe);
120 #else
121     retval = udp4.waitforMessage(3, pfds[0]);
122 #endif
123     Log::getInstance()->log("InputUDP", Log::DEBUG, "Back from waitForMessage");
124
125     if (retval == 2)
126     {
127       processRequest(udp4.getData(), udp4.getDataLength());
128     }
129     else if (retval == 3) // quit
130     {
131       Log::getInstance()->log("InputUDP", Log::DEBUG, "quit");
132       break;
133     }
134     else
135     {
136       log->log("InputUDP", Log::CRIT, "Wait for packet error");
137       return;
138     }
139   }
140 }
141
142 void InputUDP::processRequest(const void* data, UINT length)
143 {
144   log->log("InputUDP", Log::DEBUG, "Got request");
145
146   char* temp = new char[length + 1];
147   memcpy(temp, data, length);
148   temp[length] = '\0';
149   UINT command = static_cast<UINT>(atoi(temp));
150   delete[] temp;
151
152   log->log("InputUDP", Log::DEBUG, "Command %i recieved", command);
153   sendInputKey(command);
154 }
155
156 const char* InputUDP::getHardCodedHardwareKeyNamesForVompKey(UCHAR /* vompKey */)
157 {
158   return "";
159 }
160
161 std::string InputUDP::getHardwareKeyName(HWC_TYPE /* hardwareKey */)
162 {
163   std::string retval;
164   return retval;
165 }
166
167
168
169
170
171
172 /*
173
174 //void dump(unsigned char* data, USHORT size);
175 //unsigned char dcc(UCHAR c);
176
177 void dump(unsigned char* data, USHORT size)
178 {
179   printf("Size = %u\n", size);
180
181   USHORT c = 0;
182   while(c < size)
183   {
184     if ((size - c) > 15)
185     {
186       printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
187         data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
188         data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13], data[c+14], data[c+15],
189         dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
190         dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]), dcc(data[c+14]), dcc(data[c+15]));
191       c += 16;
192     }
193     else
194     {
195       switch (size - c)
196       {
197         case 15:
198           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X     %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
199             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
200             data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13], data[c+14],
201             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
202             dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]), dcc(data[c+14]));
203           c += 15;
204           break;
205         case 14:
206           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X        %c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
207             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
208             data[c+8], data[c+9], data[c+10], data[c+11], data[c+12], data[c+13],
209             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
210             dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]), dcc(data[c+13]));
211           c += 14;
212           break;
213         case 13:
214           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X  %02X           %c%c%c%c%c%c%c%c%c%c%c%c%c\n",
215             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
216             data[c+8], data[c+9], data[c+10], data[c+11], data[c+12],
217             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
218             dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]), dcc(data[c+12]));
219           c += 13;
220           break;
221         case 12:
222           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X %02X               %c%c%c%c%c%c%c%c%c%c%c%c\n",
223             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
224             data[c+8], data[c+9], data[c+10], data[c+11],
225             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
226             dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]), dcc(data[c+11]));
227           c += 12;
228           break;
229         case 11:
230           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X %02X                  %c%c%c%c%c%c%c%c%c%c%c\n",
231             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
232             data[c+8], data[c+9], data[c+10],
233             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
234             dcc(data[c+8]), dcc(data[c+9]), dcc(data[c+10]));
235           c += 11;
236           break;
237         case 10:
238           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X %02X                     %c%c%c%c%c%c%c%c%c%c\n",
239             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
240             data[c+8], data[c+9],
241             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
242             dcc(data[c+8]), dcc(data[c+9]));
243           c += 10;
244           break;
245         case 9:
246           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X  %02X                        %c%c%c%c%c%c%c%c%c\n",
247             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
248             data[c+8],
249             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]),
250             dcc(data[c+8]));
251           c += 9;
252           break;
253         case 8:
254           printf(" %02X %02X %02X %02X  %02X %02X %02X %02X                            %c%c%c%c%c%c%c%c\n",
255             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6], data[c+7],
256             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]), dcc(data[c+7]));
257           c += 8;
258           break;
259         case 7:
260           printf(" %02X %02X %02X %02X  %02X %02X %02X                               %c%c%c%c%c%c%c\n",
261             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5], data[c+6],
262             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]), dcc(data[c+6]));
263           c += 7;
264           break;
265         case 6:
266           printf(" %02X %02X %02X %02X  %02X %02X                                  %c%c%c%c%c%c\n",
267             data[c], data[c+1], data[c+2], data[c+3], data[c+4], data[c+5],
268             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]), dcc(data[c+5]));
269           c += 6;
270           break;
271         case 5:
272           printf(" %02X %02X %02X %02X  %02X                                     %c%c%c%c%c\n",
273             data[c], data[c+1], data[c+2], data[c+3], data[c+4],
274             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]), dcc(data[c+4]));
275           c += 5;
276           break;
277         case 4:
278           printf(" %02X %02X %02X %02X                                         %c%c%c%c\n",
279             data[c], data[c+1], data[c+2], data[c+3],
280             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]), dcc(data[c+3]));
281           c += 4;
282           break;
283         case 3:
284           printf(" %02X %02X %02X                                            %c%c%c\n",
285             data[c], data[c+1], data[c+2],
286             dcc(data[c]), dcc(data[c+1]), dcc(data[c+2]));
287           c += 3;
288           break;
289         case 2:
290           printf(" %02X %02X                                               %c%c\n",
291             data[c], data[c+1],
292             dcc(data[c]), dcc(data[c+1]));
293           c += 2;
294           break;
295         case 1:
296           printf(" %02X                                                  %c\n",
297             data[c],
298             dcc(data[c]));
299           c += 1;
300           break;
301       }
302     }
303   }
304 }
305
306 unsigned char dcc(UCHAR c)
307 {
308   if (isspace(c)) return ' ';
309   if (isprint(c)) return c;
310   return '.';
311 }
312 */