304 lines
8.0 KiB
C++
304 lines
8.0 KiB
C++
/*
|
|
dmp/component.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 "component.h"
|
|
|
|
namespace ACN::DMP {
|
|
|
|
/**
|
|
* @brief Component::Component
|
|
* @param uuid
|
|
* @param fctn
|
|
*/
|
|
Component::Component(UUID::uuid uuid, std::string fctn)
|
|
: ACN::Component(uuid, fctn)
|
|
, last_address_used(0)
|
|
{
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::addDmpSender
|
|
* @param function
|
|
*/
|
|
void Component::addDmpSender(PDU::Handler<DMP::Pdu> function)
|
|
{
|
|
dmp_senders_.push_back(function);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::DmpReceiver
|
|
* @param block
|
|
*/
|
|
void Component::DmpReceiver(std::shared_ptr<ACN::PDU::Block<Pdu>> block)
|
|
{
|
|
/// \cite DMP 5.1.2 Relative Addresses
|
|
///
|
|
/// Relative addresses are used to specify an address as an offset from the
|
|
/// most recently used address within the same PDU Block.
|
|
last_address_used = 0;
|
|
|
|
for(auto const &message : *block->pdu)
|
|
{
|
|
switch (message->vector())
|
|
{
|
|
case GET_PROPERTY:
|
|
rxDmpGetProperty(message);
|
|
break;
|
|
case SET_PROPERTY:
|
|
rxDmpSetProperty(message);
|
|
break;
|
|
case GET_PROPERTY_REPLY:
|
|
rxDmpGetPropertyReply(message);
|
|
break;
|
|
case EVENT:
|
|
rxDmpEvent(message);
|
|
break;
|
|
case SUBSCRIBE:
|
|
rxDmpSubscribe(message);
|
|
break;
|
|
case UNSUBSCRIBE:
|
|
rxDmpUnsubscribe(message);
|
|
break;
|
|
case GET_PROPERTY_FAIL:
|
|
rxDmpGetPropertyFail(message);
|
|
break;
|
|
case SET_PROPERTY_FAIL:
|
|
rxDmpSetPropertyFail(message);
|
|
break;
|
|
case SUBSCRIBE_ACCEPT:
|
|
rxDmpSubscribeAccept(message);
|
|
break;
|
|
case SUBSCRIBE_REJECT:
|
|
rxDmpSubscribeReject(message);
|
|
break;
|
|
case SYNC_EVENT:
|
|
rxDmpSyncEvent(message);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::sendMessage
|
|
* @param message
|
|
*/
|
|
void Component::sendDMP(PDU::Message<DMP::Pdu> message) const
|
|
{
|
|
for( const auto & sender : dmp_senders_)
|
|
sender(message);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpGetProperty
|
|
* @param message
|
|
*
|
|
* The base class behavior is to reply with GET PROPERTY FAIL : Not a Property.
|
|
*
|
|
* \todo Find a way to test this.
|
|
*/
|
|
void Component::rxDmpGetProperty(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
auto reply = std::make_shared<DMP::Pdu>();
|
|
reply->setVector(GET_PROPERTY_FAIL);
|
|
reply->setHeader(message->header());
|
|
auto addr_type = std::static_pointer_cast<address_type>(reply->header());
|
|
reply->setData(std::make_shared<address_pair_list>(*addr_type));
|
|
auto list_in = std::static_pointer_cast<ACN::DMP::address_list>(message->data());
|
|
auto list_out = std::static_pointer_cast<ACN::DMP::address_pair_list>(reply->data());
|
|
auto reason = std::vector<uint8_t>(NOT_PROPERTY);
|
|
for (const auto & range_in : list_in->addresses)
|
|
{
|
|
Range range_out(range_in.getAddressType());
|
|
range_out.address = range_in.address;
|
|
range_out.count = 1;
|
|
range_out.incriment = 1;
|
|
list_out->properties.push_back(address_data_pair(range_out, reason));
|
|
}
|
|
sendDMP(reply);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpSetProperty
|
|
* @param message
|
|
*
|
|
* The base class behavior is to reply with SET PROPERTY FAIL : Not a Property.
|
|
*
|
|
* \todo Find a way to test this.
|
|
*/
|
|
void Component::rxDmpSetProperty(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
auto reply = std::make_shared<DMP::Pdu>();
|
|
reply->setVector(SET_PROPERTY_FAIL);
|
|
reply->setHeader(message->header());
|
|
auto addr_type = std::static_pointer_cast<address_type>(reply->header());
|
|
reply->setData(std::make_shared<address_pair_list>(*addr_type));
|
|
auto list_in = std::static_pointer_cast<ACN::DMP::address_pair_list>(message->data());
|
|
auto list_out = std::static_pointer_cast<ACN::DMP::address_pair_list>(reply->data());
|
|
auto reason = std::vector<uint8_t>(NOT_PROPERTY);
|
|
for (const auto & [range_in, _] : list_in->properties)
|
|
{
|
|
Range range_out(range_in.getAddressType());
|
|
range_out.address = range_in.address;
|
|
range_out.count = 1;
|
|
range_out.incriment = 1;
|
|
list_out->properties.push_back(address_data_pair(range_out, reason));
|
|
}
|
|
sendDMP(reply);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpGetPropertyReply
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the reply.
|
|
*/
|
|
void Component::rxDmpGetPropertyReply(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpEvent
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the event.
|
|
*/
|
|
void Component::rxDmpEvent(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpSubscribe
|
|
* @param message
|
|
*
|
|
* The base class behavior is to send SUBSCRIBE REJECTED : Not a Property.
|
|
*
|
|
* \todo Find a way to test this.
|
|
*/
|
|
void Component::rxDmpSubscribe(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
auto reply = std::make_shared<DMP::Pdu>();
|
|
reply->setVector(SUBSCRIBE_REJECT);
|
|
reply->setHeader(message->header());
|
|
auto addr_type = std::static_pointer_cast<address_type>(reply->header());
|
|
reply->setData(std::make_shared<address_pair_list>(*addr_type));
|
|
auto list_in = std::static_pointer_cast<ACN::DMP::address_list>(message->data());
|
|
auto list_out = std::static_pointer_cast<ACN::DMP::address_pair_list>(reply->data());
|
|
auto reason = std::vector<uint8_t>(NOT_PROPERTY);
|
|
for (const auto & range_in : list_in->addresses)
|
|
{
|
|
Range range_out(range_in.getAddressType());
|
|
range_out.address = range_in.address;
|
|
range_out.count = 1;
|
|
range_out.incriment = 1;
|
|
list_out->properties.push_back(address_data_pair(range_out, reason));
|
|
}
|
|
sendDMP(reply);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpUnsubscribe
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the message.
|
|
*/
|
|
void Component::rxDmpUnsubscribe(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpGetPropertyFail
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the message.
|
|
*/
|
|
void Component::rxDmpGetPropertyFail(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpSetPropertyFail
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the message.
|
|
*/
|
|
void Component::rxDmpSetPropertyFail(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpSubscribeAccept
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the message.
|
|
*/
|
|
void Component::rxDmpSubscribeAccept(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpSubscribeReject
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the message.
|
|
*/
|
|
void Component::rxDmpSubscribeReject(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Component::rxDmpSyncEvent
|
|
* @param message
|
|
*
|
|
* The base class behavior is to ignore the message.
|
|
*/
|
|
void Component::rxDmpSyncEvent(PDU::Message<DMP::Pdu> message)
|
|
{
|
|
(void)message;
|
|
}
|
|
|
|
|
|
} // namespace ACN::DMP
|