/* broker-protocol.h Copyright (c) 2021 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. */ #pragma once #include "pdu.h" #include "rdm/uid.h" #include "uuid/uuid.h" namespace RDMnet::BrokerProtocol { /** * @brief 1.2.2 Broker Protocol * * The Broker Protocol enables the scalability and multi-controller * functionality of RDMnet. It uses a central server called a Broker to handle * discovery, maintain the state of the system and facilitate message routing. * The Broker routes messages between a set of other Components, which are * referred to as Clients. The Broker Protocol contains a small set of messages * that facilitate Client connection and discovery of other Clients. */ namespace ClientEntry { /** * @brief The ClientEntry::Pdu class */ class Pdu : public RDMnet::Pdu { public: Pdu(); void iStream(ACN::PDU::Stream) override; }; /** * @brief The ClientEntry::header struct */ struct entry_header : ACN::PDU::pdu_header { UUID::uuid cid; //!< Component's UUID size_t streamSize() const override; void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief The ClientEntry::RptClientEntry_data struct */ struct entry_rpt_data : ACN::PDU::pdu_data { RDM::UID client_uid; //!< client RDM UID uint8_t client_type; //!< client type identifier UUID::uuid binding_cid; //!< UUID to bind size_t streamSize() const override { return 23; } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief The ClientEntry::EptClientEntry_data struct */ struct entry_ept_data : ACN::PDU::pdu_data { std::vector subprotocol_list; //!< list of sub-protocols size_t streamSize() const override { return subprotocol_list.size(); } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; } // namespace CLientEntry /** * @brief The BrokerProtocol::Pdu class */ class Pdu : public RDMnet::Pdu { public: Pdu(); void iStream(ACN::PDU::Stream) override; }; /** * @brief The connection_flags union */ union connection_flags { uint8_t byte; //!< packed byte struct { bool incrementalUpdates : 1; //!< incremental updates uint8_t flags_reserved : 7; //!< Brokers shall ignore. }__attribute__((packed)); }; /** * @brief 6.3.1.2 Client Connect */ struct client_connect_data : ACN::PDU::pdu_data { std::string clientScope; //!< scope of the client uint16_t version; //!< version std::string searchDomain; //!< search domain connection_flags flags; //!< connection flags ACN::PDU::Message pdu; //!< client entry PDU size_t streamSize() const override { return 297 + pdu->streamSize(); } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.3 Connect Reply */ struct connect_reply_data : ACN::PDU::pdu_data { uint16_t code; //!< reply code uint16_t version; //!< version RDM::UID broker_uid; //!< broker's UID RDM::UID client_uid; //!< client's UID size_t streamSize() const override { return 16; } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.4 Client Entry Update */ struct client_entry_update_data : ACN::PDU::pdu_data { connection_flags flags; //!< connection flags ACN::PDU::Message pdu; //!< client entry PDU size_t streamSize() const override { return 1 + pdu->streamSize(); } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.5 Client Redirect IPv4 */ struct client_redirect_ipv4_data : ACN::PDU::pdu_data { uint32_t ip; //!< IP address uint16_t port; //!< Port size_t streamSize() const override { return 6; } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.6 Client Redirect IPv6 */ struct client_redirect_ipv6_data : ACN::PDU::pdu_data { uint8_t ip[16]; //!< IP address uint16_t port; //!< Port size_t streamSize() const override { return 18; } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief The dynamic_uid_request struct */ struct dynamic_uid_request : ACN::PDU::pdu_stream_object { RDM::UID uid; //!< UID UUID::uuid rid; //!< UUID size_t streamSize() const override { return 22; } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.12 Request Dynamic UID Assignment */ struct request_dynamic_uid_data : ACN::PDU::pdu_data { std::vector list; //!< dynamic UIDs size_t streamSize() const override { return 22 * list.size(); } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief The dynamic_uid_mapping struct */ struct dynamic_uid_mapping : ACN::PDU::pdu_stream_object { RDM::UID uid; //!< UID UUID::uuid rid; //!< UUID uint16_t status; //!< status size_t streamSize() const override { return 24; } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.13 Dynamic UID Assignment List */ struct dynamic_uid_assignment_data : ACN::PDU::pdu_data { std::vector list; //!< dynamic mappings size_t streamSize() const override { return 24 * list.size(); } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.14 Fetch Dynamic UID Assignment List */ struct fetch_dynamcic_assignment_data : ACN::PDU::pdu_data { std::vector list; //!< list of UID size_t streamSize() const override { return 6 * list.size(); } void iStream(ACN::PDU::Stream) override; void oStream(ACN::PDU::Stream) const override; }; /** * @brief 6.3.1.15 Client Disconnect */ struct disconnect_data : ACN::PDU::pdu_data { uint16_t reason; //!< reason code size_t streamSize() const override { return 2; } void iStream(ACN::PDU::Stream s) override { *s >> reason; } void oStream(ACN::PDU::Stream s) const override { *s << reason; }; }; } // namespace RDMnet::BrokerProtocol