#include "PacketTypes.h" namespace PacketTypes { bool BasePack::checkPacketLayout() const { if (packInfo == nullptr || packInfo->buffer == nullptr || packInfo->packSize < msgBytes + crcBytes || packInfo->packSize > irproto::kMaxWireFrameBytes) { return false; } return (packInfo->buffer[msgOffset] & IR_MASK_MSG_INFO) == packInfo->packSize; } bool BasePack::checkAddress() { return true; }; void BasePack::set(IR_FOX::PackInfo *packInfo, uint16_t id) { isAvailable = false; isRawAvailable = false; this->packInfo = packInfo; this->id = id; if (!checkPacketLayout()) { return; } if (checkAddress()) { isAvailable = true; isRawAvailable = true; #ifdef IRDEBUG_INFO Serial.print(" OK "); #endif } else { isRawAvailable = true; #ifdef IRDEBUG_INFO Serial.print(" NOT-OK "); #endif } } uint16_t BasePack::_getAddrFrom(BasePack *obj) { if (obj == nullptr || !obj->checkPacketLayout() || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr || obj->packInfo->packSize < crcBytes || static_cast(obj->addressFromOffset) + 1U >= static_cast(obj->packInfo->packSize - crcBytes)) { return 0U; } return (obj->packInfo->buffer[obj->addressFromOffset] << 8) | obj->packInfo->buffer[obj->addressFromOffset + 1]; }; uint16_t BasePack::_getAddrTo(BasePack *obj) { if (obj == nullptr || !obj->checkPacketLayout() || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr || obj->packInfo->packSize < crcBytes || static_cast(obj->addressToOffset) + 1U >= static_cast(obj->packInfo->packSize - crcBytes)) { return 0U; } return (obj->packInfo->buffer[obj->addressToOffset] << 8) | obj->packInfo->buffer[obj->addressToOffset + 1]; }; uint8_t BasePack::_getDataSize(BasePack *obj) { if (obj == nullptr || !obj->checkPacketLayout() || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr) { return 0U; } const uint16_t overhead = static_cast(obj->DataOffset) + crcBytes; return static_cast(obj->packInfo->packSize) > overhead ? static_cast(static_cast(obj->packInfo->packSize) - overhead) : 0U; }; uint8_t *BasePack::_getDataPrt(BasePack *obj) { if (obj == nullptr || !obj->checkPacketLayout() || obj->packInfo == nullptr || obj->packInfo->buffer == nullptr || obj->packInfo->packSize < crcBytes || static_cast(obj->DataOffset) > static_cast(obj->packInfo->packSize - crcBytes)) { return nullptr; } return obj->packInfo->buffer + obj->DataOffset; }; uint8_t BasePack::_getDataRawSize(BasePack *obj) { return obj != nullptr && obj->checkPacketLayout() && obj->packInfo != nullptr ? obj->packInfo->packSize : 0U; }; 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::checkPacketLayout() const { if (!BasePack::checkPacketLayout()) { return false; } const uint8_t msgType = (packInfo->buffer[msgOffset] >> 5) & IR_MASK_MSG_TYPE; return (msgType == IR_MSG_DATA_ACCEPT || msgType == IR_MSG_DATA_NOACCEPT) && irproto::isTypedWireSizeValid(msgType, packInfo->packSize); } bool Data::checkAddress() { bool ret; IR_FOX::checkAddressRuleApply(getAddrTo(), this->id, ret); return ret; } bool DataBack::checkPacketLayout() const { if (!BasePack::checkPacketLayout()) { return false; } const uint8_t msgType = (packInfo->buffer[msgOffset] >> 5) & IR_MASK_MSG_TYPE; return (msgType == IR_MSG_BACK || msgType == IR_MSG_BACK_TO) && irproto::isTypedWireSizeValid(msgType, packInfo->packSize); } 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::checkPacketLayout() const { if (!BasePack::checkPacketLayout()) { return false; } const uint8_t msgType = (packInfo->buffer[msgOffset] >> 5) & IR_MASK_MSG_TYPE; return msgType == IR_MSG_ACCEPT && irproto::isTypedWireSizeValid(msgType, packInfo->packSize); } bool Accept::checkAddress() { return true; } bool Request::checkPacketLayout() const { if (!BasePack::checkPacketLayout()) { return false; } const uint8_t msgType = (packInfo->buffer[msgOffset] >> 5) & IR_MASK_MSG_TYPE; return msgType == IR_MSG_REQUEST && irproto::isTypedWireSizeValid(msgType, packInfo->packSize); } bool Request::checkAddress() { bool ret; IR_FOX::checkAddressRuleApply(getAddrTo(), this->id, ret); return ret; } }