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 // From what I understand (mostly from reading LIRC config files), NEC
16 // protocol based remotes mostly use a frequency of 38000 units and a
17 // duty cycle of 50%. They'll be set to these defaults here, and overridden
18 // as needed by child classes.
20 PIRProtocol::PIRProtocol(
25 : carrierFrequency(38000),
27 isConstantLength(iclflag),
29 minimumRepetitions(0),
32 qRegisterMetaType<PIRKeyName>("PIRKeyName");
36 SIGNAL(buttonPressed(unsigned int, PIRKeyName)),
38 SLOT(startSendingCommand(unsigned int, PIRKeyName)),
39 Qt::QueuedConnection);
43 SIGNAL(commandFailed(const char *)),
45 SLOT(receivedExternalWarning(const char *)),
46 Qt::QueuedConnection);
50 void PIRProtocol::addKey(
52 unsigned long command,
55 appendToBitSeq(keycodes[key], command, bits);
60 void PIRProtocol::setIndex(
68 void PIRProtocol::setCarrierFrequency(
71 carrierFrequency = freq;
75 void PIRProtocol::setDutyCycle(
82 void PIRProtocol::setMinimumRepetitions(
85 minimumRepetitions = minrep;
89 bool PIRProtocol::isCommandSupported(
92 return (keycodes.find(command) != keycodes.end());
96 void PIRProtocol::appendToBitSeq(
97 CommandSequence &sequence,
101 if (significantBits == 0)
103 // This is bad, but just return silently for now...
107 // For each bit in the char, append a 1 or a 0 into the sequence.
108 // Starting with the largest bit, move forward one bit at a time:
109 unsigned int currentBit = 1 << (significantBits - 1);
113 if (bits & currentBit)
115 sequence.push_back(1);
119 sequence.push_back(0);
122 currentBit = currentBit >> 1;
124 while (currentBit > 0);
128 void PIRProtocol::clearRepeatFlag()
130 QMutexLocker locker(&stopRepeatingMutex);
131 stopRepeatingFlag = false;
135 bool PIRProtocol::checkRepeatFlag()
137 QMutexLocker locker(&stopRepeatingMutex);
138 return stopRepeatingFlag;
142 // Note that the following routine blindly sleeps for the amount of time
143 // specified by the LIRC config file. The extra overhead of processing
144 // each command will mean that repeated commands will overshoot the config
145 // time by some amount. We could improve accuracy by waiting a little less
146 // than the specified time, if we could get a good handle on how long the
147 // overhead is delaying the command...
148 #define PIEROGI_OVERHEAD_HACK 13260
150 void PIRProtocol::sleepUntilRepeat(
155 // If the LIRC config file specifies the flag "CONST_LENGTH", that means
156 // the "gap" value is the exact amount of time to wait between kicking off
157 // each command. If not, then the "gap" needs to be added on to the total
158 // time of the previous command to see how long to sleep.
160 if (isConstantLength)
162 microseconds = (gap - commandDuration) - PIEROGI_OVERHEAD_HACK;
166 microseconds = gap - PIEROGI_OVERHEAD_HACK;
169 // Don't even bother sleeping if there's only a few microseconds:
170 if (microseconds < 1000)
176 sleeptime.tv_sec = 0;
177 sleeptime.tv_nsec = microseconds * 1000;
179 timespec remainingtime;
181 if (nanosleep(&sleeptime, &remainingtime) == -1)
183 std::stringstream ss;
184 ss << "Problem while sleeping.\n";
185 ss << "Trying to sleep for: " << microseconds << "\n";
186 ss << "Nanosleep returned error: " << strerror(errno) << "\n";
187 throw PIRException(ss.str());