2022-06-08 16:05:06 -04:00
|
|
|
|
/*
|
|
|
|
|
packet.cpp
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2022 Kevin Matz (kevin.matz@gmail.com)
|
|
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
|
SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "packet.h"
|
2022-11-28 15:57:52 -05:00
|
|
|
|
#include "dmx.h"
|
2023-04-02 13:24:26 -04:00
|
|
|
|
|
|
|
|
|
#include <cstring>
|
2022-06-08 16:05:06 -04:00
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
namespace ARTNET {
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void poll_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
*stream >> talk_to_me._raw; // 5
|
|
|
|
|
diagnostic_level = static_cast<Priority>(stream->get()); // 6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void poll_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
*stream << talk_to_me._raw; // 5
|
|
|
|
|
*stream << diagnostic_level; // 6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief ArtPollReply::set_report
|
|
|
|
|
* @param code
|
|
|
|
|
* @param count
|
|
|
|
|
* @param text
|
|
|
|
|
*/
|
|
|
|
|
void pollreply_data::set_report(NodeReport code, uint count, std::string text)
|
|
|
|
|
{
|
|
|
|
|
std::ostringstream report;
|
|
|
|
|
std::ostringstream codestr;
|
|
|
|
|
|
|
|
|
|
codestr << "#";
|
|
|
|
|
codestr.width(4);
|
|
|
|
|
codestr.fill('0');
|
|
|
|
|
codestr << std::ios::hex << code;
|
|
|
|
|
|
|
|
|
|
report << codestr.str();
|
|
|
|
|
report << " ";
|
|
|
|
|
report << count;
|
|
|
|
|
report << " ";
|
|
|
|
|
report << text;
|
|
|
|
|
|
|
|
|
|
_node_report = report.str();
|
|
|
|
|
_node_report.resize(Node_Report_Length - 1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void pollreply_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
*stream >> my_ip; // 3
|
|
|
|
|
*stream >> udp_port; // 4
|
|
|
|
|
version = stream->get() << 8 | // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
net_sub_switch.value = stream->get() << 8 | // 7
|
|
|
|
|
stream->get() << 4; // 8
|
|
|
|
|
oem.word = stream->get() << 8 | // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
*stream >> ubea_version; // 11
|
|
|
|
|
*stream >> status._raw1; // 12
|
|
|
|
|
esta_manufacturer = stream->get() | // 13
|
|
|
|
|
stream->get() << 8; // 14
|
|
|
|
|
stream->readString(short_name, Short_Name_Length); // 15
|
|
|
|
|
stream->readString(long_name, Long_Name_Length); // 16
|
|
|
|
|
stream->readString(_node_report, Node_Report_Length); // 17
|
|
|
|
|
num_ports = stream->get() << 8 | // 18
|
|
|
|
|
stream->get(); // 19
|
|
|
|
|
for( size_t i = 0; i < sizeof(port_types) / sizeof(PortTypes); i++)
|
|
|
|
|
*stream >> port_types[i]._raw; // 20
|
|
|
|
|
for( size_t i = 0; i < sizeof(good_input) / sizeof(GoodInput); i++)
|
|
|
|
|
*stream >> good_input[i]._raw; // 21
|
|
|
|
|
for( size_t i = 0; i < sizeof(good_output) / sizeof(GoodOutput); i++)
|
|
|
|
|
*stream >> good_output[i]._rawA; // 22
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwIn); i++)
|
|
|
|
|
SwIn[i] = stream->get() & 0x0f; // 23
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwOut); i++)
|
|
|
|
|
SwOut[i] = stream->get() & 0x0f; // 24
|
|
|
|
|
*stream >> SwVideo; // 25
|
|
|
|
|
*stream >> SwMacro._raw; // 26
|
|
|
|
|
*stream >> SwRemote._raw; // 27
|
|
|
|
|
stream->get(); // 28
|
|
|
|
|
stream->get(); // 29
|
|
|
|
|
stream->get(); // 30
|
|
|
|
|
style = static_cast<Style>(stream->get()); // 31
|
|
|
|
|
for( size_t i = sizeof(mac_address); i > 0; i--)
|
|
|
|
|
*stream >> mac_address[i-1]; // 32-37
|
|
|
|
|
*stream >> bind_ip; // 38
|
|
|
|
|
*stream >> bind_index; // 39
|
|
|
|
|
*stream >> status._raw2; // 40
|
|
|
|
|
*stream >> good_output->_rawB; // 41
|
|
|
|
|
*stream >> status._raw3; // 42
|
|
|
|
|
for( size_t i = 0; i < _filler_length; i++)
|
|
|
|
|
stream->get(); // 43
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void pollreply_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
*stream << my_ip; // 3
|
|
|
|
|
*stream << udp_port; // 4
|
|
|
|
|
stream->put(version >> 8); // 5
|
|
|
|
|
stream->put(version & 0xff); // 6
|
|
|
|
|
stream->put(net_sub_switch.value >> 8); // 7
|
|
|
|
|
stream->put(net_sub_switch.value >> 4 & 0x0f); // 8
|
|
|
|
|
stream->put(oem.word >> 8); // 9
|
|
|
|
|
stream->put(oem.word & 0xff); // 10
|
|
|
|
|
*stream << ubea_version; // 11
|
|
|
|
|
*stream << status._raw1; // 12
|
|
|
|
|
stream->put(esta_manufacturer & 0xff); // 13
|
|
|
|
|
stream->put(esta_manufacturer >> 8); // 14
|
|
|
|
|
stream->writeString(short_name, Short_Name_Length, true); // 15
|
|
|
|
|
stream->writeString(long_name, Long_Name_Length, true); // 16
|
|
|
|
|
stream->writeString(_node_report, Node_Report_Length, true); // 17
|
|
|
|
|
stream->put(num_ports >> 8); // 18
|
|
|
|
|
stream->put(num_ports & 0xff); // 19
|
|
|
|
|
for( size_t i = 0; i < sizeof(port_types) / sizeof(PortTypes); i++)
|
|
|
|
|
*stream << port_types[i]._raw; // 20
|
|
|
|
|
for( size_t i = 0; i < sizeof(good_input) / sizeof(GoodInput); i++)
|
|
|
|
|
*stream << good_input[i]._raw; // 21
|
|
|
|
|
for( size_t i = 0; i < sizeof(good_output) / sizeof(GoodOutput); i++)
|
|
|
|
|
*stream << good_output[i]._rawA; // 22
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwIn); i++)
|
|
|
|
|
stream->put(SwIn[i] &0x0f); // 23
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwOut); i++)
|
|
|
|
|
stream->put(SwOut[i] &0x0f); // 24
|
|
|
|
|
*stream << SwVideo; // 25
|
|
|
|
|
*stream << SwMacro._raw; // 26
|
|
|
|
|
*stream << SwRemote._raw; // 27
|
|
|
|
|
stream->put(0); // 28
|
|
|
|
|
stream->put(0); // 29
|
|
|
|
|
stream->put(0); // 30
|
|
|
|
|
*stream << style; // 31
|
|
|
|
|
for( size_t i = sizeof(mac_address); i > 0; i--)
|
|
|
|
|
*stream << mac_address[i-1]; // 32-37
|
|
|
|
|
*stream << bind_ip; // 38
|
|
|
|
|
*stream << bind_index; // 39
|
|
|
|
|
*stream << status._raw2; // 40
|
|
|
|
|
*stream << good_output->_rawB; // 41
|
|
|
|
|
*stream << status._raw3; // 42
|
|
|
|
|
for( size_t i = 0; i < _filler_length; i++)
|
|
|
|
|
stream->put(0); // 43
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void ipprog_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
*stream >> command._raw; // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
*stream >> ip_address; // 9-12
|
|
|
|
|
*stream >> subnet_mask; // 13-16
|
|
|
|
|
*stream >> udp_port; // 17-18
|
|
|
|
|
stream->ignore(_spare_length); // 19
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void ipprog_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
*stream << command._raw; // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
*stream << ip_address; // 9-12
|
|
|
|
|
*stream << subnet_mask; // 13-16
|
|
|
|
|
*stream << udp_port; // 17-18
|
|
|
|
|
for( size_t i = 0; i < _spare_length; i++)
|
|
|
|
|
stream->put(0); // 19
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void ipprogreply_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
stream->get(); // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
*stream >> ip_address; // 9-12
|
|
|
|
|
*stream >> subnet_mask; // 13-16
|
|
|
|
|
*stream >> udp_port; // 17-18
|
|
|
|
|
*stream >> status._raw; // 19
|
|
|
|
|
stream->ignore(_spare_length); // 20-26
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void ipprogreply_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
stream->put(0); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
*stream << ip_address; // 9-12
|
|
|
|
|
*stream << subnet_mask; // 13-16
|
|
|
|
|
*stream << udp_port; // 17-18
|
|
|
|
|
*stream << status._raw; // 19
|
|
|
|
|
for( size_t i = 0; i < _spare_length; i++)
|
|
|
|
|
stream->put(0); // 20-26
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void address_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
net_sub_switch.value = stream->get() << 8; // 5
|
|
|
|
|
*stream >> bind_index; // 6
|
|
|
|
|
stream->readString(short_name, Short_Name_Length); // 7
|
|
|
|
|
stream->readString(long_name, Long_Name_Length); // 8
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwIn); i++)
|
|
|
|
|
SwIn[i] = stream->get() & 0x0f; // 9
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwOut); i++)
|
|
|
|
|
SwOut[i] = stream->get() & 0x0f; // 10
|
|
|
|
|
net_sub_switch.value |= stream->get() << 4; // 11
|
|
|
|
|
*stream >> SwVideo; // 12
|
|
|
|
|
command = static_cast<AddressCommand>(stream->get()); // 13
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void address_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(net_sub_switch.value >> 8); // 5
|
|
|
|
|
*stream << bind_index; // 6
|
|
|
|
|
stream->writeString(short_name, Short_Name_Length, true); // 7
|
|
|
|
|
stream->writeString(long_name, Long_Name_Length, true); // 8
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwIn); i++)
|
|
|
|
|
stream->put(SwIn[i] &0x0f); // 9
|
|
|
|
|
for( size_t i = 0; i < sizeof(SwOut); i++)
|
|
|
|
|
stream->put(SwOut[i] &0x0f); // 10
|
|
|
|
|
stream->put(net_sub_switch.value >> 4 & 0x0f); // 11
|
|
|
|
|
*stream << SwVideo; // 12
|
|
|
|
|
*stream << command; // 13
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void diagdata_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
priority = static_cast<Priority>(stream->get()); // 6
|
|
|
|
|
stream->get(); // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
uint16_t length = stream->get() << 8 | // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
stream->readString(data, length); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void diagdata_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
*stream << priority; // 6
|
|
|
|
|
stream->put(0); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
uint16_t length = data.length() + 1; // include null terminator
|
|
|
|
|
if ( length > _max_data_length )
|
|
|
|
|
length = _max_data_length;
|
|
|
|
|
stream->put(length >> 8); // 9
|
|
|
|
|
stream->put(length & 0xff); // 10
|
|
|
|
|
stream->writeString(data, length, true); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void timecode_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
*stream >> time.frame; // 7
|
|
|
|
|
*stream >> time.seconds; // 8
|
|
|
|
|
*stream >> time.minutes; // 9
|
|
|
|
|
*stream >> time.hours; // 10
|
|
|
|
|
time.type = static_cast<TimecodeType>(stream->get()); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void timecode_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
*stream << time.frame; // 7
|
|
|
|
|
*stream << time.seconds; // 8
|
|
|
|
|
*stream << time.minutes; // 9
|
|
|
|
|
*stream << time.hours; // 10
|
|
|
|
|
*stream << time.type; // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void command_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->put(esta_manufacturer & 0xff); // 5
|
|
|
|
|
stream->put(esta_manufacturer >> 8); // 6
|
|
|
|
|
uint16_t length = stream->get() << 8 | // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
stream->readString(data, length); // 9
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void command_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(esta_manufacturer & 0xff); // 5
|
|
|
|
|
stream->put(esta_manufacturer >> 8); // 6
|
|
|
|
|
uint16_t length = data.length() + 1; // include null terminator
|
|
|
|
|
if ( length > _max_data_length )
|
|
|
|
|
length = _max_data_length;
|
|
|
|
|
stream->put(length >> 8); // 7
|
|
|
|
|
stream->put(length & 0xff); // 8
|
|
|
|
|
stream->writeString(data, length, true); // 9
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void trigger_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
oem.word = stream->get() << 8 | // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
*stream >> key; // 9
|
|
|
|
|
*stream >> subkey; // 10
|
|
|
|
|
stream->read(data, sizeof(data)); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void trigger_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
stream->put(oem.word >> 8); // 7
|
|
|
|
|
stream->put(oem.word & 0xff); // 8
|
|
|
|
|
*stream << key; // 9
|
|
|
|
|
*stream << subkey; // 10
|
|
|
|
|
stream->write(data, sizeof(data)); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void dmx_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
*stream >> sequence; // 5
|
|
|
|
|
*stream >> physical; // 6
|
|
|
|
|
*stream >> universe.subuni; // 7
|
|
|
|
|
*stream >> universe._net; // 8
|
|
|
|
|
uint16_t length = stream->get() << 8 | // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
// this value should be an even number in the range 2 – 512
|
|
|
|
|
if ( length % 2 != 0 ||
|
|
|
|
|
length < 2 ||
|
|
|
|
|
length > DMX::E111_LAST_SLOT )
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
data.reserve(length + 1);
|
|
|
|
|
for (int i = 1; i <= length; i++)
|
|
|
|
|
data.push_back(stream->get()); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void dmx_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
*stream << sequence; // 5
|
|
|
|
|
*stream << physical; // 6
|
|
|
|
|
*stream << universe.subuni; // 7
|
|
|
|
|
*stream << universe.net; // 8
|
|
|
|
|
uint16_t length = data.size() - 1;
|
|
|
|
|
uint16_t datalength = length + (length % 2);
|
|
|
|
|
stream->put(datalength >> 8); // 9
|
|
|
|
|
stream->put(datalength & 0xff ); // 10
|
|
|
|
|
for (int i = 1; i <= length; i++)
|
|
|
|
|
stream->put(data.at(i)); // 11
|
|
|
|
|
for (int i = 0; i < length % 2; i++)
|
|
|
|
|
stream->put(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void sync_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void sync_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void nzs_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
*stream >> sequence; // 5
|
|
|
|
|
data.clear();
|
|
|
|
|
data.push_back(stream->get()); // 6
|
|
|
|
|
*stream >> universe.subuni; // 7
|
|
|
|
|
*stream >> universe._net; // 8
|
|
|
|
|
uint16_t length = stream->get() << 8 | // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
// this value should be an even number in the range 1 – 512
|
|
|
|
|
if (length < 1 ||
|
|
|
|
|
length > DMX::E111_LAST_SLOT )
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
data.reserve(length + 1);
|
|
|
|
|
for (int i = 1; i <= length; i++)
|
|
|
|
|
data.push_back(stream->get()); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void nzs_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
*stream << sequence; // 5
|
|
|
|
|
*stream << data.at(0); // 6
|
|
|
|
|
*stream << universe.subuni; // 7
|
|
|
|
|
*stream << universe.net; // 8
|
|
|
|
|
uint16_t length = data.size() - 1;
|
|
|
|
|
stream->put(length >> 8); // 9
|
|
|
|
|
stream->put(length & 0xff ); // 10
|
|
|
|
|
for (int i = 1; i <= length; i++)
|
|
|
|
|
stream->put(data.at(i)); // 11
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool vlc_data::_from_nzs(const nzs_data * other)
|
|
|
|
|
{ // Field #
|
|
|
|
|
version = other->version;
|
|
|
|
|
sequence = other->sequence;
|
|
|
|
|
universe = other->universe;
|
|
|
|
|
if (other->data.size() < 11) // enough data to read the payload length
|
|
|
|
|
return false;
|
|
|
|
|
if (other->data[0] != VLC::START_CODE ||
|
|
|
|
|
other->data[1] != VLC::MagicNumber[0] || // 11
|
|
|
|
|
other->data[2] != VLC::MagicNumber[1] || // 12
|
|
|
|
|
other->data[3] != VLC::MagicNumber[2]) // 13
|
|
|
|
|
return false;
|
|
|
|
|
flags._raw = other->data[4]; // 14
|
|
|
|
|
transaction = other->data[5] << 8 | // 15
|
|
|
|
|
other->data[6]; // 16
|
|
|
|
|
address = other->data[7] << 8 | // 17
|
|
|
|
|
other->data[8]; // 18
|
|
|
|
|
size_t length = other->data[9] << 8 | // 19
|
|
|
|
|
other->data[10]; // 20
|
|
|
|
|
if (other->data.size() < 23 + length ||
|
|
|
|
|
length > _payload_max_length)
|
|
|
|
|
return false;
|
|
|
|
|
uint16_t cksm = other->data[11] << 8 | // 21
|
|
|
|
|
other->data[12]; // 22
|
|
|
|
|
// skip unlucky other->data[13] // 23
|
|
|
|
|
depth = other->data[14]; // 24
|
|
|
|
|
frequency = other->data[15] << 8 | // 25
|
|
|
|
|
other->data[16]; // 26
|
|
|
|
|
modulation = other->data[17] << 8 | // 27
|
|
|
|
|
other->data[18]; // 28
|
|
|
|
|
language = other->data[19] << 8 | // 29
|
|
|
|
|
other->data[20]; // 30
|
|
|
|
|
beacon_frequency = other->data[21] << 8 | // 31
|
|
|
|
|
other->data[22]; // 32
|
|
|
|
|
for (size_t i = 0; i < length; i++)
|
|
|
|
|
payload.push_back(other->data[23+i]); // 33
|
|
|
|
|
if (cksm != _checksum())
|
|
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void vlc_data::compile()
|
|
|
|
|
{ // Field #
|
|
|
|
|
data.insert(data.end(), // 11-13
|
|
|
|
|
std::begin(VLC::MagicNumber), std::end(VLC::MagicNumber));
|
|
|
|
|
data.push_back(flags._raw); // 14
|
|
|
|
|
data.push_back(transaction >> 8); // 15
|
|
|
|
|
data.push_back(transaction & 0xff); // 16
|
|
|
|
|
data.push_back(address >> 8); // 17
|
|
|
|
|
data.push_back(address & 0xff); // 18
|
|
|
|
|
uint16_t length = payload.size();
|
|
|
|
|
data.push_back(length >> 8); // 19
|
|
|
|
|
data.push_back(length & 0xff); // 20
|
|
|
|
|
uint16_t chksum = _checksum();
|
|
|
|
|
data.push_back(chksum >> 8); // 21
|
|
|
|
|
data.push_back(chksum & 0xff); // 22
|
|
|
|
|
data.push_back(0); // 23
|
|
|
|
|
data.push_back(depth); // 24
|
|
|
|
|
data.push_back(frequency >> 8); // 25
|
|
|
|
|
data.push_back(frequency & 0xff); // 26
|
|
|
|
|
data.push_back(modulation >> 8); // 27
|
|
|
|
|
data.push_back(modulation & 0xff); // 28
|
|
|
|
|
data.push_back(language >> 8); // 29
|
|
|
|
|
data.push_back(language & 0xff); // 30
|
|
|
|
|
data.push_back(beacon_frequency >> 8); // 31
|
|
|
|
|
data.push_back(beacon_frequency & 0xff); // 32
|
|
|
|
|
data.insert(data.end(), payload.begin(), payload.end()); // 33
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint16_t vlc_data::_checksum() const
|
|
|
|
|
{
|
|
|
|
|
/// \todo impliment the real checksum!
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void input_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
*stream >> bind_index; // 6
|
|
|
|
|
num_ports = stream->get() << 8 | // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
for (size_t i = 0; i < (sizeof(status) / sizeof(InputFlags)); i++)
|
|
|
|
|
*stream >> status[i]._raw; // 9
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void input_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
*stream << bind_index; // 6
|
|
|
|
|
stream->put(num_ports >> 8); // 7
|
|
|
|
|
stream->put(num_ports & 0xff); // 8
|
|
|
|
|
for (size_t i = 0; i < (sizeof(status) / sizeof(InputFlags)); i++)
|
|
|
|
|
*stream << status[i]._raw; // 9
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void firmwaremaster_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
type = static_cast<FIRMWARE::MasterType>(stream->get()); // 7
|
|
|
|
|
*stream >> block_id; // 8
|
|
|
|
|
length = stream->get() << 24 | // 9
|
|
|
|
|
stream->get() << 16 | // 10
|
|
|
|
|
stream->get() << 8 | // 11
|
|
|
|
|
stream->get(); // 12
|
|
|
|
|
stream->ignore(_spare_length); // 13
|
|
|
|
|
for (size_t i = 0; i < sizeof(block) / sizeof(block[0]); i++)
|
|
|
|
|
*stream >> block[i]; // 14
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void firmwaremaster_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
*stream << type; // 7
|
|
|
|
|
*stream << block_id; // 8
|
|
|
|
|
stream->put((length >> 24) & 0xff); // 9
|
|
|
|
|
stream->put((length >> 16) & 0xff); // 10
|
|
|
|
|
stream->put((length >> 8) & 0xff); // 11
|
|
|
|
|
stream->put(length & 0xff); // 12
|
|
|
|
|
for (size_t i = 0; i < _spare_length; i++)
|
|
|
|
|
stream->put(0); // 13
|
|
|
|
|
for (size_t i = 0; i < sizeof(block); i++)
|
|
|
|
|
*stream << block[i]; // 14
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void firmwarereply_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
type = static_cast<FIRMWARE::ResponseType>(stream->get()); // 7
|
|
|
|
|
stream->ignore(_spare_length); // 8
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void firmwarereply_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
*stream << type; // 7
|
|
|
|
|
for (size_t i = 0; i < _spare_length; i++)
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void todrequest_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
stream->get(); // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
stream->get(); // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
stream->get(); // 11
|
|
|
|
|
stream->get(); // 12
|
|
|
|
|
stream->get(); // 13
|
|
|
|
|
uint8_t net = stream->get(); // 14
|
|
|
|
|
if ( stream->get() != RDM::TodFull) // 15
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
uint8_t count = stream->get(); // 16
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
universes.emplace_back(net, stream->get()); // 17
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void todrequest_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
stream->put(0); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
stream->put(0); // 9
|
|
|
|
|
stream->put(0); // 10
|
|
|
|
|
stream->put(0); // 11
|
|
|
|
|
stream->put(0); // 12
|
|
|
|
|
stream->put(0); // 13
|
|
|
|
|
stream->put(universes.empty() ? 0 : universes[0].net); // 14
|
|
|
|
|
stream->put(RDM::TodFull); // 15
|
|
|
|
|
stream->put(universes.size() < _max_count ? universes.size() : _max_count); // 16
|
|
|
|
|
for (size_t i = 0; i < universes.size() && i < _max_count; i++ )
|
|
|
|
|
stream->put(universes[i].subuni); // 17
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void toddata_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
rdm_version = static_cast<RDM::Version>(stream->get()); // 5
|
|
|
|
|
*stream >> port; // 6
|
|
|
|
|
stream->get(); // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
stream->get(); // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
stream->get(); // 11
|
|
|
|
|
stream->get(); // 12
|
|
|
|
|
*stream >> bind_index; // 13
|
|
|
|
|
*stream >> universe._net; // 14
|
|
|
|
|
type = static_cast<RDM::TodCommandResponse>(stream->get()); // 15
|
|
|
|
|
*stream >> universe.subuni; // 16
|
|
|
|
|
*stream >> total_count; // 17-18
|
|
|
|
|
*stream >> block_count; // 19
|
|
|
|
|
uint8_t count = stream->get(); // 20
|
|
|
|
|
uint16_t manufacturer;
|
|
|
|
|
uint32_t device;
|
|
|
|
|
for (int i = 0; i < count; i++) // 21
|
|
|
|
|
{
|
|
|
|
|
*stream >> manufacturer;
|
|
|
|
|
*stream >> device;
|
|
|
|
|
devices.emplace_back(std::make_shared<::RDM::UID>(device, manufacturer));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void toddata_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(rdm_version); // 5
|
|
|
|
|
*stream << port; // 6
|
|
|
|
|
stream->put(0); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
stream->put(0); // 9
|
|
|
|
|
stream->put(0); // 10
|
|
|
|
|
stream->put(0); // 11
|
|
|
|
|
stream->put(0); // 12
|
|
|
|
|
*stream << bind_index; // 13
|
|
|
|
|
*stream << universe.net; // 14
|
|
|
|
|
*stream << type; // 15
|
|
|
|
|
*stream << universe.subuni; // 16
|
|
|
|
|
*stream << total_count; // 17-18
|
|
|
|
|
*stream << block_count; // 19
|
|
|
|
|
stream->put(devices.size()); // 20
|
|
|
|
|
for (size_t i = 0; i < devices.size(); i++) { // 21
|
|
|
|
|
auto uid = devices.at(i)->uid();
|
|
|
|
|
stream->put((uid >> 40) & 0xff);
|
|
|
|
|
stream->put((uid >> 32) & 0xff);
|
|
|
|
|
stream->put((uid >> 24) & 0xff);
|
|
|
|
|
stream->put((uid >> 16) & 0xff);
|
|
|
|
|
stream->put((uid >> 8) & 0xff);
|
|
|
|
|
stream->put(uid & 0xff);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void todcontrol_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
stream->get(); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
stream->get(); // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
stream->get(); // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
stream->get(); // 11
|
|
|
|
|
stream->get(); // 12
|
|
|
|
|
stream->get(); // 13
|
|
|
|
|
*stream >> universe._net; // 14
|
|
|
|
|
command = static_cast<RDM::TodControlCommand>(stream->get()); // 15
|
|
|
|
|
*stream >> universe.subuni; // 16
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void todcontrol_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
stream->put(0); // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
stream->put(0); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
stream->put(0); // 9
|
|
|
|
|
stream->put(0); // 10
|
|
|
|
|
stream->put(0); // 11
|
|
|
|
|
stream->put(0); // 12
|
|
|
|
|
stream->put(0); // 13
|
|
|
|
|
*stream << universe.net; // 14
|
|
|
|
|
*stream << command; // 15
|
|
|
|
|
*stream << universe.subuni; // 16
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void rdm_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
rdm_version = static_cast<RDM::Version>(stream->get()); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
stream->get(); // 7
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
stream->get(); // 9
|
|
|
|
|
stream->get(); // 10
|
|
|
|
|
stream->get(); // 11
|
|
|
|
|
stream->get(); // 12
|
|
|
|
|
stream->get(); // 13
|
|
|
|
|
*stream >> universe._net; // 14
|
|
|
|
|
command = static_cast<RDM::RdmCommand>(stream->get()); // 15
|
|
|
|
|
*stream >> universe.subuni; // 16
|
|
|
|
|
data.reserve(stream->available() + 1);
|
2023-05-18 14:39:05 -04:00
|
|
|
|
while (stream->available())
|
2022-06-08 16:05:06 -04:00
|
|
|
|
data.push_back(stream->get()); // 17
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void rdm_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
*stream << rdm_version; // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
stream->put(0); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
stream->put(0); // 9
|
|
|
|
|
stream->put(0); // 10
|
|
|
|
|
stream->put(0); // 11
|
|
|
|
|
stream->put(0); // 12
|
|
|
|
|
stream->put(0); // 13
|
|
|
|
|
*stream << universe.net; // 14
|
|
|
|
|
*stream << command; // 15
|
|
|
|
|
*stream << universe.subuni; // 16
|
|
|
|
|
for (size_t i = 1; i < data.size(); i++)
|
|
|
|
|
*stream << data[i]; // 17
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void rdmsub_data::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
version = stream->get() << 8 | // 3
|
|
|
|
|
stream->get(); // 4
|
|
|
|
|
if (version < VERSION)
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
rdm_version = static_cast<RDM::Version>(stream->get()); // 5
|
|
|
|
|
stream->get(); // 6
|
|
|
|
|
auto manufacturer = stream->readType<uint16_t>(); // 7
|
|
|
|
|
auto device = stream->readType<uint32_t>(); // 7
|
|
|
|
|
uid = ::RDM::UID(device, manufacturer);
|
|
|
|
|
stream->get(); // 8
|
|
|
|
|
*stream >> command_class; // 9
|
|
|
|
|
*stream >> pid; // 10
|
|
|
|
|
*stream >> subdevice; // 11
|
|
|
|
|
auto count = stream->readType<uint16_t>(); // 12
|
|
|
|
|
stream->get(); // 13
|
|
|
|
|
stream->get(); // 14
|
|
|
|
|
stream->get(); // 15
|
|
|
|
|
stream->get(); // 16
|
|
|
|
|
if (command_class == ::RDM::SET_COMMAND ||
|
|
|
|
|
command_class == ::RDM::GET_COMMAND_RESPONSE)
|
|
|
|
|
for (uint i = 0; i < count; i++)
|
|
|
|
|
data.push_back(stream->readType<uint16_t>()); // 17
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void rdmsub_data::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{ // Field #
|
|
|
|
|
stream->put(version >> 8); // 3
|
|
|
|
|
stream->put(version & 0xff); // 4
|
|
|
|
|
*stream << rdm_version; // 5
|
|
|
|
|
stream->put(0); // 6
|
|
|
|
|
auto uid_number = uid.uid();
|
|
|
|
|
stream->put((uid_number >> 40) & 0xff); // 7
|
|
|
|
|
stream->put((uid_number >> 32) & 0xff); // 7
|
|
|
|
|
stream->put((uid_number >> 24) & 0xff); // 7
|
|
|
|
|
stream->put((uid_number >> 16) & 0xff); // 7
|
|
|
|
|
stream->put((uid_number >> 8) & 0xff); // 7
|
|
|
|
|
stream->put(uid_number & 0xff); // 7
|
|
|
|
|
stream->put(0); // 8
|
|
|
|
|
*stream << command_class; // 9
|
|
|
|
|
*stream << pid; // 10
|
|
|
|
|
*stream << subdevice; // 11
|
|
|
|
|
if (command_class == ::RDM::GET_COMMAND ||
|
|
|
|
|
command_class == ::RDM::SET_COMMAND_RESPONSE ||
|
|
|
|
|
data.empty())
|
|
|
|
|
*stream << (uint16_t)1; // 12
|
|
|
|
|
else
|
|
|
|
|
*stream << (uint16_t)data.size(); // 12
|
|
|
|
|
stream->put(0); // 13
|
|
|
|
|
stream->put(0); // 14
|
|
|
|
|
stream->put(0); // 15
|
|
|
|
|
stream->put(0); // 16
|
|
|
|
|
if (command_class == ::RDM::SET_COMMAND ||
|
|
|
|
|
command_class == ::RDM::GET_COMMAND_RESPONSE)
|
|
|
|
|
for (uint i = 0; i < data.size(); i++)
|
|
|
|
|
*stream << data[i]; // 17
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief packet::streamSize
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
size_t Packet::streamSize() const
|
|
|
|
|
{
|
|
|
|
|
return sizeof(PACKET_IDENTIFIER)
|
|
|
|
|
+ sizeof(OpCode)
|
|
|
|
|
+ _data->streamSize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief packet::iStream
|
|
|
|
|
*
|
|
|
|
|
* Read a packet from the network.
|
|
|
|
|
*
|
|
|
|
|
* @param stream
|
|
|
|
|
*/
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void Packet::iStream(std::shared_ptr<bufferstream> stream)
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{
|
|
|
|
|
uint8_t identifier[sizeof(PACKET_IDENTIFIER)]; //!< 'A''r''t''-''N''e''t'0x00
|
|
|
|
|
// Field #
|
|
|
|
|
stream->read(identifier, sizeof(identifier)); // 1
|
|
|
|
|
if (stream->gcount() != sizeof(identifier))
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
if (memcmp(identifier, PACKET_IDENTIFIER, sizeof(identifier))) // memcmp returns 0 if matched
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
|
|
|
|
|
OpCode opcode = static_cast<OpCode>(stream->readType<uint16_t>()); // 2
|
|
|
|
|
|
|
|
|
|
switch (opcode) { // 3-...
|
|
|
|
|
case OpPoll:
|
|
|
|
|
createData<poll_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpPollReply:
|
|
|
|
|
createData<pollreply_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpIpProg:
|
|
|
|
|
createData<ipprog_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpIpProgReply:
|
|
|
|
|
createData<ipprogreply_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpAddress:
|
|
|
|
|
createData<address_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpDiagData:
|
|
|
|
|
createData<diagdata_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpTimeCode:
|
|
|
|
|
createData<timecode_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpCommand:
|
|
|
|
|
createData<command_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpTrigger:
|
|
|
|
|
createData<trigger_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpDmx:
|
|
|
|
|
createData<dmx_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpSync:
|
|
|
|
|
createData<sync_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpNzs:
|
|
|
|
|
{
|
|
|
|
|
createData<nzs_data>(stream);
|
|
|
|
|
if (!_data)
|
|
|
|
|
break;
|
|
|
|
|
#ifdef RTTI_ENABLED
|
|
|
|
|
auto data = std::dynamic_pointer_cast<nzs_data>(_data);
|
|
|
|
|
#else
|
|
|
|
|
auto data = std::static_pointer_cast<nzs_data>(_data);
|
|
|
|
|
#endif
|
|
|
|
|
if (data->data[0] == VLC::START_CODE)
|
|
|
|
|
_data = std::make_shared<vlc_data>(data.get());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case OpInput:
|
|
|
|
|
createData<input_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpFirmwareMaster:
|
|
|
|
|
createData<firmwaremaster_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpFirmwareReply:
|
|
|
|
|
createData<firmwarereply_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpTodRequest:
|
|
|
|
|
createData<todrequest_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpTodData:
|
|
|
|
|
createData<toddata_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpTodControl:
|
|
|
|
|
createData<todcontrol_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpRdm:
|
|
|
|
|
createData<rdm_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
case OpRdmSub:
|
|
|
|
|
createData<rdmsub_data>(stream);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief packet::oStream
|
|
|
|
|
*
|
|
|
|
|
* Write a packet to the network.
|
|
|
|
|
*
|
|
|
|
|
* @param stream
|
|
|
|
|
*/
|
2023-04-02 13:24:26 -04:00
|
|
|
|
void Packet::oStream(std::shared_ptr<bufferstream> stream) const
|
2022-06-08 16:05:06 -04:00
|
|
|
|
{
|
|
|
|
|
if ( _opcode == OpNull )
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
if ( _data == nullptr )
|
|
|
|
|
return stream->setstate(std::ios_base::failbit);
|
|
|
|
|
// Field #
|
|
|
|
|
stream->write(PACKET_IDENTIFIER, sizeof(PACKET_IDENTIFIER)); // 1
|
|
|
|
|
*stream << _opcode; // 2
|
|
|
|
|
*stream << _data; // 3-...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace ARTNET
|