1
0
Fork 0

responder counts failed message construction

This commit is contained in:
Kevin Matz 2021-08-10 15:35:27 -04:00
parent 3a86b10a8b
commit 8e7a96ac82
4 changed files with 101 additions and 48 deletions

View File

@ -30,6 +30,7 @@ namespace RDM {
* @brief Message::Message
*/
Message::Message()
: failure_mode(0)
{
}
@ -47,6 +48,7 @@ Message::Message(const Message &obj)
, messageCount(obj.messageCount)
, subDevice(obj.subDevice)
, propertyID(obj.propertyID)
, failure_mode(0)
{
data_.insert(data_.end(), obj.data()->begin(), obj.data()->end());
}
@ -57,6 +59,7 @@ Message::Message(const Message &obj)
* @param data
*/
Message::Message(const std::vector<u_int8_t> &data)
: failure_mode(0)
{
read(data);
}
@ -77,15 +80,21 @@ Message::~Message()
*/
void Message::read(const std::vector<uint8_t> &data)
{
if (data.size() < 3) // SC + SC_SUB + LENGTH
return;
if (data.size() < 9) // SC + SC_SUB + LENGTH + DESTINATION
{
short_message = true;
return;
}
// 6.2.1 START Code
// This field shall contain the defined RDM START Code (SC_RDM). Controllers
// and Responders shall always send SC_RDM in this slot, and any packet
// containing a value other than SC_RDM is outside the scope of this standard.
if (data[0] != SC_RDM)
return;
{
incorrect_sc = true;
return;
}
// 6.2.2 Sub START Code
// This field shall contain the Sub-START Code within RDM that defines this
@ -95,7 +104,10 @@ void Message::read(const std::vector<uint8_t> &data)
// Controllers shall always send SC_SUB_MESSAGE in this slot, and Responders
// shall ignore any packets containing other values.
if (data[1] != SC_SUB_MESSAGE)
return;
{
incorrect_sub_sc = true;
return;
}
// 6.2.3 Message Length
// The Message Length value is defined as the number of slots in the RDM
@ -103,8 +115,11 @@ void Message::read(const std::vector<uint8_t> &data)
// an 8-bit value.
// The Message Length field points to the Checksum High Slot.
uint8_t length = data[2];
if (length != data.size() - 2)
return;
if (length + 2 != data.size())
{
length_mismatch = true;
return;
}
// 6.2.4 Destination UID
// The Destination UID is the UID of the target device(s).
@ -168,9 +183,19 @@ void Message::read(const std::vector<uint8_t> &data)
uint8_t pdl = data[23];
// 6.2.10.4 Parameter Data (PD)
// The Parameter Data is of variable length. The content format is PID dependent.
// The Parameter Data is of variable length.
for (int i = 0; i < pdl; i++)
appendData<uint8_t>(data[24+i]);
// 6.2.11 Checksum
// If the checksum field in the packet does not match the calculated checksum,
// then the packet shall be discarded and no response sent.
auto chksum = Message::readType<uint16_t>(data, data.size() - 2);
if (chksum != checksum())
{
checksum_fail = true;
return;
}
}

View File

@ -52,6 +52,17 @@ struct Message
uint8_t commandClass;
PID propertyID;
union {
uint8_t failure_mode;
struct {
bool short_message : 1;
bool length_mismatch : 1;
bool checksum_fail : 1;
bool incorrect_sc : 1;
bool incorrect_sub_sc: 1;
};
};
const std::vector<uint8_t>* data() const { return &data_; }
uint8_t length() const { return data_.size(); }
uint16_t checksum() const;

View File

@ -23,6 +23,8 @@
*/
#include "responder.h"
#include <limits>
namespace RDM {
/**
@ -34,14 +36,19 @@ Responder::Responder()
deviceModelID = 1;
deviceModelDescription = "Basic RDM Responder";
// E1.20 required parameters
// DISC_UNIQUE_BRANCH
// DISC_MUTE
// DISC_UN_MUTE
// addt'l parameters
// COMMS_STATUS
// QUEUED_MESSAGE
// /// Category Network Management
// static const PID DISC_UNIQUE_BRANCH = 0x0001;
// static const PID DISC_MUTE = 0x0002;
// static const PID DISC_UN_MUTE = 0x0003;
// static const PID PROXIED_DEVICES = 0x0010;
// static const PID PROXIED_DEVICE_COUNT = 0x0011;
// static const PID COMMS_STATUS = 0x0015;
// /// Category - Status Collection
// static const PID QUEUED_MESSAGE = 0x0020; // See Table A-4
// static const PID STATUS_MESSAGES = 0x0030; // See Table A-4
// static const PID STATUS_ID_DESCRIPTION = 0x0031;
// static const PID CLEAR_STATUS_ID = 0x0032;
// static const PID SUB_DEVICE_STATUS_REPORT_THRESHOLD = 0x0033; // See Table A-4
}
@ -96,25 +103,6 @@ void Responder::send(Message *response)
void Responder::receive(const std::vector<uint8_t> &data)
{
auto message = new Message(data);
// 6.2.8.1 Message Count field for Controller Generated Messages
// The Message Count shall be set to 0x00 in all controller generated requests.
if (message->messageCount != 0)
{
delete message;
return;
}
// 6.2.11 Checksum
// If the checksum field in the packet does not match the calculated checksum,
// then the packet shall be discarded and no response sent.
auto checksum = Message::readType<uint16_t>(data, data.size() - 2);
if (checksum != message->checksum())
{
delete message;
return;
}
receive(message);
delete message;
}
@ -126,13 +114,41 @@ void Responder::receive(const std::vector<uint8_t> &data)
*/
void Responder::receive(const Message *message)
{
if (message->commandClass != DISCOVERY_COMMAND ||
message->commandClass != GET_COMMAND ||
message->commandClass != SET_COMMAND)
return;
if (message->short_message)
{
if (short_message_counter_ != std::numeric_limits<uint16_t>::max())
short_message_counter_++;
return;
}
// RDM::UID::operator== also returns true for broadcast messages
if (message->destination != id)
if (message->destination != id ||
message->incorrect_sc ||
message->incorrect_sub_sc)
return;
if (message->length_mismatch)
{
if (length_mismatch_counter_ != std::numeric_limits<uint16_t>::max())
length_mismatch_counter_++;
return;
}
if (message->checksum_fail)
{
if (checksum_fail_counter_ != std::numeric_limits<uint16_t>::max())
checksum_fail_counter_++;
return;
}
// all other uncaught errors
if (message->failure_mode != 0)
return;
// responder can ignore _COMMAND_RESPONSE class messages
if (message->commandClass == DISCOVERY_COMMAND_RESPONSE ||
message->commandClass == GET_COMMAND_RESPONSE ||
message->commandClass == SET_COMMAND_RESPONSE)
return;
auto response = new Message();
@ -153,8 +169,12 @@ void Responder::receive(const Message *message)
rxSet(message, response);
break;
default:
break;
delete response;
return;
}
if (response)
queued_messages_.push(response);
}
@ -166,7 +186,6 @@ void Responder::rxDiscovery(__attribute__((unused)) const Message *message,
Message* response)
{
response->commandClass = DISCOVERY_COMMAND_RESPONSE;
queued_messages_.push(response);
}
@ -186,14 +205,12 @@ void Responder::rxGet(const Message *message,
{
response->responseType = RESPONSE_TYPE_NACK_REASON;
response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE);
queued_messages_.push(response);
return;
}
if (message->subDevice == 0)
{
get(message, response);
queued_messages_.push(response);
return;
}
@ -201,12 +218,10 @@ void Responder::rxGet(const Message *message,
{
response->responseType = RESPONSE_TYPE_NACK_REASON;
response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE);
queued_messages_.push(response);
return;
}
sub_devices_.at(message->subDevice)->get(message, response);
queued_messages_.push(response);
}
@ -220,7 +235,6 @@ void Responder::rxSet(const Message *message,
if (message->subDevice == 0)
{
set(message, response);
queued_messages_.push(response);
return;
}
@ -234,6 +248,7 @@ void Responder::rxSet(const Message *message,
queued_messages_.push(rsp);
}
delete response;
response = nullptr;
return;
}
@ -241,12 +256,10 @@ void Responder::rxSet(const Message *message,
{
response->responseType = RESPONSE_TYPE_NACK_REASON;
response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE);
queued_messages_.push(response);
return;
}
sub_devices_.at(message->subDevice)->set(message, response);
queued_messages_.push(response);
}

View File

@ -53,6 +53,10 @@ protected:
std::queue<Message*> queued_messages_;
private:
uint16_t short_message_counter_ = 0;
uint16_t length_mismatch_counter_ = 0;
uint16_t checksum_fail_counter_ = 0;
};