#include "PacketTypes.h" namespace PacketTypes { uint8_t minimumPacketSize(uint8_t msgType) { switch (msgType) { case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: case IR_MSG_BACK_TO: case IR_MSG_REQUEST: return uint8_t(msgBytes + addrBytes + addrBytes + crcBytes); case IR_MSG_BACK: return uint8_t(msgBytes + addrBytes + crcBytes); case IR_MSG_ACCEPT: return uint8_t(msgBytes + addrBytes + 1U + crcBytes); default: return 0; } } bool isTypedPacketSizeValid(uint8_t msgType, uint8_t packSize) { const uint8_t minimum = minimumPacketSize(msgType); return minimum != 0 && packSize >= minimum; } bool BasePack::checkAddress() { return true; } bool BasePack::set(IR_FOX::PackInfo *packInfo, uint16_t id, bool requireTypedSize) { isAvailable = false; isRawAvailable = false; this->packInfo = packInfo; this->id = id; if (packInfo == nullptr || packInfo->buffer == nullptr) { return false; } const uint8_t msgType = (packInfo->buffer[msgOffset] >> 5) & IR_MASK_MSG_TYPE; if (requireTypedSize && !isTypedPacketSizeValid(msgType, packInfo->packSize)) { return false; } if (checkAddress()) { isAvailable = true; isRawAvailable = true; #ifdef IRDEBUG_INFO Serial.print(" OK "); #endif } else { isRawAvailable = true; #ifdef IRDEBUG_INFO Serial.print(" NOT-OK "); #endif } return isAvailable; } uint16_t BasePack::_getAddrFrom(BasePack *obj) { if (obj == nullptr || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr || obj->packInfo->packSize < crcBytes || uint16_t(obj->addressFromOffset) + 1U >= uint16_t(obj->packInfo->packSize - crcBytes)) { return 0; } return (obj->packInfo->buffer[obj->addressFromOffset] << 8) | obj->packInfo->buffer[obj->addressFromOffset + 1]; } uint16_t BasePack::_getAddrTo(BasePack *obj) { if (obj == nullptr || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr || obj->packInfo->packSize < crcBytes || uint16_t(obj->addressToOffset) + 1U >= uint16_t(obj->packInfo->packSize - crcBytes)) { return 0; } return (obj->packInfo->buffer[obj->addressToOffset] << 8) | obj->packInfo->buffer[obj->addressToOffset + 1]; } uint8_t BasePack::_getDataSize(BasePack *obj) { if (obj == nullptr || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr) { return 0; } const uint16_t frameOverhead = uint16_t(crcBytes) + uint16_t(obj->DataOffset); if (uint16_t(obj->packInfo->packSize) <= frameOverhead) { return 0; } return uint8_t(uint16_t(obj->packInfo->packSize) - frameOverhead); } uint8_t *BasePack::_getDataPrt(BasePack *obj) { if (obj == nullptr || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr || obj->packInfo->packSize < crcBytes) { return nullptr; } const uint16_t dataEnd = uint16_t(obj->packInfo->packSize) - uint16_t(crcBytes); if (uint16_t(obj->DataOffset) > dataEnd) { return nullptr; } return obj->packInfo->buffer + obj->DataOffset; } uint8_t BasePack::_getDataRawSize(BasePack *obj) { if (obj == nullptr || obj->packInfo == nullptr) { return 0; } return obj->packInfo->packSize; } bool BasePack::available() { if (isAvailable) { isAvailable = false; isRawAvailable = false; return true; } else { return false; } } bool BasePack::availableRaw() { if (isRawAvailable) { isRawAvailable = false; return true; } else { return false; } } bool Data::checkAddress() { bool ret; IR_FOX::checkAddressRuleApply(getAddrTo(), this->id, ret); return ret; } bool DataBack::checkAddress() { bool ret; if (getMsgType() == IR_MSG_BACK_TO) { DataOffset = 5; IR_FOX::checkAddressRuleApply((packInfo->buffer[addressToOffset] << 8) | packInfo->buffer[addressToOffset + 1], this->id, ret); } else { DataOffset = 3; ret = true; } return ret; } bool Accept::checkAddress() { return true; } bool Request::checkAddress() { bool ret; IR_FOX::checkAddressRuleApply(getAddrTo(), this->id, ret); return ret; } }