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