1
0
Fork 0

review of stream condition checking throughout iStream path

This commit is contained in:
Kevin Matz 2021-08-16 10:14:39 -04:00
parent abb5bf1466
commit a6620f1def
16 changed files with 197 additions and 135 deletions

View File

@ -90,6 +90,11 @@ void Appliance::TcpPacketReceiver(PDU::Stream stream)
*/
void Appliance::RlpReceiver(std::shared_ptr<RLP::Pdu> root)
{
/// To this point, the data segment of the RLP PDU will not have been read.
/// The root PDU must have not failed, and still have bytes available to read.
if (!root->stream()->good())
return;
if (rlp_vectors_.count(root->vector()))
for(auto const &handler : rlp_vectors_[root->vector()])
handler(root);

View File

@ -88,10 +88,12 @@ size_t range::streamSize() const
*/
void range::iStream(PDU::Stream stream)
{
address = read_(stream);
if (type_ == SINGLE) return;
incriment = read_(stream);
count = read_(stream);
if (!stream->good())
return;
address = read_(stream);
if (type_ == SINGLE) return;
incriment = read_(stream);
count = read_(stream);
}
@ -229,61 +231,59 @@ Pdu::Pdu()
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
PDU::Pdu::iStream(stream); // flags, length, and vector
createHeader<address_type>(); // header
createHeader<address_type>();
if (!flags_.hasData)
return;
if (!flags_.hasData)
return;
auto header = static_cast<address_type*>(this->header());
auto header = static_cast<address_type*>(this->header());
auto dataIsAddressList = [this, header] () {
data_ = new address_list(header);
data_->iStream(stream_);
};
auto dataIsAddressList = [this, header] () {
data_ = new address_list(header);
data_->iStream(stream_);
};
auto dataIsAdddresPairList = [this, header] () {
data_ = new address_pair_list(header);
data_->iStream(stream_);
};
auto dataIsAdddresPairList = [this, header] () {
data_ = new address_pair_list(header);
data_->iStream(stream_);
};
switch(vector()) {
case GET_PROPERTY:
dataIsAddressList();
break;
case SET_PROPERTY:
dataIsAdddresPairList();
break;
case GET_PROPERTY_REPLY:
dataIsAdddresPairList();
break;
case EVENT:
dataIsAdddresPairList();
break;
case SUBSCRIBE:
dataIsAddressList();
break;
case UNSUBSCRIBE:
dataIsAddressList();
break;
case GET_PROPERTY_FAIL:
dataIsAdddresPairList();
break;
case SET_PROPERTY_FAIL:
dataIsAdddresPairList();
break;
case SUBSCRIBE_ACCEPT:
dataIsAddressList();
break;
case SUBSCRIBE_REJECT:
dataIsAdddresPairList();
break;
case SYNC_EVENT:
dataIsAdddresPairList();
break;
}
switch(vector()) {
case GET_PROPERTY:
dataIsAddressList();
break;
case SET_PROPERTY:
dataIsAdddresPairList();
break;
case GET_PROPERTY_REPLY:
dataIsAdddresPairList();
break;
case EVENT:
dataIsAdddresPairList();
break;
case SUBSCRIBE:
dataIsAddressList();
break;
case UNSUBSCRIBE:
dataIsAddressList();
break;
case GET_PROPERTY_FAIL:
dataIsAdddresPairList();
break;
case SET_PROPERTY_FAIL:
dataIsAdddresPairList();
break;
case SUBSCRIBE_ACCEPT:
dataIsAddressList();
break;
case SUBSCRIBE_REJECT:
dataIsAdddresPairList();
break;
case SYNC_EVENT:
dataIsAdddresPairList();
break;
}
}
} // DMP

View File

@ -51,7 +51,7 @@ public:
{
if (in_avail() < sizeof(T))
setstate(std::ios_base::failbit);
if (fail())
if (!good())
return 0;
T ret = 0;
auto data = reinterpret_cast<uint8_t*>(&ret);

View File

@ -49,6 +49,8 @@ transport::transport(bool filled)
*/
void transport::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
/**
* 2. Preamble Format:
* The ACN Packet Identifier shall be the text string ASC-E1.17\0\0\0

View File

@ -52,6 +52,8 @@ transport::transport(bool filled)
*/
void transport::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
/**
* 2. Preamble Format:
* The preamble size includes both size fields so the

View File

@ -43,11 +43,14 @@ size_t rlp_header::streamSize() const
*/
void rlp_header::iStream(PDU::Stream stream)
{
uint8_t buffer[UUID_LENGTH];
stream->read(buffer, UUID_LENGTH);
if (stream->gcount() != UUID_LENGTH)
return stream->setstate(std::ios_base::failbit);
cid = UUID::uuid(buffer);
if (!stream->good())
return;
uint8_t buffer[UUID_LENGTH];
stream->read(buffer, UUID_LENGTH);
if (stream->gcount() != UUID_LENGTH)
return stream->setstate(std::ios_base::failbit);
cid = UUID::uuid(buffer);
}
@ -57,7 +60,7 @@ void rlp_header::iStream(PDU::Stream stream)
*/
void rlp_header::oStream(PDU::Stream stream) const
{
stream->write(cid.bytes(), UUID_LENGTH);
stream->write(cid.bytes(), UUID_LENGTH);
}
@ -77,10 +80,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
if (stream->fail()) return;
createHeader<rlp_header>();
PDU::Pdu::iStream(stream); // flags, length, and vector
createHeader<rlp_header>(); // header
// protocol dependent data segment // data
}
} // RLP

View File

@ -32,9 +32,12 @@ namespace UDP {
* @brief address_t::iStream
* @param stream
*/
void address_t::iStream(PDU::Stream stream) {
*stream >> type;
void address_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> type;
if (type != SDT_ADDR_NULL)
*stream >> port;

View File

@ -33,6 +33,8 @@ namespace SDT {
*/
void params_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> Expiry;
uint8_t packed;
*stream >> packed;
@ -50,6 +52,8 @@ void params_t::iStream(PDU::Stream stream)
*/
void join_data_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> mid;
*stream >> number;
*stream >> reciprocal;
@ -67,6 +71,8 @@ void join_data_t::iStream(PDU::Stream stream)
*/
void join_accept_data_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
@ -83,6 +89,8 @@ void join_accept_data_t::iStream(PDU::Stream stream)
*/
void join_refuse_data_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
@ -99,6 +107,8 @@ void join_refuse_data_t::iStream(PDU::Stream stream)
*/
void nak_data_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
uint8_t buf[16];
stream->read(buf, sizeof(buf));
leader = UUID::uuid(buf);
@ -116,6 +126,8 @@ void nak_data_t::iStream(PDU::Stream stream)
*/
void wrapper_data_t::iStream(PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> number;
}
@ -194,9 +206,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream); //! do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
PDU::Pdu::iStream(stream); // flags, length, and vector
// TODO: header segment // header
// TODO: data segment // data
}
/**
@ -226,10 +238,9 @@ ClientPdu::ClientPdu()
*/
void ClientPdu::iStream(PDU::Stream stream)
{
PDU::Pdu::iStream(stream);
if (stream->fail()) return;
createHeader<client_pdu_header>();
PDU::Pdu::iStream(stream); // flags, length, and vector
createHeader<client_pdu_header>(); // header
// TODO: data segment // data
}
}; // SDT

View File

@ -40,8 +40,11 @@ Pdu::Pdu()
* @brief BrokerProtocol::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// TODO: header segment // header
// TODO: data segment // data
}

View File

@ -40,8 +40,11 @@ Pdu::Pdu()
* @brief EPT::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// TODO: header segment // header
// TODO: data segment // data
}
@ -60,8 +63,11 @@ Pdu::Pdu()
* @brief EPT::DATA::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// TODO: header segment // header
// TODO: data segment // data
}
} // namespace DATA
@ -82,8 +88,11 @@ Pdu::Pdu()
* @brief EPT::STATUS::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// TODO: header segment // header
// TODO: data segment // data
}
} // namespace STATUS

View File

@ -33,6 +33,8 @@ namespace LLRP {
*/
void llrp_data::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
/// Destination CID - The Destination CID indicates the CID of the intended
/// recipient of this PDU.
uint8_t * buffer = new uint8_t[UUID_LENGTH];
@ -76,16 +78,11 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
/// has no header
auto payload = new llrp_data();
payload->iStream(stream_);
data_ = payload;
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
createData<llrp_data>(); // data
auto payload = static_cast<llrp_data*>(data_);
switch (vector_) {
case VECTOR_LLRP_PROBE_REQUEST:
{
@ -129,6 +126,9 @@ namespace ProbeRequest {
*/
void request_data::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
auto readUID = [stream] (RDM::UID& uid) {
*stream >> uid.device;
*stream >> uid.manufacturer;
@ -178,14 +178,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
/// LLRP::PDU has no header
data_ = new request_data();
data_->iStream(stream_);
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
createData<request_data>(); // data
}
} // namespace ProbeRequest
@ -198,6 +193,9 @@ namespace ProbeReply {
*/
void reply_data::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> id.device;
*stream >> id.manufacturer;
stream->read(address, sizeof(address));
@ -233,14 +231,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
/// has no header
data_ = new reply_data();
data_->iStream(stream_);
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
createData<reply_data>(); // data
}
} // namespace ProbeReply
@ -253,6 +246,9 @@ namespace RdmCmd {
*/
void rdm_data::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
auto buffer = std::vector<uint8_t>();
buffer.push_back(RDM::SC_RDM);
while (stream->good())
@ -288,14 +284,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // do base class first
if (stream->fail()) return;
if (!stream_->good()) return;
/// has no header
data_ = new rdm_data();
data_->iStream(stream_);
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
createData<rdm_data>(); // data
}
} // namespace RdmCmd

View File

@ -40,8 +40,11 @@ Pdu::Pdu()
* @brief RPT::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
}
@ -60,8 +63,11 @@ Pdu::Pdu()
* @brief RPT::REQUEST::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
}
} // namespace DATA
@ -82,8 +88,11 @@ Pdu::Pdu()
* @brief RPT::STATUS::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
}
} // namespace STATUS
@ -104,8 +113,11 @@ Pdu::Pdu()
* @brief RPT::NOTIFICATION::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
}
} // namespace NOTIFICATION
@ -127,8 +139,11 @@ Pdu::Pdu()
* @brief RPT::COMMAND::Pdu::iStream
* @param stream
*/
void Pdu::iStream([[maybe_unused]] ACN::PDU::Stream stream)
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
}
} // namespace COMMAND

View File

@ -24,6 +24,8 @@
#pragma once
#include "pdu.h"
#include "config.h"
#include "rdm/uid.h"
namespace RDMnet {
namespace RPT {
@ -40,6 +42,13 @@ namespace RPT {
*/
/**
* @brief 3.3.2 Dynamic UID Request
* RPT Components wishing to obtain Dynamic UIDs from the Broker use a special
* Dynamic UID value known as a Dynamic UID Request.
*/
static const RDM::UID DynamicUidRequest = RDM::UID(0, MY_ESTA_MANUFACTURER_ID,
true);
/**
* @brief The RPT::Pdu class

View File

@ -49,6 +49,9 @@ size_t data_header::streamSize() const
*/
void data_header::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
stream->read(source_name, sizeof(source_name));
if (stream->gcount() != sizeof(source_name))
return stream->setstate(std::ios_base::failbit);
@ -91,11 +94,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
ACN::PDU::Pdu::iStream(stream);
if (stream->fail()) return;
createHeader<data_header>();
createDataBlock<ACN::DMP::Pdu>();
ACN::PDU::Pdu::iStream(stream); // flags, length, and vector
createHeader<data_header>(); // header
createDataBlock<ACN::DMP::Pdu>(); // data
}
} // DATA

View File

@ -47,6 +47,9 @@ size_t sync_header::streamSize() const
*/
void sync_header::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> sequence_number;
*stream >> sync_address;
stream->read(reserved, sizeof(reserved));
@ -82,6 +85,9 @@ size_t discovery_header::streamSize() const
*/
void discovery_header::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
stream->read(source_name, sizeof(source_name));
if (stream->gcount() != sizeof(source_name))
return stream->setstate(std::ios_base::failbit);
@ -112,17 +118,15 @@ Pdu::Pdu()
void Pdu::iStream(ACN::PDU::Stream stream)
{
ACN::PDU::Pdu::iStream(stream);
if (stream->fail()) return;
ACN::PDU::Pdu::iStream(stream); // flags, length, and vector
switch(vector_)
{
case VECTOR_E131_EXTENDED_SYNCHRONIZATION:
createHeader<sync_header>();
break;
createHeader<sync_header>(); // header
break; // has no data // data
case VECTOR_E131_EXTENDED_DISCOVERY:
createHeader<discovery_header>();
createDataBlock<DISCOVERY::Pdu>();
createHeader<discovery_header>(); // header
createDataBlock<DISCOVERY::Pdu>(); // data
break;
default:
break;
@ -148,6 +152,9 @@ size_t discovery_list_header::streamSize() const
*/
void discovery_list_header::iStream(ACN::PDU::Stream stream)
{
if (!stream->good())
return;
*stream >> page;
*stream >> last_page;
}
@ -205,11 +212,9 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
ACN::PDU::Pdu::iStream(stream);
if (stream->fail()) return;
createHeader<discovery_list_header>();
createData<discovery_list_data>();
ACN::PDU::Pdu::iStream(stream); // flags, length, and vector
createHeader<discovery_list_header>(); // header
createData<discovery_list_data>(); // data
if (data_)
{

View File

@ -126,8 +126,10 @@ void Receiver::onDiscovered(const EXTENDED::DISCOVERY::Watcher cb) {
void Receiver::dataReceiver(std::shared_ptr<ACN::RLP::Pdu> root)
{
root->createDataBlock<DATA::Pdu>();
// a PDU::Block is guaranteed to have been instantiated, but if the input
// stream failed, it will not list any PDU. OK to loop without checking
// the state of the stream.
auto block = static_cast<ACN::PDU::Block<DATA::Pdu>*>(root->data());
for(auto const &frame : *block->pdu)
{
/// 6.2.1 E1.31 Data Packet: Vector
@ -154,8 +156,10 @@ void Receiver::dataReceiver(std::shared_ptr<ACN::RLP::Pdu> root)
void Receiver::extendedReceiver(std::shared_ptr<ACN::RLP::Pdu> root)
{
root->createDataBlock<EXTENDED::Pdu>();
// a PDU::Block is guaranteed to have been instantiated, but if the input
// stream failed, it will not list any PDU. OK to loop without checking
// the state of the stream.
auto block = static_cast<ACN::PDU::Block<EXTENDED::Pdu>*>(root->data());
for(auto const &frame : *block->pdu)
{
switch(frame->vector()) {