diff --git a/bacnet-stack/BACnet-stack.doxyfile b/bacnet-stack/BACnet-stack.doxyfile index b6186ad5..bfa46a29 100644 --- a/bacnet-stack/BACnet-stack.doxyfile +++ b/bacnet-stack/BACnet-stack.doxyfile @@ -506,7 +506,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = src demo/server ports/linux demo/handler include +INPUT = include src demo/server ports/linux demo/handler demo/object # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c index b187b36c..ddeb767d 100644 --- a/bacnet-stack/demo/object/device.c +++ b/bacnet-stack/demo/object/device.c @@ -74,7 +74,15 @@ static int Device_Read_Property_Local( static bool Device_Write_Property_Local( BACNET_WRITE_PROPERTY_DATA * wp_data); -/* all object helper functions */ +/** Defines the group of object helper functions for any supported Object. + * @ingroup ObjHelpers + * Each Object must provide some implementation of each of these helpers + * in order to properly support the handlers. Eg, the ReadProperty handler + * handler_read_property() relies on the instance of Object_Read_Property + * for each Object type. + * In both appearance and operation, this group of functions acts like + * they are member functions of a C++ Object base class. + */ static struct object_functions { BACNET_OBJECT_TYPE Object_Type; object_init_function Object_Init; @@ -223,6 +231,13 @@ static struct object_functions { {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL} }; +/** Glue function to let the Device object, when called by a handler, + * lookup which Object type needs to be invoked. + * @ingroup ObjHelpers + * @param Object_Type [in] The type of BACnet Object the handler wants to access. + * @return Pointer to the group of object helper functions that implement this + * type of Object. + */ static struct object_functions * Device_Objects_Find_Functions( BACNET_OBJECT_TYPE Object_Type) { @@ -241,8 +256,15 @@ static struct object_functions * Device_Objects_Find_Functions( return(NULL); } -/* Try and find an rr_info_function for the requested object type */ - +/** Try to find a rr_info_function helper function for the requested object type. + * @ingroup ObjIntf + * + * @param object_type [in] The type of BACnet Object the handler wants to access. + * @return Pointer to the object helper function that implements the + * ReadRangeInfo function, Object_RR_Info, for this type of Object on + * success, else a NULL pointer if the type of Object isn't supported + * or doesn't have a ReadRangeInfo function. + */ rr_info_function Device_Objects_RR_Info( BACNET_OBJECT_TYPE object_type) @@ -268,7 +290,17 @@ static unsigned property_list_count( return property_count; } -/* for a given object type, returns the special property list */ +/** For a given object type, returns the special property list. + * This function is used for ReadPropertyMultiple calls which want + * just Required, just Optional, or All properties. + * @ingroup ObjIntf + * + * @param object_type [in] The desired BACNET_OBJECT_TYPE whose properties + * are to be listed. + * @param pPropertyList [out] Reference to the structure which will, on return, + * list, separately, the Required, Optional, and Proprietary object + * properties with their counts. + */ void Device_Objects_Property_List( BACNET_OBJECT_TYPE object_type, struct special_property_list_t *pPropertyList) @@ -305,6 +337,19 @@ void Device_Objects_Property_List( return; } +/** Commands a Device re-initialization, to a given state. + * The request's password must match for the operation to succeed. + * This implementation provides a framework, but doesn't + * actually *DO* anything. + * @note You could use a mix of states and passwords to multiple outcomes. + * @note You probably want to restart *after* the simple ack has been sent + * from the return handler, so just set a local flag here. + * @ingroup ObjIntf + * + * @param rd_data [in,out] The information from the RD request. + * On failure, the error class and code will be set. + * @return True if succeeds (password is correct), else False. + */ bool Device_Reinitialize( BACNET_REINITIALIZE_DEVICE_DATA *rd_data) { @@ -470,6 +515,13 @@ uint32_t Device_Index_To_Instance( } /* methods to manipulate the data */ + +/** Return the Object Instance number for our (single) Device Object. + * This is a key function, widely invoked by the handler code, since + * it provides "our" (ie, local) address. + * @ingroup ObjIntf + * @return The Instance number used in the BACNET_OBJECT_ID for the Device. + */ uint32_t Device_Object_Instance_Number( void) { @@ -613,6 +665,10 @@ const char *Device_Vendor_Name( return Vendor_Name; } +/** Returns the Vendor ID for this Device. + * See the assignments at http://www.bacnet.org/VendorID/BACnet%20Vendor%20IDs.htm + * @return The Vendor ID of this Device. + */ uint16_t Device_Vendor_Identifier( void) { @@ -811,6 +867,14 @@ bool Device_Object_List_Identifier( return status; } +/** Determine if we have an object with the given object_name. + * If the object_type and object_instance pointers are not null, + * and the lookup succeeds, they will be given the resulting values. + * @param object_name [in] The desired Object Name to look for. + * @param object_type [out] The BACNET_OBJECT_TYPE of the matching Object. + * @param object_instance [out] The object instance number of the matching Object. + * @return True on success or else False if not found. + */ bool Device_Valid_Object_Name( const char *object_name, int *object_type, @@ -844,7 +908,11 @@ bool Device_Valid_Object_Name( return found; } -/* returns the name or NULL if not found */ +/** Determine if we have an object of this type and instance number. + * @param object_type [in] The desired BACNET_OBJECT_TYPE + * @param object_instance [in] The object instance number to be looked up. + * @return The Object Name or else NULL if not found + */ char *Device_Valid_Object_Id( int object_type, uint32_t object_instance) @@ -1166,8 +1234,14 @@ static int Device_Read_Property_Local( return apdu_len; } -/* Encodes the property APDU and returns the length, - or sets the error, and returns -1 */ +/** Looks up the requested Object and Property, and encodes its Value in an APDU. + * @ingroup ObjIntf + * If the Object or Property can't be found, sets the error class and code. + * + * @param rpdata [in,out] Structure with the desired Object and Property info + * on entry, and APDU message on return. + * @return The length of the APDU on success, else -1 + */ int Device_Read_Property( BACNET_READ_PROPERTY_DATA *rpdata) { @@ -1280,7 +1354,7 @@ static bool Device_Write_Property_Local( break; case PROP_OBJECT_NAME: status = WPValidateString(&value, - MAX_DEV_LOC_LEN, + MAX_DEV_NAME_LEN, false, &wp_data->error_class, &wp_data->error_code); @@ -1362,6 +1436,15 @@ static bool Device_Write_Property_Local( return status; } +/** Looks up the requested Object and Property, and set the new Value in it, + * if allowed. + * If the Object or Property can't be found, sets the error class and code. + * @ingroup ObjIntf + * + * @param wp_data [in,out] Structure with the desired Object and Property info + * and new Value on entry, and APDU message on return. + * @return True on success, else False if there is an error. + */ bool Device_Write_Property( BACNET_WRITE_PROPERTY_DATA * wp_data) { @@ -1390,9 +1473,13 @@ bool Device_Write_Property( wp_data->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; } - return apdu_len; + return ( ( apdu_len > 0 ) ? true : false ); } + +/** Initialize the Device Object and each of its child Object instances. + * @ingroup ObjIntf + */ void Device_Init( void) { diff --git a/bacnet-stack/include/device.h b/bacnet-stack/include/device.h index 7c3d142e..76930d74 100644 --- a/bacnet-stack/include/device.h +++ b/bacnet-stack/include/device.h @@ -48,12 +48,15 @@ #include "rpm.h" #include "readrange.h" -/** Called so a BACnet object can perform any necessary initialization. */ +/** Called so a BACnet object can perform any necessary initialization. + * @ingroup ObjHelpers + */ typedef void ( *object_init_function) ( void); /** Counts the number of objects of this type. + * @ingroup ObjHelpers * @return Count of implemented objects of this type. */ typedef unsigned ( @@ -61,6 +64,7 @@ typedef unsigned ( void); /** Maps an object index position to its corresponding BACnet object instance number. + * @ingroup ObjHelpers * @param index [in] The index of the object, in the array of objects of its type. * @return The BACnet object instance number to be used in a BACNET_OBJECT_ID. */ @@ -70,6 +74,7 @@ typedef uint32_t( unsigned index); /** Provides the BACnet Object_Name for a given object instance of this type. + * @ingroup ObjHelpers * @param [in] The object instance number to be looked up. * @return Pointer to a string containing the unique Object_Name. This string * is temporary and should be copied upon the return. It is @@ -82,6 +87,7 @@ typedef char *( /** Look in the table of objects of this type, and see if this is a valid * instance number. + * @ingroup ObjHelpers * @param [in] The object instance number to be looked up. * @return True if the object instance refers to a valid object of this type. */ @@ -212,4 +218,39 @@ extern "C" { #ifdef __cplusplus } #endif /* __cplusplus */ + +/** @defgroup ObjFrmwk Object Framework + * The modules in this section describe the BACnet-stack's framework for + * BACnet-defined Objects (Device, Analog Input, etc). There are two submodules + * to describe this arrangement: + * - The "object helper functions" which provide C++-like common functionality + * to all supported object types. + * - The interface between the implemented Objects and the BAC-stack services, + * specifically the handlers, which are mediated through function calls to + * the Device object. + */ + +/** @defgroup ObjHelpers Object Helper Functions + * @ingroup ObjFrmwk + * This section describes the function templates for the helper functions that + * provide common object support. + */ + +/** @defgroup ObjIntf Handler-to-Object Interface Functions + * @ingroup ObjFrmwk + * This section describes the fairly limited set of functions that link the + * BAC-stack handlers to the BACnet Object instances. All of these calls are + * situated in the Device Object, which "knows" how to reach its child Objects. + * + * Most of these calls have a common operation: + * -# Call Device_Objects_Find_Functions( for the desired Object_Type ) + * - Gets a pointer to the object_functions for this Type of Object. + * -# Call the Object's Object_Valid_Instance( for the desired object_instance ) + * to make sure there is such an instance. + * -# Call the Object helper function needed by the handler, + * eg Object_Read_Property() for the RP handler. + * + */ + + #endif diff --git a/bacnet-stack/include/readrange.h b/bacnet-stack/include/readrange.h index c6fa103c..04749970 100644 --- a/bacnet-stack/include/readrange.h +++ b/bacnet-stack/include/readrange.h @@ -125,6 +125,8 @@ typedef struct rrpropertyinfo { } RR_PROP_INFO; /** Function template for ReadRange information retrieval function. + * A function template; @see device.c for assignment to object types. + * @ingroup ObjHelpers * @param pRequest [in] Info on the request. * @param pInfo [out] Where to write the response to. * @return True on success, False on error or failure. diff --git a/bacnet-stack/include/rp.h b/bacnet-stack/include/rp.h index ae76da54..5bfc52a7 100644 --- a/bacnet-stack/include/rp.h +++ b/bacnet-stack/include/rp.h @@ -52,6 +52,7 @@ typedef struct BACnet_Read_Property_Data { /** Reads one property for this object type of a given instance. * A function template; @see device.c for assignment to object types. + * @ingroup ObjHelpers * * @param rp_data [in] Pointer to the BACnet_Read_Property_Data structure, * which is packed with the information from the RP request. diff --git a/bacnet-stack/include/rpm.h b/bacnet-stack/include/rpm.h index 8182d044..6c2aaf33 100644 --- a/bacnet-stack/include/rpm.h +++ b/bacnet-stack/include/rpm.h @@ -52,6 +52,7 @@ typedef struct BACnet_Read_Access_Data { /** Fetches the lists of properties (array of BACNET_PROPERTY_ID's) for this * object type, grouped by Required, Optional, and Proprietary. * A function template; @see device.c for assignment to object types. + * @ingroup ObjHelpers * * @param pRequired [out] Pointer reference for the list of Required properties. * @param pOptional [out] Pointer reference for the list of Optional properties. diff --git a/bacnet-stack/include/wp.h b/bacnet-stack/include/wp.h index 32da35e0..b2ce2a02 100644 --- a/bacnet-stack/include/wp.h +++ b/bacnet-stack/include/wp.h @@ -58,6 +58,7 @@ typedef struct BACnet_Write_Property_Data { /** Attempts to write a new value to one property for this object type * of a given instance. * A function template; @see device.c for assignment to object types. + * @ingroup ObjHelpers * * @param wp_data [in] Pointer to the BACnet_Write_Property_Data structure, * which is packed with the information from the WP request.