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 * @brief Message::Message
*/ */
Message::Message() Message::Message()
: failure_mode(0)
{ {
} }
@ -47,6 +48,7 @@ Message::Message(const Message &obj)
, messageCount(obj.messageCount) , messageCount(obj.messageCount)
, subDevice(obj.subDevice) , subDevice(obj.subDevice)
, propertyID(obj.propertyID) , propertyID(obj.propertyID)
, failure_mode(0)
{ {
data_.insert(data_.end(), obj.data()->begin(), obj.data()->end()); data_.insert(data_.end(), obj.data()->begin(), obj.data()->end());
} }
@ -57,6 +59,7 @@ Message::Message(const Message &obj)
* @param data * @param data
*/ */
Message::Message(const std::vector<u_int8_t> &data) Message::Message(const std::vector<u_int8_t> &data)
: failure_mode(0)
{ {
read(data); read(data);
} }
@ -77,15 +80,21 @@ Message::~Message()
*/ */
void Message::read(const std::vector<uint8_t> &data) void Message::read(const std::vector<uint8_t> &data)
{ {
if (data.size() < 3) // SC + SC_SUB + LENGTH if (data.size() < 9) // SC + SC_SUB + LENGTH + DESTINATION
return; {
short_message = true;
return;
}
// 6.2.1 START Code // 6.2.1 START Code
// This field shall contain the defined RDM START Code (SC_RDM). Controllers // 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 // 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. // containing a value other than SC_RDM is outside the scope of this standard.
if (data[0] != SC_RDM) if (data[0] != SC_RDM)
return; {
incorrect_sc = true;
return;
}
// 6.2.2 Sub START Code // 6.2.2 Sub START Code
// This field shall contain the Sub-START Code within RDM that defines this // 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 // Controllers shall always send SC_SUB_MESSAGE in this slot, and Responders
// shall ignore any packets containing other values. // shall ignore any packets containing other values.
if (data[1] != SC_SUB_MESSAGE) if (data[1] != SC_SUB_MESSAGE)
return; {
incorrect_sub_sc = true;
return;
}
// 6.2.3 Message Length // 6.2.3 Message Length
// The Message Length value is defined as the number of slots in the RDM // 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. // an 8-bit value.
// The Message Length field points to the Checksum High Slot. // The Message Length field points to the Checksum High Slot.
uint8_t length = data[2]; uint8_t length = data[2];
if (length != data.size() - 2) if (length + 2 != data.size())
return; {
length_mismatch = true;
return;
}
// 6.2.4 Destination UID // 6.2.4 Destination UID
// The Destination UID is the UID of the target device(s). // 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]; uint8_t pdl = data[23];
// 6.2.10.4 Parameter Data (PD) // 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++) for (int i = 0; i < pdl; i++)
appendData<uint8_t>(data[24+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; uint8_t commandClass;
PID propertyID; 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_; } const std::vector<uint8_t>* data() const { return &data_; }
uint8_t length() const { return data_.size(); } uint8_t length() const { return data_.size(); }
uint16_t checksum() const; uint16_t checksum() const;

View File

@ -23,6 +23,8 @@
*/ */
#include "responder.h" #include "responder.h"
#include <limits>
namespace RDM { namespace RDM {
/** /**
@ -34,14 +36,19 @@ Responder::Responder()
deviceModelID = 1; deviceModelID = 1;
deviceModelDescription = "Basic RDM Responder"; deviceModelDescription = "Basic RDM Responder";
// E1.20 required parameters // /// Category Network Management
// DISC_UNIQUE_BRANCH // static const PID DISC_UNIQUE_BRANCH = 0x0001;
// DISC_MUTE // static const PID DISC_MUTE = 0x0002;
// DISC_UN_MUTE // static const PID DISC_UN_MUTE = 0x0003;
// static const PID PROXIED_DEVICES = 0x0010;
// addt'l parameters // static const PID PROXIED_DEVICE_COUNT = 0x0011;
// COMMS_STATUS // static const PID COMMS_STATUS = 0x0015;
// QUEUED_MESSAGE // /// 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) void Responder::receive(const std::vector<uint8_t> &data)
{ {
auto message = new Message(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); receive(message);
delete message; delete message;
} }
@ -126,13 +114,41 @@ void Responder::receive(const std::vector<uint8_t> &data)
*/ */
void Responder::receive(const Message *message) void Responder::receive(const Message *message)
{ {
if (message->commandClass != DISCOVERY_COMMAND || if (message->short_message)
message->commandClass != GET_COMMAND || {
message->commandClass != SET_COMMAND) if (short_message_counter_ != std::numeric_limits<uint16_t>::max())
return; short_message_counter_++;
return;
}
// RDM::UID::operator== also returns true for broadcast messages // 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; return;
auto response = new Message(); auto response = new Message();
@ -153,8 +169,12 @@ void Responder::receive(const Message *message)
rxSet(message, response); rxSet(message, response);
break; break;
default: 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) Message* response)
{ {
response->commandClass = DISCOVERY_COMMAND_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->responseType = RESPONSE_TYPE_NACK_REASON;
response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE); response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE);
queued_messages_.push(response);
return; return;
} }
if (message->subDevice == 0) if (message->subDevice == 0)
{ {
get(message, response); get(message, response);
queued_messages_.push(response);
return; return;
} }
@ -201,12 +218,10 @@ void Responder::rxGet(const Message *message,
{ {
response->responseType = RESPONSE_TYPE_NACK_REASON; response->responseType = RESPONSE_TYPE_NACK_REASON;
response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE); response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE);
queued_messages_.push(response);
return; return;
} }
sub_devices_.at(message->subDevice)->get(message, response); 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) if (message->subDevice == 0)
{ {
set(message, response); set(message, response);
queued_messages_.push(response);
return; return;
} }
@ -234,6 +248,7 @@ void Responder::rxSet(const Message *message,
queued_messages_.push(rsp); queued_messages_.push(rsp);
} }
delete response; delete response;
response = nullptr;
return; return;
} }
@ -241,12 +256,10 @@ void Responder::rxSet(const Message *message,
{ {
response->responseType = RESPONSE_TYPE_NACK_REASON; response->responseType = RESPONSE_TYPE_NACK_REASON;
response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE); response->appendData<uint16_t>(NR_SUB_DEVICE_OUT_OF_RANGE);
queued_messages_.push(response);
return; return;
} }
sub_devices_.at(message->subDevice)->set(message, response); sub_devices_.at(message->subDevice)->set(message, response);
queued_messages_.push(response);
} }

View File

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