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 // First, if key already exists, clear it out:
60 KeycodeCollection::iterator i = keycodes.find(key);
61 if (i != keycodes.end())
66 appendToBitSeq(keycodes[key], command, bits);
70 void PIRProtocol::setCarrierFrequency(
73 carrierFrequency = freq;
77 void PIRProtocol::setDutyCycle(
84 void PIRProtocol::setMinimumRepetitions(
87 minimumRepetitions = minrep;
91 void PIRProtocol::setPreData(
95 // If the container is not empty, first clear it out:
101 appendToBitSeq(preData, data, bits);
105 void PIRProtocol::setPostData(
109 // If the container is not empty, first clear it out:
110 if (!postData.empty())
115 appendToBitSeq(postData, data, bits);
119 bool PIRProtocol::isCommandSupported(
122 return (keycodes.find(command) != keycodes.end());
126 void PIRProtocol::appendToBitSeq(
127 CommandSequence &sequence,
131 if (significantBits == 0)
133 // This is bad, but just return silently for now...
137 // For each bit in the char, append a 1 or a 0 into the sequence.
138 // Starting with the largest bit, move forward one bit at a time:
139 unsigned int currentBit = 1 << (significantBits - 1);
143 if (bits & currentBit)
145 sequence.push_back(1);
149 sequence.push_back(0);
152 currentBit = currentBit >> 1;
154 while (currentBit > 0);
158 void PIRProtocol::clearRepeatFlag()
160 QMutexLocker locker(&stopRepeatingMutex);
161 stopRepeatingFlag = false;
165 bool PIRProtocol::checkRepeatFlag()
167 QMutexLocker locker(&stopRepeatingMutex);
168 return stopRepeatingFlag;
172 // Note that the following routine blindly sleeps for the amount of time
173 // specified by the LIRC config file. The extra overhead of processing
174 // each command will mean that repeated commands will overshoot the config
175 // time by some amount. We could improve accuracy by waiting a little less
176 // than the specified time, if we could get a good handle on how long the
177 // overhead is delaying the command...
178 #define PIEROGI_OVERHEAD_HACK 13260
180 void PIRProtocol::sleepUntilRepeat(
185 // If the LIRC config file specifies the flag "CONST_LENGTH", that means
186 // the "gap" value is the exact amount of time to wait between kicking off
187 // each command. If not, then the "gap" needs to be added on to the total
188 // time of the previous command to see how long to sleep.
190 if (isConstantLength)
192 microseconds = (gap - commandDuration) - PIEROGI_OVERHEAD_HACK;
196 microseconds = gap - PIEROGI_OVERHEAD_HACK;
199 // Don't even bother sleeping if there's only a few microseconds:
200 if (microseconds < 1000)
206 sleeptime.tv_sec = 0;
207 sleeptime.tv_nsec = microseconds * 1000;
209 timespec remainingtime;
211 if (nanosleep(&sleeptime, &remainingtime) == -1)
213 std::stringstream ss;
214 ss << "Problem while sleeping.\n";
215 ss << "Trying to sleep for: " << microseconds << "\n";
216 ss << "Nanosleep returned error: " << strerror(errno) << "\n";
217 throw PIRException(ss.str());