2021-05-27 10:59:22 -04:00
/*
dmp . h
Copyright ( c ) 2020 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 <cstdint>
# include <memory>
# include <vector>
2021-08-24 18:10:20 -04:00
# include "acn/pdu.h"
2021-05-27 10:59:22 -04:00
// Architecture for Control Networks – Device Management Protocol
2021-08-24 18:10:20 -04:00
namespace ACN : : DMP {
2021-05-27 10:59:22 -04:00
2021-07-30 09:11:32 -04:00
/**
* @ brief 5.1 .4 Address and Data Types
*/
2021-05-27 10:59:22 -04:00
enum data_type {
2021-08-15 21:43:36 -04:00
SINGLE = 0 b00 , //!< Non-range address, Single data item
RANGE = 0 b01 , //!< Range address, Single data item
ARRAY = 0 b10 , //!< Range address, Array of equal size data items
SERIES = 0 b11 //!< Range address, Series of mixed size data items
2021-05-27 10:59:22 -04:00
} ;
2021-07-30 09:11:32 -04:00
/**
* @ brief The address_length enum
*/
2021-05-27 10:59:22 -04:00
enum address_length {
ONE = 0 b00 , // 0
TWO = 0 b01 , // 1
FOUR = 0 b10 , // 2
ZERO = 0 b11 // 3 (reserved)
} ;
2021-07-30 09:11:32 -04:00
2021-08-15 21:43:36 -04:00
/**
* @ brief address_width
* @ param l
* @ return
*/
inline unsigned int address_width ( const address_length & l )
{
switch ( l ) {
case ONE : return 1 ;
case TWO : return 2 ;
case FOUR : return 4 ;
default : return 0 ;
}
}
2021-07-30 09:11:32 -04:00
/**
* @ brief The address_type struct
*/
2021-08-15 21:43:36 -04:00
struct address_type
: PDU : : pdu_header
{
union {
uint8_t byte = 0 ;
struct __attribute__ ( ( packed ) ) {
address_length width : 2 ; // A1, A0
uint8_t x_reserved : 2 ; // X1, X0
data_type type : 2 ; // D1, D0
bool relative : 1 ; // R
bool z_reserved : 1 ; // Z
} ;
} ;
size_t streamSize ( ) const override { return 1 ; }
void iStream ( PDU : : Stream s ) override { * s > > byte ; }
void oStream ( PDU : : Stream s ) const override { * s < < byte ; }
2021-05-27 10:59:22 -04:00
} ;
2021-07-30 09:11:32 -04:00
/**
* @ brief 5.1 .5 The range struct
*/
2021-08-26 11:54:08 -04:00
/// \todo maybe template this struct based on address_length
2021-08-15 21:43:36 -04:00
struct range
: PDU : : pdu_stream_object
{
2021-08-25 17:20:33 -04:00
/**
* @ brief range
* @ param t
* @ param l
*/
2021-08-15 21:43:36 -04:00
range ( const data_type t , const address_length l )
: type_ ( t )
, length_ ( l )
{ } ;
2021-08-25 17:20:33 -04:00
uint32_t address = 0 ; //!< start address
uint32_t incriment = 0 ; //!< property size (number of octets)
uint32_t count = 0 ; //!< number of properties
2021-08-15 21:43:36 -04:00
size_t streamSize ( ) const override ;
void iStream ( PDU : : Stream ) override ;
void oStream ( PDU : : Stream ) const override ;
2021-05-27 10:59:22 -04:00
private :
2021-08-15 21:43:36 -04:00
const data_type type_ ;
const address_length length_ ;
uint32_t read_ ( PDU : : Stream ) ;
void write_ ( PDU : : Stream , const uint32_t & ) const ;
2021-05-27 10:59:22 -04:00
} ;
2021-07-30 09:11:32 -04:00
/**
* @ brief set_property
*/
2021-08-15 21:43:36 -04:00
typedef std : : pair < range , std : : vector < uint8_t > > address_data_pair ;
2021-07-30 09:11:32 -04:00
/**
2021-08-15 21:43:36 -04:00
* @ brief The address_pair_list struct
2021-07-30 09:11:32 -04:00
*/
2021-08-15 21:43:36 -04:00
struct address_pair_list
: PDU : : pdu_data
{
2021-08-25 17:20:33 -04:00
/**
* @ brief address_pair_list
* @ param t
*/
2021-08-15 21:43:36 -04:00
address_pair_list ( const address_type * t ) : type_ ( t ) { } ;
2021-08-25 17:20:33 -04:00
std : : vector < address_data_pair > properties ; //!< list of address/data pairs
2021-08-15 21:43:36 -04:00
2021-07-29 23:40:46 -04:00
size_t streamSize ( ) const override ;
2021-08-15 21:43:36 -04:00
void iStream ( PDU : : Stream ) override ;
void oStream ( PDU : : Stream ) const override ;
private :
const address_type * type_ ;
} ;
/**
* @ brief The address_list struct
*/
struct address_list
: PDU : : pdu_data
{
2021-08-25 17:20:33 -04:00
/**
* @ brief address_list
* @ param t
*/
2021-08-15 21:43:36 -04:00
address_list ( const address_type * t ) : type_ ( t ) { } ;
2021-08-25 17:20:33 -04:00
std : : vector < range > addresses ; //!< list of addresses
2021-08-15 21:43:36 -04:00
size_t streamSize ( ) const override ;
void iStream ( PDU : : Stream ) override ;
void oStream ( PDU : : Stream ) const override ;
private :
const address_type * type_ ;
2021-05-27 10:59:22 -04:00
} ;
2021-07-30 09:11:32 -04:00
/**
* @ brief 7 Response Messages
*/
2021-05-27 10:59:22 -04:00
enum failure_reason {
2021-08-15 21:43:36 -04:00
NONSPECIFIC = 1 , //!< Non-specific or non-DMP reason.
NOT_PROPERTY = 2 , //!< The address does not correspond to a property.
WRITE_ONLY = 3 , //!< The property’ s value may not be read.
NOT_WRITABLE = 4 , //!< The property’ s value may not be written.
DATA_ERROR = 5 , //!< The data does not correspond to the property.
SUBSCIRPTION_NOT_SUPPORTED = 10 , //!< Subscriptions on the specified property are not supported by the device.
NO_SUBSCRIPTIONS_SUPPORTED = 11 , //!< Subscriptions not supported on any property.
INSUFFICIENT_RESOURCES = 12 , //!< The component cannot support more subscriptions due to resource limitations
UNAVAILABLE = 13 //!< The property’ s value is not available due to restrictions imposed by device specific functionality (e.g., access permission mechanisms).
2021-05-27 10:59:22 -04:00
} ;
2021-07-30 09:11:32 -04:00
/**
* @ brief 13.1 Protocol Codes
*/
2021-08-15 21:43:36 -04:00
static const uint32_t DMP_PROTOCOL_ID = 2 ; //!< protocol vector
2021-05-27 10:59:22 -04:00
// 13.2 Message Codes
static const uint8_t GET_PROPERTY = 1 ;
static const uint8_t SET_PROPERTY = 2 ;
static const uint8_t GET_PROPERTY_REPLY = 3 ;
static const uint8_t EVENT = 4 ;
static const uint8_t SUBSCRIBE = 7 ;
static const uint8_t UNSUBSCRIBE = 8 ;
static const uint8_t GET_PROPERTY_FAIL = 9 ;
static const uint8_t SET_PROPERTY_FAIL = 10 ;
static const uint8_t SUBSCRIBE_ACCEPT = 12 ;
static const uint8_t SUBSCRIBE_REJECT = 13 ;
static const uint8_t SYNC_EVENT = 17 ;
2021-07-30 09:11:32 -04:00
/**
* @ brief The DMP : : Pdu class
*/
2021-05-27 10:59:22 -04:00
class Pdu
: public PDU : : Pdu
{
public :
2021-07-29 19:26:49 -04:00
Pdu ( ) ;
void iStream ( PDU : : Stream ) override ;
2021-05-27 10:59:22 -04:00
} ;
2021-08-24 18:10:20 -04:00
} // ACN::DMP