void testDevice( Test * pTest) { bool status = false; const char *name = "Patricia"; status = Device_Set_Object_Instance_Number(0); ct_test(pTest, Device_Object_Instance_Number() == 0); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); ct_test(pTest, Device_Object_Instance_Number() == BACNET_MAX_INSTANCE); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE / 2); ct_test(pTest, Device_Object_Instance_Number() == (BACNET_MAX_INSTANCE / 2)); ct_test(pTest, status == true); status = Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE + 1); ct_test(pTest, Device_Object_Instance_Number() != (BACNET_MAX_INSTANCE + 1)); ct_test(pTest, status == false); Device_Set_System_Status(STATUS_NON_OPERATIONAL); ct_test(pTest, Device_System_Status() == STATUS_NON_OPERATIONAL); ct_test(pTest, Device_Vendor_Identifier() == BACNET_VENDOR_ID); Device_Set_Model_Name(name, strlen(name)); ct_test(pTest, strcmp(Device_Model_Name(), name) == 0); return; }
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA * rpdata) { int apdu_len = 0; /* return value */ int len = 0; /* apdu len intermediate value */ BACNET_BIT_STRING bit_string = { 0 }; BACNET_CHARACTER_STRING char_string = { 0 }; unsigned i = 0; int object_type = 0; uint32_t instance = 0; unsigned count = 0; uint8_t *apdu = NULL; struct my_object_functions *pObject = NULL; if ((rpdata->application_data == NULL) || (rpdata->application_data_len == 0)) { return 0; } apdu = rpdata->application_data; switch ((int) rpdata->object_property) { case PROP_OBJECT_IDENTIFIER: apdu_len = encode_application_object_id(&apdu[0], rpdata->object_type, rpdata->object_instance); break; case PROP_OBJECT_NAME: Device_Object_Name(rpdata->object_instance, &char_string); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_OBJECT_TYPE: apdu_len = encode_application_enumerated(&apdu[0], rpdata->object_type); break; case PROP_DESCRIPTION: bacnet_name(NVM_DEVICE_DESCRIPTION, &char_string, "default description"); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_LOCATION: bacnet_name(NVM_DEVICE_LOCATION, &char_string, "default location"); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_SYSTEM_STATUS: apdu_len = encode_application_enumerated(&apdu[0], Device_System_Status()); break; case PROP_VENDOR_NAME: characterstring_init_ansi(&char_string, Device_Vendor_Name()); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_VENDOR_IDENTIFIER: apdu_len = encode_application_unsigned(&apdu[0], BACNET_VENDOR_ID); break; case PROP_MODEL_NAME: characterstring_init_ansi(&char_string, Device_Model_Name()); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_FIRMWARE_REVISION: characterstring_init_ansi(&char_string, Device_Firmware_Revision()); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_APPLICATION_SOFTWARE_VERSION: characterstring_init_ansi(&char_string, Device_Application_Software_Version()); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_PROTOCOL_VERSION: apdu_len = encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_VERSION); break; case PROP_PROTOCOL_REVISION: apdu_len = encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_REVISION); break; case PROP_PROTOCOL_SERVICES_SUPPORTED: /* Note: list of services that are executed, not initiated. */ bitstring_init(&bit_string); for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { /* automatic lookup based on handlers set */ bitstring_set_bit(&bit_string, (uint8_t) i, apdu_service_supported((BACNET_SERVICES_SUPPORTED) i)); } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: /* Note: this is the list of objects that can be in this device, not a list of objects that this device can access */ bitstring_init(&bit_string); for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { /* initialize all the object types to not-supported */ bitstring_set_bit(&bit_string, (uint8_t) i, false); } /* set the object types with objects to supported */ i = 0; pObject = &Object_Table[i]; while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) { if ((pObject->Object_Count) && (pObject->Object_Count() > 0)) { bitstring_set_bit(&bit_string, pObject->Object_Type, true); } pObject++; } apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_OBJECT_LIST: count = Device_Object_List_Count(); /* Array element zero is the number of objects in the list */ if (rpdata->array_index == 0) apdu_len = encode_application_unsigned(&apdu[0], count); /* if no index was specified, then try to encode the entire list */ /* into one packet. Note that more than likely you will have */ /* to return an error if the number of encoded objects exceeds */ /* your maximum APDU size. */ else if (rpdata->array_index == BACNET_ARRAY_ALL) { for (i = 1; i <= count; i++) { if (Device_Object_List_Identifier(i, &object_type, &instance)) { len = encode_application_object_id(&apdu[apdu_len], object_type, instance); apdu_len += len; /* assume next one is the same size as this one */ /* can we all fit into the APDU? */ if ((apdu_len + len) >= MAX_APDU) { /* Abort response */ rpdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; apdu_len = BACNET_STATUS_ABORT; break; } } else { /* error: internal error? */ rpdata->error_class = ERROR_CLASS_SERVICES; rpdata->error_code = ERROR_CODE_OTHER; apdu_len = BACNET_STATUS_ERROR; break; } } } else { if (Device_Object_List_Identifier(rpdata->array_index, &object_type, &instance)) apdu_len = encode_application_object_id(&apdu[0], object_type, instance); else { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; apdu_len = BACNET_STATUS_ERROR; } } break; case PROP_MAX_APDU_LENGTH_ACCEPTED: apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); break; case PROP_SEGMENTATION_SUPPORTED: apdu_len = encode_application_enumerated(&apdu[0], Device_Segmentation_Supported()); break; case PROP_APDU_TIMEOUT: apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout()); break; case PROP_NUMBER_OF_APDU_RETRIES: apdu_len = encode_application_unsigned(&apdu[0], apdu_retries()); break; case PROP_DEVICE_ADDRESS_BINDING: /* FIXME: encode the list here, if it exists */ break; case PROP_DATABASE_REVISION: apdu_len = encode_application_unsigned(&apdu[0], Device_Database_Revision()); break; case PROP_MAX_INFO_FRAMES: apdu_len = encode_application_unsigned(&apdu[0], dlmstp_max_info_frames()); break; case PROP_MAX_MASTER: apdu_len = encode_application_unsigned(&apdu[0], dlmstp_max_master()); break; case 512: apdu_len = encode_application_unsigned(&apdu[0], stack_size()); break; case 513: apdu_len = encode_application_unsigned(&apdu[0], stack_unused()); break; default: rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY; apdu_len = BACNET_STATUS_ERROR; break; } /* only array properties can have array options */ if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) && (rpdata->array_index != BACNET_ARRAY_ALL)) { rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; apdu_len = BACNET_STATUS_ERROR; } return apdu_len; }