From 4600ec83a3f1d018ee3066a01cc642363cac516c Mon Sep 17 00:00:00 2001 From: skarg Date: Wed, 2 Aug 2006 11:47:38 +0000 Subject: [PATCH] added Analog Value and Binary Value objects to ReadProperty and WriteProperty handlers. Added WriteProperty support for File object. --- bacnet-stack/demo/handler/h_rp.c | 58 +++++++++++++++++++++--- bacnet-stack/demo/handler/h_wp.c | 72 ++++++++++++++++++++++++++---- bacnet-stack/demo/object/bacfile.c | 64 ++++++++++++++++++++++++++ bacnet-stack/demo/object/bacfile.h | 4 ++ 4 files changed, 183 insertions(+), 15 deletions(-) diff --git a/bacnet-stack/demo/handler/h_rp.c b/bacnet-stack/demo/handler/h_rp.c index a9d33df4..a45581bb 100644 --- a/bacnet-stack/demo/handler/h_rp.c +++ b/bacnet-stack/demo/handler/h_rp.c @@ -39,8 +39,10 @@ #include "device.h" #include "ai.h" #include "ao.h" +#include "av.h" #include "bi.h" #include "bo.h" +#include "bv.h" #include "lsp.h" #if BACFILE #include "bacfile.h" @@ -98,7 +100,7 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for Device!\n"); send = true; } else error = true; @@ -119,7 +121,7 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for AI!\n"); send = true; } else error = true; @@ -140,7 +142,7 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for BI!\n"); send = true; } else error = true; @@ -161,7 +163,28 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for BO!\n"); + send = true; + } else + error = true; + } else + error = true; + 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 */ + pdu_len += + rp_ack_encode_apdu(&Handler_Transmit_Buffer + [pdu_len], service_data->invoke_id, &data); + fprintf(stderr, "Sending Read Property Ack for BV!\n"); send = true; } else error = true; @@ -182,7 +205,28 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for AO!\n"); + send = true; + } else + error = true; + } else + error = true; + break; + case OBJECT_ANALOG_VALUE: + if (Analog_Value_Valid_Instance(data.object_instance)) { + len = Analog_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 */ + pdu_len += + rp_ack_encode_apdu(&Handler_Transmit_Buffer + [pdu_len], service_data->invoke_id, &data); + fprintf(stderr, "Sending Read Property Ack for AV!\n"); send = true; } else error = true; @@ -203,7 +247,7 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for LSP!\n"); send = true; } else error = true; @@ -225,7 +269,7 @@ void handler_read_property(uint8_t * service_request, pdu_len += rp_ack_encode_apdu(&Handler_Transmit_Buffer [pdu_len], service_data->invoke_id, &data); - fprintf(stderr, "Sending Read Property Ack!\n"); + fprintf(stderr, "Sending Read Property Ack for File!\n"); send = true; } else error = true; diff --git a/bacnet-stack/demo/handler/h_wp.c b/bacnet-stack/demo/handler/h_wp.c index fde19137..2bc79a60 100644 --- a/bacnet-stack/demo/handler/h_wp.c +++ b/bacnet-stack/demo/handler/h_wp.c @@ -39,8 +39,10 @@ #include "device.h" #include "ai.h" #include "ao.h" +#include "av.h" #include "bi.h" #include "bo.h" +#include "bv.h" #include "lsp.h" #if BACFILE #include "bacfile.h" @@ -92,14 +94,15 @@ void handler_write_property(uint8_t * service_request, encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - fprintf(stderr, "Sending Write Property Simple Ack!\n"); + fprintf(stderr, + "Sending Write Property Simple Ack for Device!\n"); } else { pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); - fprintf(stderr, "Sending Write Property Error!\n"); + fprintf(stderr, "Sending Write Property Error for Device!\n"); } break; case OBJECT_ANALOG_INPUT: @@ -119,14 +122,31 @@ void handler_write_property(uint8_t * service_request, encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - fprintf(stderr, "Sending Write Property Simple Ack!\n"); + fprintf(stderr, "Sending Write Property Simple Ack for BO!\n"); } else { pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); - fprintf(stderr, "Sending Write Access Error!\n"); + fprintf(stderr, "Sending Write Access Error for BO!\n"); + } + break; + case OBJECT_BINARY_VALUE: + if (Binary_Value_Write_Property(&wp_data, &error_class, + &error_code)) { + pdu_len += + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + fprintf(stderr, "Sending Write Property Simple Ack for BV!\n"); + } else { + pdu_len += + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + fprintf(stderr, "Sending Write Access Error for BV!\n"); } break; case OBJECT_ANALOG_OUTPUT: @@ -136,14 +156,31 @@ void handler_write_property(uint8_t * service_request, encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - fprintf(stderr, "Sending Write Property Simple Ack!\n"); + fprintf(stderr, "Sending Write Property Simple Ack for AO!\n"); } else { pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); - fprintf(stderr, "Sending Write Access Error!\n"); + fprintf(stderr, "Sending Write Access Error for AO!\n"); + } + break; + case OBJECT_ANALOG_VALUE: + if (Analog_Value_Write_Property(&wp_data, &error_class, + &error_code)) { + pdu_len += + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + fprintf(stderr, "Sending Write Property Simple Ack for AV!\n"); + } else { + pdu_len += + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + fprintf(stderr, "Sending Write Access Error for AV!\n"); } break; case OBJECT_LIFE_SAFETY_POINT: @@ -153,16 +190,35 @@ void handler_write_property(uint8_t * service_request, encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); - fprintf(stderr, "Sending Write Property Simple Ack!\n"); + fprintf(stderr, "Sending Write Property Simple Ack for LSP!\n"); } else { pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); - fprintf(stderr, "Sending Write Access Error!\n"); + fprintf(stderr, "Sending Write Access Error for LSP!\n"); } break; +#if BACFILE + case OBJECT_FILE: + if (bacfile_write_property(&wp_data, &error_class, + &error_code)) { + pdu_len += + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + fprintf(stderr, "Sending Write Property Simple Ack for File!\n"); + } else { + pdu_len += + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + fprintf(stderr, "Sending Write Access Error for File!\n"); + } + break; +#endif default: pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], diff --git a/bacnet-stack/demo/object/bacfile.c b/bacnet-stack/demo/object/bacfile.c index db69d209..b13edc49 100644 --- a/bacnet-stack/demo/object/bacfile.c +++ b/bacnet-stack/demo/object/bacfile.c @@ -189,6 +189,13 @@ int bacfile_encode_property_apdu(uint8_t * apdu, apdu_len += encode_tagged_time(&apdu[apdu_len], &btime); break; case PROP_ARCHIVE: + /* 12.13.8 Archive + This property, of type BOOLEAN, indicates whether the File + object has been saved for historical or backup purposes. This + property shall be logical TRUE only if no changes have been + made to the file data by internal processes or through File + Access Services since the last time the object was archived. + */ /* FIXME: get the actual value: note it may be inverse... */ apdu_len = encode_tagged_boolean(&apdu[0], true); break; @@ -209,6 +216,63 @@ int bacfile_encode_property_apdu(uint8_t * apdu, return apdu_len; } +/* returns true if successful */ +bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + + if (!bacfile_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 */ + switch (wp_data->object_property) { + case PROP_ARCHIVE: + /* 12.13.8 Archive + This property, of type BOOLEAN, indicates whether the File + object has been saved for historical or backup purposes. This + property shall be logical TRUE only if no changes have been + made to the file data by internal processes or through File + Access Services since the last time the object was archived. */ + if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { + if (wp_data->value.type.Boolean) + { + /* FIXME: do something to wp_data->object_instance */ + } + else + { + /* FIXME: do something to wp_data->object_instance */ + } + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + case PROP_FILE_SIZE: + /* If the file size can be changed by writing to the file, + and File_Access_Method is STREAM_ACCESS, then this property + shall be writable. */ + if (wp_data->value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { + /* FIXME: do something with wp_data->value.type.Unsigned + to wp_data->object_instance */ + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + } + + return status; +} + + + uint32_t bacfile_instance(char *filename) { uint32_t index = 0; diff --git a/bacnet-stack/demo/object/bacfile.h b/bacnet-stack/demo/object/bacfile.h index 59ce52b9..079a5a7c 100644 --- a/bacnet-stack/demo/object/bacfile.h +++ b/bacnet-stack/demo/object/bacfile.h @@ -69,6 +69,10 @@ extern "C" { int32_t array_index, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); +/* handling for write property service */ +bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code); + #ifdef __cplusplus } #endif /* __cplusplus */