Change back to real tabbed window, updates keysets
[pierogi] / protocols / pirprotocol.cpp
1 #include "pirprotocol.h"
2
3 #include <QMutex>
4 #include <QMetaType>
5
6 #include <time.h>
7 #include <sstream>
8 #include <errno.h>
9 #include "pirexception.h"
10
11 // A flag for communicating with the main thread:
12 extern bool stopRepeatingFlag;
13 extern QMutex stopRepeatingMutex;
14
15 // Total of all running commands
16 extern bool commandInFlight;
17 extern QMutex commandIFMutex;
18
19 // From what I understand (mostly from reading LIRC config files), NEC
20 // protocol based remotes mostly use a frequency of 38000 units and a
21 // duty cycle of 50%.  They'll be set to these defaults here, and overridden
22 // as needed by child classes.
23
24 PIRProtocol::PIRProtocol(
25   QObject *guiObject,
26   unsigned int index,
27   unsigned int gSpace,
28   bool iclflag)
29   : carrierFrequency(38000),
30     dutyCycle(50),
31     isConstantLength(iclflag),
32     gap(gSpace),
33     minimumRepetitions(0),
34     id(index)
35 {
36   qRegisterMetaType<PIRKeyName>("PIRKeyName");
37
38   QObject::connect(
39     guiObject,
40     SIGNAL(buttonPressed(unsigned int, PIRKeyName)),
41     this,
42     SLOT(startSendingCommand(unsigned int, PIRKeyName)),
43     Qt::QueuedConnection);
44
45   QObject::connect(
46     this,
47     SIGNAL(commandFailed(const char *)),
48     guiObject,
49     SLOT(receivedExternalWarning(const char *)),
50     Qt::QueuedConnection);
51 }
52
53
54 void PIRProtocol::addKey(
55   PIRKeyName key,
56   unsigned long command,
57   unsigned int size)
58 {
59   // First, if key already exists, clear it out:
60   PIRKeyBits *pkb = 0;
61   KeycodeCollection::iterator i = keycodes.find(key);
62   if (i != keycodes.end())
63   {
64     pkb = &(i->second);
65     pkb->firstCode.clear();
66   }
67   else
68   {
69     pkb = &(keycodes[key]);
70   }
71
72   appendToBitSeq(pkb->firstCode, command, size);
73 }
74
75
76 void PIRProtocol::addSIRCKey(
77   PIRKeyName key,
78   unsigned int addressData,
79   unsigned int size,
80   unsigned int commandData)
81 {
82   // First, if key already exists, clear it out:
83   PIRKeyBits *pkb = 0;
84   KeycodeCollection::iterator i = keycodes.find(key);
85   if (i != keycodes.end())
86   {
87     pkb = &(i->second);
88     pkb->firstCode.clear();
89     pkb->secondCode.clear();
90     pkb->thirdCode.clear();
91   }
92   else
93   {
94     pkb = &(keycodes[key]);
95   }
96
97   // First, append the address data:
98   appendToBitSeq(pkb->firstCode, addressData, size);
99
100   // Next, the command data.  The size is always 7 bits:
101   appendToBitSeq(pkb->secondCode, commandData, 7);
102 }
103
104
105 void PIRProtocol::addSIRC20Key(
106   PIRKeyName key,
107   unsigned int secondaryAddressData,
108   unsigned int primaryAddressData,
109   unsigned int commandData)
110 {
111   // First, if key already exists, clear it out:
112   PIRKeyBits *pkb = 0;
113   KeycodeCollection::iterator i = keycodes.find(key);
114   if (i != keycodes.end())
115   {
116     pkb = &(i->second);
117     pkb->firstCode.clear();
118     pkb->secondCode.clear();
119     pkb->thirdCode.clear();
120   }
121   else
122   {
123     pkb = &(keycodes[key]);
124   }
125
126   // First, append the secondary address data:
127   appendToBitSeq(pkb->firstCode, secondaryAddressData, 8);
128
129   // Next, the primary address data:
130   appendToBitSeq(pkb->secondCode, primaryAddressData, 5);
131
132   // Next, the command data.  The size is always 7 bits:
133   appendToBitSeq(pkb->thirdCode, commandData, 7);
134 }
135
136
137 void PIRProtocol::addSharpKey(
138   PIRKeyName key,
139   unsigned int addressData,
140   unsigned int commandData)
141 {
142   // First, if key already exists, clear it out:
143   PIRKeyBits *pkb = 0;
144   KeycodeCollection::iterator i = keycodes.find(key);
145   if (i != keycodes.end())
146   {
147     pkb = &(i->second);
148     pkb->firstCode.clear();
149     pkb->secondCode.clear();
150   }
151   else
152   {
153     pkb = &(keycodes[key]);
154   }
155
156   // Sharp commands are all 5 bit address, 8 bit command:
157   appendToBitSeq(pkb->firstCode, addressData, 5);
158   appendToBitSeq(pkb->secondCode, commandData, 8);
159 }
160
161
162 void PIRProtocol::addNECKey(
163   PIRKeyName key,
164   unsigned int addressData,
165   unsigned int commandData)
166 {
167   PIRKeyBits *pkb = 0;
168   KeycodeCollection::iterator i = keycodes.find(key);
169   if (i != keycodes.end())
170   {
171     pkb = &(i->second);
172     pkb->firstCode.clear();
173     pkb->secondCode.clear();
174     pkb->thirdCode.clear();
175     pkb->fourthCode.clear();
176   }
177   else
178   {
179     pkb = &(keycodes[key]);
180   }
181
182   // NEC commands should always be 8 bits address, 8 bits command:
183   appendToBitSeq(pkb->firstCode, addressData, 8);
184   appendToBitSeq(pkb->secondCode, commandData, 8);
185 }
186
187
188 void PIRProtocol::addPanOldKey(
189   PIRKeyName key,
190   unsigned int addressData,
191   unsigned int commandData)
192 {
193   PIRKeyBits *pkb = 0;
194   KeycodeCollection::iterator i = keycodes.find(key);
195   if (i != keycodes.end())
196   {
197     pkb = &(i->second);
198     pkb->firstCode.clear();
199     pkb->secondCode.clear();
200     pkb->thirdCode.clear();
201     pkb->fourthCode.clear();
202   }
203   else
204   {
205     pkb = &(keycodes[key]);
206   }
207
208   // The "Old Panasonic" commands have 5 bits address, 6 bits command:
209   appendToBitSeq(pkb->firstCode, addressData, 5);
210   appendToBitSeq(pkb->secondCode, commandData, 6);
211 }
212
213
214 // Most Pioneer keys use the NEC key format, but some are pairs of
215 // NEC keys sent together:
216 void PIRProtocol::addPioneerKey(
217   PIRKeyName key,
218   unsigned int firstAddress,
219   unsigned int firstCommand,
220   unsigned int secondAddress,
221   unsigned int secondCommand)
222 {
223   PIRKeyBits *pkb = 0;
224   KeycodeCollection::iterator i = keycodes.find(key);
225   if (i != keycodes.end())
226   {
227     pkb = &(i->second);
228     pkb->firstCode.clear();
229     pkb->secondCode.clear();
230     pkb->thirdCode.clear();
231     pkb->fourthCode.clear();
232   }
233   else
234   {
235     pkb = &(keycodes[key]);
236   }
237
238   // All four codes should be 8 bits in length:
239   appendToBitSeq(pkb->firstCode, firstAddress, 8);
240   appendToBitSeq(pkb->secondCode, firstCommand, 8);
241   appendToBitSeq(pkb->thirdCode, secondAddress, 8);
242   appendToBitSeq(pkb->fourthCode, secondCommand, 8);
243 }
244
245
246 /*
247 void PIRProtocol::addRCAKey(
248   PIRKeyName key,
249   unsigned int addressData,
250   unsigned int commandData)
251 {
252   PIRKeyBits *pkb = 0;
253   KeycodeCollection::iterator i = keycodes.find(key);
254   if (i != keycodes.end())
255   {
256     pkb = &(i->second);
257     pkb->firstcode.clear();
258     pkb->secondCode.clear();
259   }
260   else
261   {
262     pkb = &(keycodes[key]);
263   }
264
265   // Address is 4 bits, command is 8 bits:
266   appendToBitSeq(pkb->firstCode, addressData, 4);
267   appendToBitSeq(pkb->secondCode, commandData, 8);
268 }
269 */
270
271
272 void PIRProtocol::addKaseikyoKey(
273   PIRKeyName key,
274   unsigned int addressData,
275   unsigned int commandData)
276 {
277   PIRKeyBits *pkb = 0;
278   KeycodeCollection::iterator i = keycodes.find(key);
279   if (i != keycodes.end())
280   {
281     pkb = &(i->second);
282     pkb->firstCode.clear();
283     pkb->secondCode.clear();
284   }
285   else
286   {
287     pkb = &(keycodes[key]);
288   }
289
290   appendToBitSeq(pkb->firstCode, addressData, 12);
291   appendToBitSeq(pkb->secondCode, commandData, 8);
292 }
293
294
295 void PIRProtocol::addDishKey(
296   PIRKeyName key,
297   unsigned int firstCommand,
298   unsigned int secondCommand)
299 {
300   PIRKeyBits *pkb = 0;
301   KeycodeCollection::iterator i = keycodes.find(key);
302   if (i != keycodes.end())
303   {
304     pkb = &(i->second);
305     pkb->firstCode.clear();
306     pkb->secondCode.clear();
307   }
308   else
309   {
310     pkb = &(keycodes[key]);
311   }
312
313   appendToBitSeq(pkb->firstCode, firstCommand, 6);
314   appendToBitSeq(pkb->secondCode, secondCommand, 5);
315 }
316
317
318 void PIRProtocol::addXMPKey(
319   PIRKeyName key,
320   unsigned int firstCommand,
321   unsigned int secondCommand)
322 {
323   PIRKeyBits *pkb = 0;
324   KeycodeCollection::iterator i = keycodes.find(key);
325   if (i != keycodes.end())
326   {
327     pkb = &(i->second);
328     pkb->firstCode.clear();
329     pkb->secondCode.clear();
330   }
331   else
332   {
333     pkb = &(keycodes[key]);
334   }
335
336   appendToBitSeq(pkb->firstCode, firstCommand, 8);
337   appendToBitSeq(pkb->secondCode, secondCommand, 8);
338 }
339
340
341 void PIRProtocol::setCarrierFrequency(
342   unsigned int freq)
343 {
344   carrierFrequency = freq;
345 }
346
347
348 void PIRProtocol::setDutyCycle(
349   unsigned int dc)
350 {
351   dutyCycle = dc;
352 }
353
354
355 void PIRProtocol::setMinimumRepetitions(
356   unsigned int minrep)
357 {
358   minimumRepetitions = minrep;
359 }
360
361
362 void PIRProtocol::setPreData(
363   unsigned long data,
364   unsigned int bits)
365 {
366   // If the container is not empty, first clear it out:
367   if (!preData.empty())
368   {
369     preData.clear();
370   }
371
372   appendToBitSeq(preData, data, bits);
373 }
374
375
376 void PIRProtocol::setPostData(
377   unsigned long data,
378   unsigned int bits)
379 {
380   // If the container is not empty, first clear it out:
381   if (!postData.empty())
382   {
383     postData.clear();
384   }
385
386   appendToBitSeq(postData, data, bits);
387 }
388
389
390 bool PIRProtocol::isCommandSupported(
391   PIRKeyName command)
392 {
393   return (keycodes.find(command) != keycodes.end());
394 }
395
396
397 void PIRProtocol::appendToBitSeq(
398   CommandSequence &sequence,
399   unsigned int bits,
400   int size)
401 {
402   if (size == 0)
403   {
404     // This is bad, but just return silently for now...
405     return;
406   }
407
408   // For each bit in the char, append a 1 or a 0 into the sequence.
409   // Starting with the largest bit, move forward one bit at a time:
410   unsigned int currentBit = 1 << (size - 1);
411
412   do
413   {
414     if (bits & currentBit)
415     {
416       sequence.push_back(1);
417     }
418     else
419     {
420       sequence.push_back(0);
421     }
422
423     currentBit = currentBit >> 1;
424   }
425   while (currentBit > 0);
426 }
427
428
429 void PIRProtocol::clearRepeatFlag()
430 {
431   QMutexLocker locker(&stopRepeatingMutex);
432   stopRepeatingFlag = false;
433 }
434
435
436 bool PIRProtocol::checkRepeatFlag()
437 {
438   QMutexLocker locker(&stopRepeatingMutex);
439   return stopRepeatingFlag;
440 }
441
442
443 // Note that the following routine blindly sleeps for the amount of time
444 // specified by the LIRC config file.  The extra overhead of processing
445 // each command will mean that repeated commands will overshoot the config
446 // time by some amount.  We could improve accuracy by waiting a little less
447 // than the specified time, if we could get a good handle on how long the
448 // overhead is delaying the command...
449 #define PIEROGI_OVERHEAD_HACK 13260
450
451 void PIRProtocol::sleepUntilRepeat(
452   int commandDuration)
453 {
454   int microseconds;
455
456   // If the LIRC config file specifies the flag "CONST_LENGTH", that means
457   // the "gap" value is the exact amount of time to wait between kicking off
458   // each command.  If not, then the "gap" needs to be added on to the total
459   // time of the previous command to see how long to sleep.
460
461   if (isConstantLength)
462   {
463     microseconds = (gap - commandDuration) - PIEROGI_OVERHEAD_HACK;
464   }
465   else
466   {
467     microseconds = gap - PIEROGI_OVERHEAD_HACK;
468   }
469
470 /*
471   // Don't even bother sleeping if there's only a few microseconds:
472   if (microseconds < 1000)
473   {
474     return;
475   }
476 */
477   // For now, I'm going to enforce a minimum sleep of 10 ms, so that we
478   // don't get runaway commands:
479   if (microseconds < 10000)
480   {
481     microseconds = 10000;
482   }
483
484   timespec sleeptime;
485   sleeptime.tv_sec = 0;
486   sleeptime.tv_nsec = microseconds * 1000;
487
488   timespec remainingtime;
489
490   if (nanosleep(&sleeptime, &remainingtime) == -1)
491   {
492     std::stringstream ss;
493     ss << "Problem while sleeping.\n";
494     ss << "Trying to sleep for: " << microseconds << "\n";
495     ss << "Nanosleep returned error: " << strerror(errno) << "\n";
496     throw PIRException(ss.str());
497   }
498 }
499
500
501 void PIRProtocol::setGapSize(
502   int gapSize,
503   bool iclFlag)
504 {
505   gap = gapSize;
506   isConstantLength = iclFlag;
507 }