From 7205b32f992e4c7af81c77bee9bd5aad8bc6a733 Mon Sep 17 00:00:00 2001 From: skarg Date: Tue, 27 Mar 2007 14:06:58 +0000 Subject: [PATCH] Changed PIC18F6720 demo to include BI, BV, and AI objects. --- bacnet-stack/demo/handler/h_rp_tiny.c | 57 ++++ .../ports/pic18f6720/BACnet-Server.mcp | 74 ++-- .../ports/pic18f6720/BACnet-Server.mcw | Bin 54272 -> 55808 bytes bacnet-stack/ports/pic18f6720/ai.c | 200 +++++++++++ bacnet-stack/ports/pic18f6720/bi.c | 217 ++++++++++++ bacnet-stack/ports/pic18f6720/bv.c | 323 ++++++++++++++++++ bacnet-stack/ports/pic18f6720/device.c | 6 - 7 files changed, 837 insertions(+), 40 deletions(-) create mode 100644 bacnet-stack/ports/pic18f6720/ai.c create mode 100644 bacnet-stack/ports/pic18f6720/bi.c create mode 100644 bacnet-stack/ports/pic18f6720/bv.c diff --git a/bacnet-stack/demo/handler/h_rp_tiny.c b/bacnet-stack/demo/handler/h_rp_tiny.c index e45ce5cc..a20f589a 100644 --- a/bacnet-stack/demo/handler/h_rp_tiny.c +++ b/bacnet-stack/demo/handler/h_rp_tiny.c @@ -37,6 +37,9 @@ #include "rp.h" /* demo objects */ #include "device.h" +#include "ai.h" +#include "bi.h" +#include "bv.h" /* note: this is a minimal handler. See h_rp.c for another */ @@ -94,6 +97,60 @@ void handler_read_property(uint8_t * service_request, } } break; + case OBJECT_ANALOG_INPUT: + if (Analog_Input_Valid_Instance(data.object_instance)) { + len = Analog_Input_Encode_Property_APDU(&Temp_Buf[0], + data.object_instance, + data.object_property, + data.array_index, &error_class, &error_code); + if (len >= 0) { + /* encode the APDU portion of the packet */ + data.application_data = &Temp_Buf[0]; + data.application_data_len = len; + /* FIXME: probably need a length limitation sent with encode */ + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer + [pdu_len], service_data->invoke_id, &data); + error = false; + } + } + break; + case OBJECT_BINARY_INPUT: + if (Binary_Input_Valid_Instance(data.object_instance)) { + len = Binary_Input_Encode_Property_APDU(&Temp_Buf[0], + data.object_instance, + data.object_property, + data.array_index, &error_class, &error_code); + if (len >= 0) { + /* encode the APDU portion of the packet */ + data.application_data = &Temp_Buf[0]; + data.application_data_len = len; + /* FIXME: probably need a length limitation sent with encode */ + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer + [pdu_len], service_data->invoke_id, &data); + error = false; + } + } + break; + case OBJECT_BINARY_VALUE: + if (Binary_Value_Valid_Instance(data.object_instance)) { + len = Binary_Value_Encode_Property_APDU(&Temp_Buf[0], + data.object_instance, + data.object_property, + data.array_index, &error_class, &error_code); + if (len >= 0) { + /* encode the APDU portion of the packet */ + data.application_data = &Temp_Buf[0]; + data.application_data_len = len; + /* FIXME: probably need a length limitation sent with encode */ + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer + [pdu_len], service_data->invoke_id, &data); + error = false; + } + } + break; default: break; } diff --git a/bacnet-stack/ports/pic18f6720/BACnet-Server.mcp b/bacnet-stack/ports/pic18f6720/BACnet-Server.mcp index 255a4791..34a6d3ee 100644 --- a/bacnet-stack/ports/pic18f6720/BACnet-Server.mcp +++ b/bacnet-stack/ports/pic18f6720/BACnet-Server.mcp @@ -76,6 +76,9 @@ file_056=no file_057=no file_058=no file_059=no +file_060=no +file_061=no +file_062=no [FILE_INFO] file_000=C:\code\bacnet-stack\abort.c file_001=C:\code\bacnet-stack\apdu.c @@ -103,40 +106,43 @@ file_022=C:\code\bacnet-stack\demo\handler\txbuf.c file_023=C:\code\bacnet-stack\demo\handler\h_whois.c file_024=mstp.c file_025=C:\code\bacnet-stack\demo\handler\h_rp_tiny.c -file_026=C:\code\bacnet-stack\wp.h -file_027=C:\code\bacnet-stack\abort.h -file_028=C:\code\bacnet-stack\apdu.h -file_029=C:\code\bacnet-stack\bacapp.h -file_030=C:\code\bacnet-stack\bacdcode.h -file_031=C:\code\bacnet-stack\bacdef.h -file_032=C:\code\bacnet-stack\bacenum.h -file_033=C:\code\bacnet-stack\bacerror.h -file_034=C:\code\bacnet-stack\bacstr.h -file_035=C:\code\bacnet-stack\config.h -file_036=C:\code\bacnet-stack\crc.h -file_037=C:\code\bacnet-stack\dcc.h -file_038=C:\code\bacnet-stack\dlmstp.h -file_039=C:\code\bacnet-stack\iam.h -file_040=C:\code\bacnet-stack\npdu.h -file_041=C:\code\bacnet-stack\rd.h -file_042=C:\code\bacnet-stack\reject.h -file_043=C:\code\bacnet-stack\rp.h -file_044=C:\code\bacnet-stack\whois.h -file_045=C:\code\bacnet-stack\demo\handler\client.h -file_046=C:\code\bacnet-stack\demo\handler\handlers.h -file_047=C:\code\bacnet-stack\demo\object\ai.h -file_048=C:\code\bacnet-stack\demo\object\ao.h -file_049=C:\code\bacnet-stack\demo\object\device.h -file_050=stdbool.h -file_051=stdint.h -file_052=hardware.h -file_053=rs485.h -file_054=C:\code\bacnet-stack\datetime.h -file_055=C:\code\bacnet-stack\demo\handler\txbuf.h -file_056=mstp.h -file_057=C:\code\bacnet-stack\datalink.h -file_058=C:\mcc18\h\p18f6720.h -file_059=18F6720.lkr +file_026=bv.c +file_027=ai.c +file_028=bi.c +file_029=C:\code\bacnet-stack\wp.h +file_030=C:\code\bacnet-stack\abort.h +file_031=C:\code\bacnet-stack\apdu.h +file_032=C:\code\bacnet-stack\bacapp.h +file_033=C:\code\bacnet-stack\bacdcode.h +file_034=C:\code\bacnet-stack\bacdef.h +file_035=C:\code\bacnet-stack\bacenum.h +file_036=C:\code\bacnet-stack\bacerror.h +file_037=C:\code\bacnet-stack\bacstr.h +file_038=C:\code\bacnet-stack\config.h +file_039=C:\code\bacnet-stack\crc.h +file_040=C:\code\bacnet-stack\dcc.h +file_041=C:\code\bacnet-stack\dlmstp.h +file_042=C:\code\bacnet-stack\iam.h +file_043=C:\code\bacnet-stack\npdu.h +file_044=C:\code\bacnet-stack\rd.h +file_045=C:\code\bacnet-stack\reject.h +file_046=C:\code\bacnet-stack\rp.h +file_047=C:\code\bacnet-stack\whois.h +file_048=C:\code\bacnet-stack\demo\handler\client.h +file_049=C:\code\bacnet-stack\demo\handler\handlers.h +file_050=C:\code\bacnet-stack\demo\object\ai.h +file_051=C:\code\bacnet-stack\demo\object\ao.h +file_052=C:\code\bacnet-stack\demo\object\device.h +file_053=stdbool.h +file_054=stdint.h +file_055=hardware.h +file_056=rs485.h +file_057=C:\code\bacnet-stack\datetime.h +file_058=C:\code\bacnet-stack\demo\handler\txbuf.h +file_059=mstp.h +file_060=C:\code\bacnet-stack\datalink.h +file_061=C:\mcc18\h\p18f6720.h +file_062=18F6720.lkr [SUITE_INFO] suite_guid={5B7D72DD-9861-47BD-9F60-2BE967BF8416} suite_state= diff --git a/bacnet-stack/ports/pic18f6720/BACnet-Server.mcw b/bacnet-stack/ports/pic18f6720/BACnet-Server.mcw index 05ae9cdeac3f8c661f66a837d696dc79ace52ac8..3e467055383dc4279ea166863a521fbb9b27b5b6 100644 GIT binary patch literal 55808 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 literal 54272 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 +* +* 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. +* +*********************************************************************/ + +/* Analog Input Objects customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" + +/* Analog Input = Photocell */ +#define MAX_ANALOG_INPUTS 2 + +static uint8_t Present_Value[MAX_ANALOG_INPUTS]; + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need validate that the */ +/* given instance exists */ +bool Analog_Input_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_ANALOG_INPUTS) + return true; + + return false; +} + +/* we simply have 0-n object instances. */ +unsigned Analog_Input_Count(void) +{ + return MAX_ANALOG_INPUTS; +} + +/* we simply have 0-n object instances. */ +uint32_t Analog_Input_Index_To_Instance(unsigned index) +{ + return index; +} + +char *Analog_Input_Name(uint32_t object_instance) +{ + static char text_string[16] = ""; /* okay for single thread */ + + if (object_instance < MAX_ANALOG_INPUTS) { + sprintf(text_string, "AI-%lu", object_instance); + return text_string; + } + + return NULL; +} + +static float Analog_Input_Present_Value(uint32_t object_instance) +{ + float value = 0.0; + + if (object_instance < MAX_ANALOG_INPUTS) + value = Present_Value[object_instance]; + + return value; +} + +/* return apdu length, or -1 on error */ +/* assumption - object has already exists */ +int Analog_Input_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + + (void) array_index; + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_ANALOG_INPUT, + object_instance); + break; + /* note: Name and Description don't have to be the same. + You could make Description writable and different */ + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + characterstring_init_ansi(&char_string, + Analog_Input_Name(object_instance)); + apdu_len = encode_tagged_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = encode_tagged_enumerated(&apdu[0], + OBJECT_ANALOG_INPUT); + break; + case PROP_PRESENT_VALUE: + apdu_len = encode_tagged_real(&apdu[0], + Analog_Input_Present_Value(object_instance)); + break; + case PROP_STATUS_FLAGS: + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_tagged_boolean(&apdu[0], false); + break; + case PROP_UNITS: + apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testAnalogInput(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_OUTPUT; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + + /* FIXME: we should do a lot more testing here... */ + len = Analog_Input_Encode_Property_APDU(&apdu[0], + instance, + PROP_OBJECT_IDENTIFIER, + BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len >= 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = decode_object_id(&apdu[len], + (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_ANALOG_INPUT); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_ANALOG_INPUT +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Analog Input", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testAnalogInput); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_ANALOG_INPUT */ +#endif /* TEST */ diff --git a/bacnet-stack/ports/pic18f6720/bi.c b/bacnet-stack/ports/pic18f6720/bi.c new file mode 100644 index 00000000..db1cd61a --- /dev/null +++ b/bacnet-stack/ports/pic18f6720/bi.c @@ -0,0 +1,217 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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. +* +*********************************************************************/ + +/* Analog Input Objects customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" + +#define MAX_BINARY_INPUTS 8 + +static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; + +/* we simply have 0-n object instances. */ +bool Binary_Input_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_BINARY_INPUTS) + return true; + + return false; +} + +/* we simply have 0-n object instances. */ +unsigned Binary_Input_Count(void) +{ + return MAX_BINARY_INPUTS; +} + +/* we simply have 0-n object instances.*/ +uint32_t Binary_Input_Index_To_Instance(unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the index */ +/* that correlates to the correct instance number */ +unsigned Binary_Input_Instance_To_Index(uint32_t object_instance) +{ + unsigned index = MAX_BINARY_INPUTS; + + if (object_instance < MAX_BINARY_INPUTS) + index = object_instance; + + return index; +} + +static BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t + object_instance) +{ + BACNET_BINARY_PV value = BINARY_INACTIVE; + unsigned index = 0; + + index = Binary_Input_Instance_To_Index(object_instance); + if (index < MAX_BINARY_INPUTS) { + value = Present_Value[index]; + } + + return value; +} + +char *Binary_Input_Name(uint32_t object_instance) +{ + static char text_string[16] = ""; /* okay for single thread */ + + if (object_instance < MAX_BINARY_INPUTS) { + sprintf(text_string, "BI-%lu", object_instance); + return text_string; + } + + return NULL; +} + +/* return apdu length, or -1 on error */ +/* assumption - object already exists, and has been bounds checked */ +int Binary_Input_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + BACNET_POLARITY polarity = POLARITY_NORMAL; + BACNET_BINARY_PV value = BINARY_INACTIVE; + + + (void) array_index; + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_INPUT, + object_instance); + break; + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + /* note: object name must be unique in our device */ + characterstring_init_ansi(&char_string, + Binary_Input_Name(object_instance)); + apdu_len = encode_tagged_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_INPUT); + break; + case PROP_PRESENT_VALUE: + value = Binary_Input_Present_Value(object_instance); + apdu_len = encode_tagged_enumerated(&apdu[0],value); + break; + case PROP_STATUS_FLAGS: + /* note: see the details in the standard on how to use these */ + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + /* note: see the details in the standard on how to use this */ + apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_tagged_boolean(&apdu[0], false); + break; + case PROP_POLARITY: + apdu_len = encode_tagged_enumerated(&apdu[0], polarity); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testBinaryInput(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_OUTPUT; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + + /* FIXME: we should do a lot more testing here... */ + len = Binary_Input_Encode_Property_APDU(&apdu[0], + instance, + PROP_OBJECT_IDENTIFIER, + BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len >= 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = decode_object_id(&apdu[len], + (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_BINARY_INPUT); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_BINARY_INPUT +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Binary Input", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testBinaryInput); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_BINARY_INPUT */ +#endif /* TEST */ diff --git a/bacnet-stack/ports/pic18f6720/bv.c b/bacnet-stack/ports/pic18f6720/bv.c new file mode 100644 index 00000000..81b65ca1 --- /dev/null +++ b/bacnet-stack/ports/pic18f6720/bv.c @@ -0,0 +1,323 @@ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* 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. +* +*********************************************************************/ + +/* Binary Output Objects - customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" /* the custom stuff */ +#include "wp.h" + +#define MAX_BINARY_VALUES 8 + +static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES]; + +/* we simply have 0-n object instances. */ +bool Binary_Value_Valid_Instance(uint32_t object_instance) +{ + if (object_instance < MAX_BINARY_VALUES) + return true; + + return false; +} + +/* we simply have 0-n object instances. */ +unsigned Binary_Value_Count(void) +{ + return MAX_BINARY_VALUES; +} + +/* we simply have 0-n object instances. */ +uint32_t Binary_Value_Index_To_Instance(unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. */ +unsigned Binary_Value_Instance_To_Index(uint32_t object_instance) +{ + unsigned index = MAX_BINARY_VALUES; + + if (object_instance < MAX_BINARY_VALUES) + index = object_instance; + + return index; +} + +static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t + object_instance) +{ + BACNET_BINARY_PV value = BINARY_INACTIVE; + + if (object_instance < MAX_BINARY_VALUES) { + value = Present_Value[object_instance]; + } + + return value; +} + +/* note: the object name must be unique within this device */ +char *Binary_Value_Name(uint32_t object_instance) +{ + static char text_string[16] = ""; /* okay for single thread */ + + if (object_instance < MAX_BINARY_VALUES) { + sprintf(text_string, "BV-%lu", object_instance); + return text_string; + } + + return NULL; +} + +/* return apdu len, or -1 on error */ +int Binary_Value_Encode_Property_APDU(uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + int len = 0; + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + BACNET_BINARY_PV present_value = BINARY_INACTIVE; + BACNET_POLARITY polarity = POLARITY_NORMAL; + unsigned object_index = 0; + unsigned i = 0; + bool state = false; + + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_VALUE, + object_instance); + break; + /* note: Name and Description don't have to be the same. + You could make Description writable and different */ + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + characterstring_init_ansi(&char_string, + Binary_Value_Name(object_instance)); + apdu_len = encode_tagged_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_VALUE); + break; + case PROP_PRESENT_VALUE: + present_value = Binary_Value_Present_Value(object_instance); + apdu_len = encode_tagged_enumerated(&apdu[0], present_value); + break; + case PROP_STATUS_FLAGS: + /* note: see the details in the standard on how to use these */ + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + /* note: see the details in the standard on how to use this */ + apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_tagged_boolean(&apdu[0], false); + break; + case PROP_POLARITY: + /* FIXME: figure out the polarity */ + apdu_len = encode_tagged_enumerated(&apdu[0], polarity); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} + +/* returns true if successful */ +bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + unsigned int object_index = 0; + unsigned int priority = 0; + BACNET_BINARY_PV level = BINARY_NULL; + int len = 0; + BACNET_APPLICATION_DATA_VALUE value; + + if (!Binary_Value_Valid_Instance(wp_data->object_instance)) { + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; + return false; + } + /* decode the some of the request */ + len = bacapp_decode_application_data(wp_data->application_data, + wp_data->application_data_len, &value); + /* FIXME: len < application_data_len: more data? */ + /* FIXME: len == 0: unable to decode? */ + switch (wp_data->object_property) { + case PROP_PRESENT_VALUE: + if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { + priority = wp_data->priority; + /* Command priority 6 is reserved for use by Minimum On/Off + algorithm and may not be used for other purposes in any + object. */ + if (priority && (priority <= BACNET_MAX_PRIORITY) && + (priority != 6 /* reserved */ ) && + (value.type.Enumerated >= MIN_BINARY_PV) && + (value.type.Enumerated <= MAX_BINARY_PV)) { + level = value.type.Enumerated; + object_index = + Binary_Value_Instance_To_Index(wp_data-> + object_instance); + priority--; + /* NOTE: this Binary value has no priority array */ + Present_Value[object_index] = level; + /* Note: you could set the physical output here if we + are the highest priority. + However, if Out of Service is TRUE, then don't set the + physical output. */ + status = true; + } else if (priority == 6) { + /* Command priority 6 is reserved for use by Minimum On/Off + algorithm and may not be used for other purposes in any + object. */ + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } + } else if (value.tag == BACNET_APPLICATION_TAG_NULL) { +#if 0 + /* NOTE: this Binary Value has no priority array */ + level = BINARY_NULL; + object_index = + Binary_Value_Instance_To_Index(wp_data->object_instance); + priority = wp_data->priority; + if (priority && (priority <= BACNET_MAX_PRIORITY)) { + priority--; + Binary_Value_Level[object_index][priority] = level; + /* Note: you could set the physical output here to the next + highest priority, or to the relinquish default if no + priorities are set. + However, if Out of Service is TRUE, then don't set the + physical output. This comment may apply to the + main loop (i.e. check out of service before changing output) */ + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } +#else + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; +#endif + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; +#if 0 + case PROP_OUT_OF_SERVICE: + if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { + object_index = + Binary_Value_Instance_To_Index(wp_data->object_instance); + Binary_Value_Out_Of_Service[object_index] = value.type.Boolean; + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; +#endif + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + } + + return status; +} + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testBinary_Value(Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_VALUE; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + + len = Binary_Value_Encode_Property_APDU(&apdu[0], + instance, + PROP_OBJECT_IDENTIFIER, + BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len != 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = decode_object_id(&apdu[len], + (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_BINARY_VALUE +int main(void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Binary_Value", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testBinary_Value); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_BINARY_VALUE */ +#endif /* TEST */ diff --git a/bacnet-stack/ports/pic18f6720/device.c b/bacnet-stack/ports/pic18f6720/device.c index 9b12c1bb..1dfacb41 100644 --- a/bacnet-stack/ports/pic18f6720/device.c +++ b/bacnet-stack/ports/pic18f6720/device.c @@ -160,11 +160,9 @@ unsigned Device_Object_List_Count(void) unsigned count = 1; /* at least 1 for device object */ /* FIXME: add objects as needed */ -#if 0 count += Binary_Value_Count(); count += Analog_Input_Count(); count += Binary_Input_Count(); -#endif return count; } @@ -184,7 +182,6 @@ bool Device_Object_List_Identifier(unsigned array_index, *instance = Object_Instance_Number; status = true; } -#if 0 /* FIXME: add objects as needed */ /* binary input objects */ if (!status) { @@ -224,7 +221,6 @@ bool Device_Object_List_Identifier(unsigned array_index, status = true; } } -#endif return status; } @@ -333,11 +329,9 @@ int Device_Encode_Property_APDU(uint8_t * apdu, } /* FIXME: indicate the objects that YOU support */ bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); -#if 0 bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true); -#endif apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string); break; case PROP_OBJECT_LIST: