* Decode an OpenLASIR frame. * * OpenLASIR uses the same physical layer as NEC but with different address/command structure: * - 8-bit address with inverted complement (error check on address) * - 16-bit command without error check * * The decoder validates the address by checking that the second byte is the bitwise * inverse of the first byte. The full 16-bit command is returned as-is.
| 227 | * @return true if a valid OpenLASIR frame was decoded. |
| 228 | */ |
| 229 | bool IRrecv::decodeOpenLASIR() { |
| 230 | /* |
| 231 | * First check for right data length |
| 232 | * Next check start bit |
| 233 | * Next try the decode |
| 234 | */ |
| 235 | |
| 236 | // Check we have the right amount of data (68). The +4 is for initial gap, start bit mark and space + stop bit mark. |
| 237 | if (!(decodedIRData.rawlen == ((2 * OPENLASIR_BITS) + 4) || (decodedIRData.rawlen == 4))) { |
| 238 | DEBUG_PRINT(F("OpenLASIR: Data length=")); |
| 239 | DEBUG_PRINT(decodedIRData.rawlen); |
| 240 | DEBUG_PRINTLN(F(" is not 68 or 4")); |
| 241 | return false; |
| 242 | } |
| 243 | |
| 244 | // Check header "mark" - this must be done for repeat and data |
| 245 | if (!matchMark(irparams.rawbuf[1], NEC_HEADER_MARK)) { |
| 246 | return false; |
| 247 | } |
| 248 | |
| 249 | #if !defined(DECODE_NEC) // This code is also contained in NEC sources and does also decode LASIR Repeats :-) |
| 250 | // Check for repeat - here we have another header space length |
| 251 | if (decodedIRData.rawlen == 4) { |
| 252 | if (matchSpace(irparams.rawbuf[2], NEC_REPEAT_HEADER_SPACE) && matchMark(irparams.rawbuf[3], NEC_BIT_MARK)) { |
| 253 | decodedIRData.flags = IRDATA_FLAGS_IS_REPEAT | IRDATA_FLAGS_IS_LSB_FIRST; |
| 254 | decodedIRData.address = lastDecodedAddress; |
| 255 | decodedIRData.command = lastDecodedCommand; |
| 256 | decodedIRData.protocol = lastDecodedProtocol; // Allow recognition of repeats of another look alike protocol |
| 257 | return true; |
| 258 | } |
| 259 | return false; |
| 260 | } |
| 261 | #endif |
| 262 | |
| 263 | // Check command header space |
| 264 | if (!matchSpace(irparams.rawbuf[2], NEC_HEADER_SPACE)) { |
| 265 | DEBUG_PRINTLN(F("OpenLASIR: Header space length is wrong")); |
| 266 | return false; |
| 267 | } |
| 268 | |
| 269 | // Decode the pulse distance data using NEC timing |
| 270 | decodePulseDistanceWidthData_P(&NECProtocolConstants, OPENLASIR_BITS); |
| 271 | |
| 272 | // Success - now interpret the 32 raw bits |
| 273 | LongUnion tValue; |
| 274 | tValue.ULong = decodedIRData.decodedRawData; |
| 275 | |
| 276 | // Validate address: second byte must be inverted first byte |
| 277 | if (tValue.UByte.LowByte != (uint8_t)(~tValue.UByte.MidLowByte)) { |
| 278 | // Address validation failed - this is not a valid OpenLASIR frame |
| 279 | DEBUG_PRINTLN(F("OpenLASIR: Address validation failed")); |
| 280 | return false; |
| 281 | } |
| 282 | |
| 283 | /* |
| 284 | * Disambiguation with standard NEC: |
| 285 | * If the command also has a valid inverted pattern (upper 8 bits == ~lower 8 bits), |
| 286 | * then this looks like a standard NEC frame, not OpenLASIR. |
nothing calls this directly
no test coverage detected