responder counts failed message construction
This commit is contained in:
parent
3a86b10a8b
commit
8e7a96ac82
@ -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
|
||||||
|
{
|
||||||
|
short_message = true;
|
||||||
return;
|
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)
|
||||||
|
{
|
||||||
|
incorrect_sc = true;
|
||||||
return;
|
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)
|
||||||
|
{
|
||||||
|
incorrect_sub_sc = true;
|
||||||
return;
|
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())
|
||||||
|
{
|
||||||
|
length_mismatch = true;
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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())
|
||||||
|
short_message_counter_++;
|
||||||
return;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user