1
0
Fork 0

RPT PDU i/o

This commit is contained in:
Kevin Matz 2021-08-17 14:19:17 -04:00
parent 2eac9cf7fb
commit edb0880bdf
2 changed files with 265 additions and 40 deletions

View File

@ -22,32 +22,12 @@
SOFTWARE.
*/
#include "rdmnet.h"
#include "rpt.h"
namespace RDMnet {
namespace RPT {
/**
* @brief RPT::Pdu::Pdu
*/
Pdu::Pdu()
: RDMnet::Pdu(4)
{
}
/**
* @brief RPT::Pdu::iStream
* @param 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 REQUEST {
/**
@ -67,10 +47,11 @@ void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
data_ = new COMMAND::Pdu(); // data
data_->iStream(stream_);
}
} // namespace DATA
} // namespace REQUEST
namespace STATUS {
@ -92,7 +73,69 @@ void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
switch (vector()) // data
{
case VECTOR_RPT_STATUS_UNKNOWN_RPT_UID:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_RDM_TIMEOUT:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_RDM_INVALID_RESPONSE:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_UNKNOWN_RDM_UID:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_UNKNOWN_ENDPOINT:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_BROADCAST_COMPLETE:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_UNKNOWN_VECTOR:
createData<status_string_data>();
break;
case VECTOR_RPT_STATUS_INVALID_MESSAGE:
// has no data
break;
case VECTOR_RPT_STATUS_INVALID_COMMAND_CLASS:
// has no data
break;
default:
return;
}
}
/**
* @brief status_string_data::streamSize
* @return
*/
size_t status_string_data::streamSize() const
{
return status_string.size();
}
/**
* @brief unknown_rpt_uid_data::iStream
* @param stream
*/
void status_string_data::iStream(ACN::PDU::Stream stream)
{
stream->readString(status_string);
}
/**
* @brief unknown_rpt_uid_data::oStream
* @param stream
*/
void status_string_data::oStream(ACN::PDU::Stream stream) const
{
stream->writeString(status_string);
}
} // namespace STATUS
@ -115,11 +158,12 @@ Pdu::Pdu()
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
createDataBlock<COMMAND::Pdu>(); // data
}
} // namespace NOTIFICATION
@ -143,11 +187,132 @@ void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
// hase no header // header
// TODO: data segment // data
createData<command_data>(); // data
}
/**
* @brief command_data::iStream
* @param stream
*/
void command_data::iStream(ACN::PDU::Stream stream)
{
auto buffer = std::vector<uint8_t>();
buffer.push_back(RDM::SC_RDM);
while (stream->good())
buffer.push_back(stream->readType<uint8_t>());
message.read(buffer);
}
/**
* @brief command_data::oStream
* @param stream
*/
void command_data::oStream(ACN::PDU::Stream stream) const
{
auto buffer = std::vector<uint8_t>();
message.write(buffer);
for (size_t i = 1; i < buffer.size(); i++ )
*stream << buffer.at(i);
}
} // namespace COMMAND
/**
* @brief RPT::Pdu::Pdu
*/
Pdu::Pdu()
: RDMnet::Pdu(4)
{
}
/**
* @brief RPT::Pdu::iStream
* @param stream
*/
void Pdu::iStream(ACN::PDU::Stream stream)
{
RDMnet::Pdu::iStream(stream); // flags, length, and vector
createHeader<rpt_header>(); // header
createData<rpt_data>(); // data
// rpt_data::iStream doesn't know the vector, so cannot instantiate
// the PDU. Do that now.
if (!flags_.hasData)
return;
auto data = static_cast<rpt_data*>(data_);
switch (vector())
{
case VECTOR_RPT_REQUEST:
data->pdu = std::shared_ptr<REQUEST::Pdu>(new REQUEST::Pdu());
break;
case VECTOR_RPT_STATUS:
data->pdu = std::shared_ptr<STATUS::Pdu>(new STATUS::Pdu());
break;
case VECTOR_RPT_NOTIFICATION:
data->pdu = std::shared_ptr<NOTIFICATION::Pdu>(new NOTIFICATION::Pdu());
break;
default:
return;
}
data->pdu->iStream(stream_);
}
/**
* @brief rpt_header::iStream
* @param stream
*/
void rpt_header::iStream(ACN::PDU::Stream stream)
{
*stream >> source;
*stream >> source_endpoint;
*stream >> destination;
*stream >> destination_endpoint;
}
/**
* @brief rpt_header::oStream
* @param stream
*/
void rpt_header::oStream(ACN::PDU::Stream stream) const
{
*stream << source;
*stream << source_endpoint;
*stream << destination;
*stream << destination_endpoint;
}
/**
* @brief rpt_data::iStream
* @param stream
*/
void rpt_data::iStream(ACN::PDU::Stream stream)
{
*stream >> sequence;
*stream >> reserved;
// NOTE: PDU not created here. Do it in PDU iStream();
}
/**
* @brief rpt_data::oStream
* @param stream
*/
void rpt_data::oStream(ACN::PDU::Stream stream) const
{
*stream << sequence;
stream->writeType<typeof(reserved)>(0);
pdu->oStream(stream);
}
} // namespace RPT
} // namespace RDMnet

View File

@ -25,6 +25,7 @@
#include "pdu.h"
#include "config.h"
#include "rdm/message.h"
#include "rdm/uid.h"
namespace RDMnet {
@ -50,18 +51,6 @@ namespace RPT {
static const RDM::UID DynamicUidRequest = RDM::UID(0, MY_ESTA_MANUFACTURER_ID,
true);
/**
* @brief The RPT::Pdu class
*/
class Pdu
: public RDMnet::Pdu
{
public:
Pdu();
void iStream(ACN::PDU::Stream) override;
};
namespace REQUEST {
/**
@ -77,6 +66,7 @@ public:
} // namespace REQUEST
namespace STATUS {
/**
@ -90,8 +80,23 @@ public:
void iStream(ACN::PDU::Stream) override;
};
/**
* @brief 7.5.3.1.3 Status String
*/
struct status_string_data
: ACN::PDU::pdu_data
{
std::string status_string;
size_t streamSize() const override;
void iStream(ACN::PDU::Stream) override;
void oStream(ACN::PDU::Stream) const override;
};
} // namespace STATUS
namespace NOTIFICATION {
/**
@ -105,6 +110,7 @@ public:
void iStream(ACN::PDU::Stream) override;
};
} // namespace NOTIFICATION
@ -121,7 +127,61 @@ public:
void iStream(ACN::PDU::Stream) override;
};
struct command_data
: public ACN::PDU::pdu_data
{
RDM::Message message;
size_t streamSize() const override { return 23 + message.length(); }
void iStream(ACN::PDU::Stream) override;
void oStream(ACN::PDU::Stream) const override;
};
} // namespace COMMAND
/**
* @brief 7.5.1 RPT PDU
*/
class Pdu
: public RDMnet::Pdu
{
public:
Pdu();
void iStream(ACN::PDU::Stream) override;
};
struct rpt_header
: ACN::PDU::pdu_header
{
RDM::UID source;
uint16_t source_endpoint;
RDM::UID destination;
uint16_t destination_endpoint;
size_t streamSize() const override { return 16; }
void iStream(ACN::PDU::Stream) override;
void oStream(ACN::PDU::Stream) const override;
};
struct rpt_data
: ACN::PDU::pdu_data
{
uint32_t sequence;
uint8_t reserved;
std::shared_ptr<RDMnet::Pdu> pdu;
size_t streamSize() const override { return 5 + pdu->streamSize(); }
void iStream(ACN::PDU::Stream) override;
void oStream(ACN::PDU::Stream) const override;
};
} // namespace RPT
} // namespace RDMnet