1 #include "pirprotocol.h"
9 #include "pirexception.h"
11 // A flag for communicating with the main thread:
12 extern bool stopRepeatingFlag;
13 extern QMutex stopRepeatingMutex;
15 // Total of all running commands
16 extern bool commandInFlight;
17 extern QMutex commandIFMutex;
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.
24 PIRProtocol::PIRProtocol(
29 : carrierFrequency(38000),
31 isConstantLength(iclflag),
33 minimumRepetitions(0),
36 qRegisterMetaType<PIRKeyName>("PIRKeyName");
40 SIGNAL(buttonPressed(unsigned int, PIRKeyName)),
42 SLOT(startSendingCommand(unsigned int, PIRKeyName)),
43 Qt::QueuedConnection);
47 SIGNAL(commandFailed(const char *)),
49 SLOT(receivedExternalWarning(const char *)),
50 Qt::QueuedConnection);
54 void PIRProtocol::addKey(
56 unsigned long command,
59 appendToBitSeq(keycodes[key], command, bits);
63 void PIRProtocol::setCarrierFrequency(
66 carrierFrequency = freq;
70 void PIRProtocol::setDutyCycle(
77 void PIRProtocol::setMinimumRepetitions(
80 minimumRepetitions = minrep;
84 bool PIRProtocol::isCommandSupported(
87 return (keycodes.find(command) != keycodes.end());
91 void PIRProtocol::appendToBitSeq(
92 CommandSequence &sequence,
96 if (significantBits == 0)
98 // This is bad, but just return silently for now...
102 // For each bit in the char, append a 1 or a 0 into the sequence.
103 // Starting with the largest bit, move forward one bit at a time:
104 unsigned int currentBit = 1 << (significantBits - 1);
108 if (bits & currentBit)
110 sequence.push_back(1);
114 sequence.push_back(0);
117 currentBit = currentBit >> 1;
119 while (currentBit > 0);
123 void PIRProtocol::clearRepeatFlag()
125 QMutexLocker locker(&stopRepeatingMutex);
126 stopRepeatingFlag = false;
130 bool PIRProtocol::checkRepeatFlag()
132 QMutexLocker locker(&stopRepeatingMutex);
133 return stopRepeatingFlag;
137 // Note that the following routine blindly sleeps for the amount of time
138 // specified by the LIRC config file. The extra overhead of processing
139 // each command will mean that repeated commands will overshoot the config
140 // time by some amount. We could improve accuracy by waiting a little less
141 // than the specified time, if we could get a good handle on how long the
142 // overhead is delaying the command...
143 #define PIEROGI_OVERHEAD_HACK 13260
145 void PIRProtocol::sleepUntilRepeat(
150 // If the LIRC config file specifies the flag "CONST_LENGTH", that means
151 // the "gap" value is the exact amount of time to wait between kicking off
152 // each command. If not, then the "gap" needs to be added on to the total
153 // time of the previous command to see how long to sleep.
155 if (isConstantLength)
157 microseconds = (gap - commandDuration) - PIEROGI_OVERHEAD_HACK;
161 microseconds = gap - PIEROGI_OVERHEAD_HACK;
164 // Don't even bother sleeping if there's only a few microseconds:
165 if (microseconds < 1000)
171 sleeptime.tv_sec = 0;
172 sleeptime.tv_nsec = microseconds * 1000;
174 timespec remainingtime;
176 if (nanosleep(&sleeptime, &remainingtime) == -1)
178 std::stringstream ss;
179 ss << "Problem while sleeping.\n";
180 ss << "Trying to sleep for: " << microseconds << "\n";
181 ss << "Nanosleep returned error: " << strerror(errno) << "\n";
182 throw PIRException(ss.str());