From 17b556df696a7b21134d71c11d7c81ef2617454e Mon Sep 17 00:00:00 2001 From: skarg Date: Mon, 3 Mar 2008 15:09:47 +0000 Subject: [PATCH] Created module for holding object properties in a list. --- bacnet-stack/demo/handler/objects.c | 201 ++++++++++++++++++++++++++++ bacnet-stack/include/objects.h | 92 +++++++++++++ 2 files changed, 293 insertions(+) create mode 100644 bacnet-stack/demo/handler/objects.c create mode 100644 bacnet-stack/include/objects.h diff --git a/bacnet-stack/demo/handler/objects.c b/bacnet-stack/demo/handler/objects.c new file mode 100644 index 00000000..ef0c0e35 --- /dev/null +++ b/bacnet-stack/demo/handler/objects.c @@ -0,0 +1,201 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include +#include +#include +#include +#include "keylist.h" +#include "objects.h" + +/* list of devices */ +static OS_Keylist Device_List = NULL; + +void objects_init(void) +{ + if (!Device_List) + Device_List = Keylist_Create(); +} + +int objects_device_count(void) +{ + objects_init(); + return Keylist_Count(Device_List); +} + +OBJECT_DEVICE_T *objects_device_data(int index) +{ + objects_init(); + return Keylist_Data_Index(Device_List, index); +} + +OBJECT_DEVICE_T *objects_device_by_instance(uint32_t device_instance) +{ + objects_init(); + return Keylist_Data(Device_List, device_instance); +} + +OBJECT_DEVICE_T *objects_device_new(uint32_t device_instance) +{ + OBJECT_DEVICE_T *pDevice = NULL; + KEY key = device_instance; + + if (Device_List) { + /* does this device already exist? */ + pDevice = Keylist_Data(Device_List, key); + if (pDevice) { + memset(pDevice, 0, sizeof(OBJECT_DEVICE_T)); + } else { + pDevice = calloc(1, sizeof(OBJECT_DEVICE_T)); + if (pDevice) { + pDevice->Object_Identifier.type = OBJECT_DEVICE; + pDevice->Object_Identifier.instance = device_instance; + pDevice->Object_Type = OBJECT_DEVICE; + pDevice->Object_List = Keylist_Create(); + Keylist_Data_Add(Device_List, key, pDevice); + } else { + fprintf(stderr,"Objects: Unable to allocate device %d buffer\n", + device_instance); + } + } + } + + return pDevice; +} + +OBJECT_DEVICE_T *objects_device_delete(int index) +{ + OBJECT_DEVICE_T *pDevice = NULL; + BACNET_OBJECT_ID *pObject; + + if (Device_List) { + pDevice = Keylist_Data_Delete_By_Index(Device_List, index); + if (pDevice) { + fprintf(stderr,"Objects: removing device %d", + pDevice->Object_Identifier.instance); + if (pDevice->Object_List) { + do { + pObject = + Keylist_Data_Delete_By_Index(pDevice->Object_List,0); + /* free any dynamic memory used */ + if (pObject) { + free(pObject); + } + } while (pObject); + Keylist_Delete(pDevice->Object_List); + } + free(pDevice); + } + } + return pDevice; +} + +#ifdef TEST +#include +#include + +#include "ctest.h" + +/* test the object creation and deletion */ +void testBACnetObjectsCompare( + Test * pTest, + OBJECT_DEVICE_T *pDevice, + uint32_t device_id) +{ + ct_test(pTest, pDevice != NULL); + if (pDevice) { + ct_test(pTest, pDevice->Object_List != NULL); + ct_test(pTest, pDevice->Object_Identifier.instance == device_id); + ct_test(pTest, pDevice->Object_Identifier.type == OBJECT_DEVICE); + ct_test(pTest, pDevice->Object_Type == OBJECT_DEVICE); + } +} + +void testBACnetObjects( + Test * pTest) +{ + uint32_t device_id = 0; + unsigned test_point = 0; + const unsigned max_test_points = 20; + OBJECT_DEVICE_T *pDevice; + + for (test_point = 0;test_point < max_test_points;test_point++) { + device_id = test_point * (BACNET_MAX_INSTANCE/max_test_points); + pDevice = objects_device_new(device_id); + testBACnetObjectsCompare(pTest, pDevice, device_id); + pDevice = objects_device_by_instance(device_id); + testBACnetObjectsCompare(pTest, pDevice, device_id); + } + ct_test(pTest, max_test_points == objects_device_count()); + for (test_point = 0;test_point < max_test_points;test_point++) { + device_id = test_point * (BACNET_MAX_INSTANCE/max_test_points); + pDevice = objects_device_by_instance(device_id); + testBACnetObjectsCompare(pTest, pDevice, device_id); + } + for (test_point = 0;test_point < max_test_points;test_point++) { + device_id = test_point * (BACNET_MAX_INSTANCE/max_test_points); + pDevice = objects_device_data(test_point); + testBACnetObjectsCompare( + pTest, + pDevice, + Keylist_Key(Device_List, test_point)); + } + for (test_point = 0;test_point < max_test_points;test_point++) { + pDevice = objects_device_delete(0); + } +} + +#ifdef TEST_OBJECT_LIST +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Objects", NULL); + + /* individual tests */ + rc = ct_addTestFunction(pTest, testBACnetObjects); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + + ct_destroy(pTest); + + return 0; +} +#endif +#endif diff --git a/bacnet-stack/include/objects.h b/bacnet-stack/include/objects.h new file mode 100644 index 00000000..7a47a083 --- /dev/null +++ b/bacnet-stack/include/objects.h @@ -0,0 +1,92 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#ifndef OBJECTS_H +#define OBJECTS_H + +#include +#include +#include +#include "bacdef.h" +#include "bacstr.h" +#include "bacenum.h" + +typedef union BACnetScale_t { + float Float; + int32_t Integer; +} BACNET_SCALE_T; + +/* structures to hold the data gotten by ReadProperty from the device */ +typedef struct object_accumulator_t { + BACNET_OBJECT_ID Object_Identifier; + BACNET_CHARACTER_STRING Object_Name; + BACNET_OBJECT_TYPE Object_Type; + uint32_t Present_Value; + BACNET_STATUS_FLAGS Status_Flags; + BACNET_EVENT_STATE Event_State; + bool Out_Of_Service; + BACNET_SCALE_T Scale; + BACNET_ENGINEERING_UNITS Units; + uint32_t Max_Pres_Value; +} OBJECT_ACCUMULATOR_T; + +typedef struct object_device_t { + BACNET_OBJECT_ID Object_Identifier; + BACNET_CHARACTER_STRING Object_Name; + BACNET_OBJECT_TYPE Object_Type; + BACNET_DEVICE_STATUS System_Status; + BACNET_CHARACTER_STRING Vendor_Name; + uint16_t Vendor_Identifier; + BACNET_CHARACTER_STRING Model_Name; + BACNET_CHARACTER_STRING Firmware_Revision; + BACNET_CHARACTER_STRING Application_Software_Version; + BACNET_CHARACTER_STRING Location; + BACNET_CHARACTER_STRING Description; + uint8_t Protocol_Version; + uint8_t Protocol_Revision; + BACNET_BIT_STRING Protocol_Services_Supported; + BACNET_BIT_STRING Protocol_Object_Types_Supported; + OS_Keylist Object_List; + uint32_t Max_APDU_Length_Accepted; + BACNET_SEGMENTATION Segmentation_Supported; + uint32_t APDU_Timeout; + uint8_t Number_Of_APDU_Retries; + uint32_t Database_Revision; +} OBJECT_DEVICE_T; + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif