Updated ports/bdk-atxx4-mstp to use demo handlers for RP,RPM,WP.

This commit is contained in:
skarg
2010-02-11 04:31:43 +00:00
parent 63d7a8018d
commit 70b5d45ce2
10 changed files with 652 additions and 379 deletions
+1 -1
View File
@@ -31,7 +31,7 @@
#include "rp.h" #include "rp.h"
#ifndef MAX_ANALOG_INPUTS #ifndef MAX_ANALOG_INPUTS
#define MAX_ANALOG_INPUTS 7 #define MAX_ANALOG_INPUTS 4
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
+2
View File
@@ -29,6 +29,8 @@
#include <stdint.h> #include <stdint.h>
#include "bacdef.h" #include "bacdef.h"
#include "cov.h" #include "cov.h"
#include "rp.h"
#include "wp.h"
#ifndef MAX_BINARY_INPUTS #ifndef MAX_BINARY_INPUTS
#define MAX_BINARY_INPUTS 5 #define MAX_BINARY_INPUTS 5
+2 -1
View File
@@ -29,10 +29,11 @@
#include <stdint.h> #include <stdint.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacerror.h" #include "bacerror.h"
#include "rp.h"
#include "wp.h" #include "wp.h"
#ifndef MAX_BINARY_OUTPUTS #ifndef MAX_BINARY_OUTPUTS
#define MAX_BINARY_OUTPUTS 6 #define MAX_BINARY_OUTPUTS 4
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
+5 -4
View File
@@ -18,6 +18,7 @@ SIZE = avr-size
AVRDUDE = avrdude AVRDUDE = avrdude
LINT = splint LINT = splint
SIZE_OPTIONS = -C --mcu=${MCU}
# programmer id--check the avrdude for complete list # programmer id--check the avrdude for complete list
# of available opts. These should include stk500, # of available opts. These should include stk500,
# avr910, avrisp, bsd, pony and more. Set this to # avr910, avrisp, bsd, pony and more. Set this to
@@ -58,9 +59,6 @@ CSRC = main.c \
eeprom.c \ eeprom.c \
seeprom.c \ seeprom.c \
dlmstp.c \ dlmstp.c \
h_wp.c \
h_rp.c \
h_rpm.c \
h_rd.c \ h_rd.c \
device.c \ device.c \
ai.c \ ai.c \
@@ -73,6 +71,9 @@ DEMOSRC = $(BACNET_DEMO)/handler/txbuf.c \
$(BACNET_DEMO)/handler/h_npdu.c \ $(BACNET_DEMO)/handler/h_npdu.c \
$(BACNET_DEMO)/handler/h_whois.c \ $(BACNET_DEMO)/handler/h_whois.c \
$(BACNET_DEMO)/handler/h_dcc.c \ $(BACNET_DEMO)/handler/h_dcc.c \
$(BACNET_DEMO)/handler/h_wp.c \
$(BACNET_DEMO)/handler/h_rp.c \
$(BACNET_DEMO)/handler/h_rpm.c \
$(BACNET_DEMO)/handler/s_iam.c \ $(BACNET_DEMO)/handler/s_iam.c \
$(BACNET_DEMO)/handler/noserv.c $(BACNET_DEMO)/handler/noserv.c
@@ -298,7 +299,7 @@ $(LIBRARY): $(COREOBJ) Makefile
size: ${TARGET_ELF} size: ${TARGET_ELF}
@echo @echo
@${SIZE} ${TARGET_ELF} @${SIZE} ${SIZE_OPTIONS} ${TARGET_ELF}
lint: lint:
$(LINT) $(BFLAGS) $(CSRC) $(LINT) $(BFLAGS) $(CSRC)
+21 -22
View File
@@ -32,11 +32,8 @@
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "config.h" #include "config.h"
#include "ai.h"
/* Analog Input */ #include "handlers.h"
#ifndef MAX_ANALOG_INPUTS
#define MAX_ANALOG_INPUTS 2
#endif
static uint8_t Present_Value[MAX_ANALOG_INPUTS]; static uint8_t Present_Value[MAX_ANALOG_INPUTS];
@@ -144,31 +141,33 @@ void Analog_Input_Present_Value_Set(
} }
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object already exists */
int Analog_Input_Encode_Property_APDU( int Analog_Input_Read_Property(
uint8_t * apdu, BACNET_READ_PROPERTY_DATA *rpdata)
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 */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
uint8_t *apdu = NULL;
switch (property) { if ((rpdata == NULL) ||
(rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance); rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance)); Analog_Input_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -179,7 +178,7 @@ int Analog_Input_Encode_Property_APDU(
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len =
encode_application_real(&apdu[0], encode_application_real(&apdu[0],
Analog_Input_Present_Value(object_instance)); Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -200,16 +199,16 @@ int Analog_Input_Encode_Property_APDU(
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
(array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = -1; apdu_len = -1;
} }
+61 -65
View File
@@ -40,10 +40,8 @@
#include "bacapp.h" #include "bacapp.h"
#include "config.h" /* the custom stuff */ #include "config.h" /* the custom stuff */
#include "wp.h" #include "wp.h"
#include "av.h"
#ifndef MAX_ANALOG_VALUES #include "handlers.h"
#define MAX_ANALOG_VALUES 4
#endif
static float Present_Value[MAX_ANALOG_VALUES]; static float Present_Value[MAX_ANALOG_VALUES];
@@ -194,13 +192,8 @@ char *Analog_Value_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Encode_Property_APDU( int Analog_Value_Read_Property(
uint8_t * apdu, BACNET_READ_PROPERTY_DATA *rpdata)
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 */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -211,17 +204,24 @@ int Analog_Value_Encode_Property_APDU(
unsigned i = 0; unsigned i = 0;
bool state = false; bool state = false;
#endif #endif
uint8_t *apdu = NULL;
switch (property) { if ((rpdata == NULL) ||
(rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
object_instance); rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Analog_Value_Name(object_instance)); Analog_Value_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -230,7 +230,7 @@ int Analog_Value_Encode_Property_APDU(
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
real_value = Analog_Value_Present_Value(object_instance); real_value = Analog_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_real(&apdu[0], real_value); apdu_len = encode_application_real(&apdu[0], real_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -247,7 +247,7 @@ int Analog_Value_Encode_Property_APDU(
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
#if 0 #if 0
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(rpdata->object_instance);
state = Analog_Value_Out_Of_Service[object_index]; state = Analog_Value_Out_Of_Service[object_index];
#endif #endif
apdu_len = encode_application_boolean(&apdu[0], false); apdu_len = encode_application_boolean(&apdu[0], false);
@@ -258,12 +258,12 @@ int Analog_Value_Encode_Property_APDU(
#if 0 #if 0
case PROP_PRIORITY_ARRAY: case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
if (array_index == 0) if (rpdata->array_index == 0)
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. */ /* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) { for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */ /* FIXME: check if we have room before adding it to APDU */
@@ -279,27 +279,27 @@ int Analog_Value_Encode_Property_APDU(
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
*error_class = ERROR_CLASS_SERVICES; rpdata->error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; rpdata->error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1; apdu_len = -1;
break; break;
} }
} }
} else { } else {
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(rpdata->object_instance);
if (array_index <= BACNET_MAX_PRIORITY) { if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
if (Present_Value[object_index][array_index - 1] == if (Present_Value[object_index][rpdata->array_index - 1] ==
ANALOG_LEVEL_NULL) ANALOG_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]); apdu_len = encode_application_null(&apdu[0]);
else { else {
real_value = real_value =
Present_Value[object_index][array_index - 1]; Present_Value[object_index][rpdata->array_index - 1];
apdu_len = apdu_len =
encode_application_real(&apdu[0], real_value); encode_application_real(&apdu[0], real_value);
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1; apdu_len = -1;
} }
} }
@@ -311,19 +311,19 @@ int Analog_Value_Encode_Property_APDU(
break; break;
#endif #endif
default: default:
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
#if 0 #if 0
(property != PROP_PRIORITY_ARRAY) && (rpdata->object_property != PROP_PRIORITY_ARRAY) &&
#endif #endif
(array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = -1; apdu_len = -1;
} }
@@ -332,9 +332,7 @@ int Analog_Value_Encode_Property_APDU(
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_WRITE_PROPERTY_DATA * wp_data)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
#if 0 #if 0
@@ -344,11 +342,6 @@ bool Analog_Value_Write_Property(
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
if (!Analog_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 */ /* decode the some of the request */
len = len =
bacapp_decode_application_data(wp_data->application_data, bacapp_decode_application_data(wp_data->application_data,
@@ -357,19 +350,25 @@ bool Analog_Value_Write_Property(
/* FIXME: len == 0: unable to decode? */ /* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) { status = WPValidateArgType(&value,
if (Analog_Value_Present_Value_Set(wp_data->object_instance, BACNET_APPLICATION_TAG_REAL,
value.type.Real, wp_data->priority)) { &wp_data->error_class,
status = true; &wp_data->error_code);
} else if (wp_data->priority == 6) { if (status) {
/* Command priority 6 is reserved for use by Minimum On/Off status = Analog_Value_Present_Value_Set(
algorithm and may not be used for other purposes in any wp_data->object_instance,
object. */ value.type.Real, wp_data->priority);
*error_class = ERROR_CLASS_PROPERTY; if (!status) {
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; if (wp_data->priority == 6) {
} else { /* Command priority 6 is reserved for use by Minimum On/Off
*error_class = ERROR_CLASS_PROPERTY; algorithm and may not be used for other purposes in any
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; object. */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} }
#if 0 #if 0
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) { } else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
@@ -377,31 +376,28 @@ bool Analog_Value_Write_Property(
NAN, wp_data->priority)) { NAN, wp_data->priority)) {
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
#endif #endif
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
#if 0 #if 0
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { status = WPValidateArgType(&value,
BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
object_index = object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance); Analog_Value_Instance_To_Index(wp_data->object_instance);
Analog_Value_Out_Of_Service[object_index] = value.type.Boolean; Analog_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; break;
#endif #endif
default: default:
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break; break;
} }
+22 -26
View File
@@ -32,10 +32,8 @@
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "config.h" #include "config.h"
#include "bi.h"
#ifndef MAX_BINARY_INPUTS #include "handlers.h"
#define MAX_BINARY_INPUTS 8
#endif
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
@@ -143,17 +141,13 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
bool Binary_Input_Present_Value_Set( bool Binary_Input_Present_Value_Set(
uint32_t object_instance, uint32_t object_instance,
bool value) BACNET_BINARY_PV value)
{ {
unsigned index = 0; unsigned index = 0;
index = Binary_Input_Instance_To_Index(object_instance); index = Binary_Input_Instance_To_Index(object_instance);
if (index < MAX_BINARY_INPUTS) { if (index < MAX_BINARY_INPUTS) {
if (value) { Present_Value[index] = value;
Present_Value[index] = BINARY_ACTIVE;
} else {
Present_Value[index] = BINARY_INACTIVE;
}
return true; return true;
} }
@@ -175,31 +169,33 @@ char *Binary_Input_Name(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */ /* assumption - object already exists, and has been bounds checked */
int Binary_Input_Encode_Property_APDU( int Binary_Input_Read_Property(
uint8_t * apdu, BACNET_READ_PROPERTY_DATA *rpdata)
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 */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
BACNET_POLARITY polarity = POLARITY_NORMAL; BACNET_POLARITY polarity = POLARITY_NORMAL;
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
uint8_t *apdu = NULL;
switch (property) { if ((rpdata == NULL) ||
(rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT, encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
object_instance); rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
/* note: object name must be unique in our device */ /* note: object name must be unique in our device */
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Binary_Input_Name(object_instance)); Binary_Input_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -208,7 +204,7 @@ int Binary_Input_Encode_Property_APDU(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT); encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
value = Binary_Input_Present_Value(object_instance); value = Binary_Input_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], value); apdu_len = encode_application_enumerated(&apdu[0], value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -232,16 +228,16 @@ int Binary_Input_Encode_Property_APDU(
apdu_len = encode_application_enumerated(&apdu[0], polarity); apdu_len = encode_application_enumerated(&apdu[0], polarity);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
(array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = -1; apdu_len = -1;
} }
+84 -81
View File
@@ -35,10 +35,8 @@
#include "wp.h" #include "wp.h"
#include "led.h" #include "led.h"
#include "nvdata.h" #include "nvdata.h"
#include "bo.h"
#ifndef MAX_BINARY_OUTPUTS #include "handlers.h"
#define MAX_BINARY_OUTPUTS 2
#endif
/* When all the priorities are level null, the present value returns */ /* When all the priorities are level null, the present value returns */
/* the Relinquish Default value */ /* the Relinquish Default value */
@@ -251,13 +249,8 @@ char *Binary_Output_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Binary_Output_Encode_Property_APDU( int Binary_Output_Read_Property(
uint8_t * apdu, BACNET_READ_PROPERTY_DATA *rpdata)
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 len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -267,19 +260,26 @@ int Binary_Output_Encode_Property_APDU(
unsigned object_index = 0; unsigned object_index = 0;
unsigned i = 0; unsigned i = 0;
bool state = false; bool state = false;
uint8_t *apdu = NULL;
switch (property) { if ((rpdata == NULL) ||
(rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT, encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT,
object_instance); rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Binary_Output_Name(object_instance)); Binary_Output_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -288,7 +288,7 @@ int Binary_Output_Encode_Property_APDU(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT); encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
present_value = Binary_Output_Present_Value(object_instance); present_value = Binary_Output_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value); apdu_len = encode_application_enumerated(&apdu[0], present_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -306,25 +306,26 @@ int Binary_Output_Encode_Property_APDU(
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
object_index = Binary_Output_Instance_To_Index(object_instance); object_index = Binary_Output_Instance_To_Index(rpdata->object_instance);
state = Out_Of_Service[object_index]; state = Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state); apdu_len = encode_application_boolean(&apdu[0], state);
break; break;
case PROP_POLARITY: case PROP_POLARITY:
object_index = Binary_Output_Instance_To_Index(rpdata->object_instance);
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0],
Polarity[object_index]); Polarity[object_index]);
break; break;
case PROP_PRIORITY_ARRAY: case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
if (array_index == 0) if (rpdata->array_index == 0)
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY); encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. */ /* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
object_index = object_index =
Binary_Output_Instance_To_Index(object_instance); Binary_Output_Instance_To_Index(rpdata->object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) { for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */ /* FIXME: check if we have room before adding it to APDU */
present_value = Binary_Output_Level[object_index][i]; present_value = Binary_Output_Level[object_index][i];
@@ -339,18 +340,18 @@ int Binary_Output_Encode_Property_APDU(
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
*error_class = ERROR_CLASS_SERVICES; rpdata->error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; rpdata->error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1; apdu_len = -1;
break; break;
} }
} }
} else { } else {
object_index = object_index =
Binary_Output_Instance_To_Index(object_instance); Binary_Output_Instance_To_Index(rpdata->object_instance);
if (array_index <= BACNET_MAX_PRIORITY) { if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
present_value = present_value =
Binary_Output_Level[object_index][array_index - 1]; Binary_Output_Level[object_index][rpdata->array_index - 1];
if (present_value == BINARY_NULL) { if (present_value == BINARY_NULL) {
apdu_len = encode_application_null(&apdu[apdu_len]); apdu_len = encode_application_null(&apdu[apdu_len]);
} else { } else {
@@ -359,8 +360,8 @@ int Binary_Output_Encode_Property_APDU(
present_value); present_value);
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1; apdu_len = -1;
} }
} }
@@ -380,17 +381,17 @@ int Binary_Output_Encode_Property_APDU(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
(property != PROP_PRIORITY_ARRAY) && (rpdata->object_property != PROP_PRIORITY_ARRAY) &&
(array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = -1; apdu_len = -1;
} }
@@ -399,9 +400,7 @@ int Binary_Output_Encode_Property_APDU(
/* returns true if successful */ /* returns true if successful */
bool Binary_Output_Write_Property( bool Binary_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_WRITE_PROPERTY_DATA * wp_data)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -410,12 +409,6 @@ bool Binary_Output_Write_Property(
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
object_index = Binary_Output_Instance_To_Index(wp_data->object_instance);
if (object_index >= MAX_BINARY_OUTPUTS) {
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false;
}
/* decode the some of the request */ /* decode the some of the request */
len = len =
bacapp_decode_application_data(wp_data->application_data, bacapp_decode_application_data(wp_data->application_data,
@@ -424,7 +417,11 @@ bool Binary_Output_Write_Property(
/* FIXME: len == 0: unable to decode? */ /* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { status = WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
priority = wp_data->priority; priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
@@ -436,70 +433,76 @@ bool Binary_Output_Write_Property(
priority--; priority--;
Binary_Output_Level_Set(object_index, priority, level); Binary_Output_Level_Set(object_index, priority, level);
Binary_Output_Level_Sync(object_index); Binary_Output_Level_Sync(object_index);
status = true;
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
object. */ object. */
*error_class = ERROR_CLASS_PROPERTY; status = false;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; status = false;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_class = ERROR_CLASS_PROPERTY;
} wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Output_Level_Set(object_index, priority, level);
Binary_Output_Level_Sync(object_index);
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 { } else {
*error_class = ERROR_CLASS_PROPERTY; status = WPValidateArgType(&value,
*error_code = ERROR_CODE_INVALID_DATA_TYPE; BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
level = BINARY_NULL;
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Output_Level_Set(object_index, priority, level);
Binary_Output_Level_Sync(object_index);
} else if (priority == 6) {
status = false;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
}
} }
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) { status = WPValidateArgType(&value,
BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
Binary_Output_Out_Of_Service_Set(object_index, Binary_Output_Out_Of_Service_Set(object_index,
value.type.Boolean); value.type.Boolean);
Binary_Output_Level_Sync(object_index); Binary_Output_Level_Sync(object_index);
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
case PROP_POLARITY: case PROP_POLARITY:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { status = WPValidateArgType(&value,
BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class,
&wp_data->error_code);
if (status) {
if (value.type.Enumerated < MAX_POLARITY) { if (value.type.Enumerated < MAX_POLARITY) {
Binary_Output_Polarity_Set(object_index, Binary_Output_Polarity_Set(object_index,
value.type.Enumerated); value.type.Enumerated);
Binary_Output_Level_Sync(object_index); Binary_Output_Level_Sync(object_index);
status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; status = false;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break; break;
} }
+441 -155
View File
@@ -38,6 +38,7 @@
#include "version.h" #include "version.h"
#include "nvdata.h" #include "nvdata.h"
#include "stack.h" #include "stack.h"
#include "handlers.h"
/* objects */ /* objects */
#include "device.h" #include "device.h"
#include "ai.h" #include "ai.h"
@@ -45,14 +46,225 @@
#include "bi.h" #include "bi.h"
#include "bo.h" #include "bo.h"
static struct object_functions {
BACNET_OBJECT_TYPE Object_Type;
object_init_function Object_Init;
object_count_function Object_Count;
object_index_to_instance_function Object_Index_To_Instance;
object_valid_instance_function Object_Valid_Instance;
object_name_function Object_Name;
read_property_function Object_Read_Property;
write_property_function Object_Write_Property;
rpm_property_lists_function Object_RPM_List;
} Object_Table[] =
{
{OBJECT_DEVICE,
NULL,/* don't init - recursive! */
Device_Count,
Device_Index_To_Instance,
Device_Valid_Object_Instance_Number,
Device_Name,
Device_Read_Property,
Device_Write_Property,
Device_Property_Lists},
{OBJECT_ANALOG_INPUT,
Analog_Input_Init,
Analog_Input_Count,
Analog_Input_Index_To_Instance,
Analog_Input_Valid_Instance,
Analog_Input_Name,
Analog_Input_Read_Property,
NULL,
Analog_Input_Property_Lists},
{OBJECT_ANALOG_VALUE,
Analog_Value_Init,
Analog_Value_Count,
Analog_Value_Index_To_Instance,
Analog_Value_Valid_Instance,
Analog_Value_Name,
Analog_Value_Read_Property,
Analog_Value_Write_Property,
Analog_Value_Property_Lists},
{OBJECT_BINARY_INPUT,
Binary_Input_Init,
Binary_Input_Count,
Binary_Input_Index_To_Instance,
Binary_Input_Valid_Instance,
Binary_Input_Name,
Binary_Input_Read_Property,
NULL,
Binary_Input_Property_Lists},
{OBJECT_BINARY_OUTPUT,
Binary_Output_Init,
Binary_Output_Count,
Binary_Output_Index_To_Instance,
Binary_Output_Valid_Instance,
Binary_Output_Name,
Binary_Output_Read_Property,
Binary_Output_Write_Property,
Binary_Output_Property_Lists},
{MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
/* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */
int Device_Objects_Read_Property(
BACNET_READ_PROPERTY_DATA *rpdata)
{
int apdu_len = -1;
unsigned index = 0;
struct object_functions *pObject = NULL;
bool found = false;
/* initialize the default return values */
rpdata->error_class = ERROR_CLASS_OBJECT;
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
pObject = &Object_Table[0];
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
/* handle each object type */
if (pObject->Object_Type == rpdata->object_type) {
found = true;
if (pObject->Object_Valid_Instance &&
pObject->Object_Valid_Instance(rpdata->object_instance)) {
if (pObject->Object_Read_Property) {
apdu_len = pObject->Object_Read_Property(rpdata);
}
} else {
rpdata->error_class = ERROR_CLASS_OBJECT;
rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
}
break;
}
index++;
pObject = &Object_Table[index];
}
if (!found) {
rpdata->error_class = ERROR_CLASS_OBJECT;
rpdata->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
}
return apdu_len;
}
bool Device_Objects_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
{
int apdu_len = -1;
unsigned index = 0;
struct object_functions *pObject = NULL;
bool found = false;
/* initialize the default return values */
wp_data->error_class = ERROR_CLASS_OBJECT;
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
pObject = &Object_Table[0];
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
/* handle each object type */
if (pObject->Object_Type == wp_data->object_type) {
found = true;
if (pObject->Object_Valid_Instance &&
pObject->Object_Valid_Instance(wp_data->object_instance)) {
if (pObject->Object_Write_Property) {
apdu_len = pObject->Object_Write_Property(wp_data);
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
}
} else {
wp_data->error_class = ERROR_CLASS_OBJECT;
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
}
break;
}
index++;
pObject = &Object_Table[index];
}
if (!found) {
wp_data->error_class = ERROR_CLASS_OBJECT;
wp_data->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
}
return apdu_len;
}
static unsigned property_list_count(
const int *pList)
{
unsigned property_count = 0;
if (pList) {
while (*pList != -1) {
property_count++;
pList++;
}
}
return property_count;
}
/* for a given object type, returns the special property list */
static void Device_Objects_Property_List(
BACNET_OBJECT_TYPE object_type,
struct special_property_list_t *pPropertyList)
{
rpm_property_lists_function object_property_list = NULL;
unsigned index = 0;
struct object_functions *pObject = NULL;
bool found = false;
pPropertyList->Required.pList = NULL;
pPropertyList->Optional.pList = NULL;
pPropertyList->Proprietary.pList = NULL;
pObject = &Object_Table[0];
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
/* handle each object type */
if (pObject->Object_Type == object_type) {
found = true;
object_property_list = pObject->Object_RPM_List;
break;
}
index++;
pObject = &Object_Table[index];
}
if (found && object_property_list) {
object_property_list(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
}
/* fill the count */
if (pPropertyList->Required.pList) {
pPropertyList->Required.count =
property_list_count(pPropertyList->Required.pList);
} else {
pPropertyList->Required.count = 0;
}
if (pPropertyList->Optional.pList) {
pPropertyList->Optional.count =
property_list_count(pPropertyList->Optional.pList);
} else {
pPropertyList->Optional.count = 0;
}
if (pPropertyList->Proprietary.pList) {
pPropertyList->Proprietary.count =
property_list_count(pPropertyList->Proprietary.pList);
} else {
pPropertyList->Proprietary.count = 0;
}
return;
}
/* note: you really only need to define variables for /* note: you really only need to define variables for
properties that are writable or that may change. properties that are writable or that may change.
The properties that are constant can be hard coded The properties that are constant can be hard coded
into the read-property encoding. */ into the read-property encoding. */
static uint32_t Object_Instance_Number; static uint32_t Object_Instance_Number;
static char Object_Name[NV_EEPROM_DEVICE_NAME_SIZE]; static char My_Object_Name[NV_EEPROM_DEVICE_NAME_SIZE];
static uint8_t Object_Name_Encoding; static uint8_t My_Object_Name_Encoding;
static uint8_t Object_Name_Length; static uint8_t My_Object_Name_Length;
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
static BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State = static BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State =
@@ -110,6 +322,27 @@ void Device_Property_Lists(
return; return;
} }
unsigned Device_Count(void)
{
return 1;
}
uint32_t Device_Index_To_Instance(
unsigned index)
{
return Object_Instance_Number;
}
char *Device_Name(
uint32_t object_instance)
{
if (object_instance == Object_Instance_Number) {
return My_Object_Name;
}
return NULL;
}
void Device_Reinit( void Device_Reinit(
void) void)
{ {
@@ -120,6 +353,23 @@ void Device_Reinit(
void Device_Init( void Device_Init(
void) void)
{ {
unsigned index = 0; /* loop counter */
struct object_functions *pObject = NULL;
handler_read_property_function_set(Device_Objects_Read_Property);
handler_rpm_function_set(Device_Objects_Read_Property);
handler_rpm_list_set(Device_Objects_Property_List);
handler_write_property_function_set(Device_Objects_Write_Property);
pObject = &Object_Table[0];
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if (pObject->Object_Init) {
pObject->Object_Init();
}
index++;
pObject = &Object_Table[index];
}
Reinitialize_State = REINITIALIZED_STATE_IDLE; Reinitialize_State = REINITIALIZED_STATE_IDLE;
dcc_set_status_duration(COMMUNICATION_ENABLE, 0); dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
@@ -132,22 +382,22 @@ void Device_Init(
(uint8_t *) & Object_Instance_Number, (uint8_t *) & Object_Instance_Number,
sizeof(Object_Instance_Number)); sizeof(Object_Instance_Number));
} }
eeprom_bytes_read(NV_EEPROM_DEVICE_NAME_ENCODING, &Object_Name_Encoding, eeprom_bytes_read(NV_EEPROM_DEVICE_NAME_ENCODING, &My_Object_Name_Encoding,
1); 1);
eeprom_bytes_read(NV_EEPROM_DEVICE_NAME_LENGTH, &Object_Name_Length, 1); eeprom_bytes_read(NV_EEPROM_DEVICE_NAME_LENGTH, &My_Object_Name_Length, 1);
eeprom_bytes_read(NV_EEPROM_DEVICE_NAME_0, (uint8_t *) & Object_Name[0], eeprom_bytes_read(NV_EEPROM_DEVICE_NAME_0, (uint8_t *) & My_Object_Name[0],
NV_EEPROM_DEVICE_NAME_SIZE); NV_EEPROM_DEVICE_NAME_SIZE);
if ((Object_Name_Encoding >= MAX_CHARACTER_STRING_ENCODING) || if ((My_Object_Name_Encoding >= MAX_CHARACTER_STRING_ENCODING) ||
(Object_Name_Length > NV_EEPROM_DEVICE_NAME_SIZE) || (My_Object_Name_Length > NV_EEPROM_DEVICE_NAME_SIZE) ||
(Object_Name_Length < 1)) { (My_Object_Name_Length < 1)) {
Object_Name_Encoding = CHARACTER_ANSI_X34; My_Object_Name_Encoding = CHARACTER_ANSI_X34;
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_ENCODING, eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_ENCODING,
&Object_Name_Encoding, 1); &My_Object_Name_Encoding, 1);
sprintf(Object_Name, "DEVICE-%lu", Object_Instance_Number); sprintf(My_Object_Name, "DEVICE-%lu", Object_Instance_Number);
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_0, eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_0,
(uint8_t *) & Object_Name[0], NV_EEPROM_DEVICE_NAME_SIZE); (uint8_t *) & My_Object_Name[0], NV_EEPROM_DEVICE_NAME_SIZE);
Object_Name_Length = strlen(Object_Name); My_Object_Name_Length = strlen(My_Object_Name);
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH, &Object_Name_Length, eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH, &My_Object_Name_Length,
1); 1);
} }
} }
@@ -189,11 +439,19 @@ BACNET_DEVICE_STATUS Device_System_Status(
return System_Status; return System_Status;
} }
void Device_Set_System_Status( int Device_Set_System_Status(
BACNET_DEVICE_STATUS status) BACNET_DEVICE_STATUS status,
bool local)
{ {
if (status < MAX_DEVICE_STATUS) /*return value - 0 = ok, -1 = bad value, -2 = not allowed */
int result = -1;
if (status < MAX_DEVICE_STATUS) {
System_Status = status; System_Status = status;
result = 0;
}
return result;
} }
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(
@@ -220,22 +478,30 @@ BACNET_SEGMENTATION Device_Segmentation_Supported(
return SEGMENTATION_NONE; return SEGMENTATION_NONE;
} }
uint8_t Device_Database_Revision( uint32_t Device_Database_Revision(
void) void)
{ {
return 0; return 0;
} }
/* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(
void) void)
{ {
unsigned count = 1; /* at least 1 for device object */ unsigned count = 0; /* number of objects */
unsigned index = 0; /* loop counter */
struct object_functions *pObject = NULL;
/* FIXME: add objects as needed */ /* initialize the default return values */
count += Binary_Input_Count(); pObject = &Object_Table[0];
count += Binary_Output_Count(); while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
count += Analog_Input_Count(); if (pObject->Object_Count) {
count += Analog_Value_Count(); count += pObject->Object_Count();
}
index++;
pObject = &Object_Table[index];
}
return count; return count;
} }
@@ -246,80 +512,96 @@ bool Device_Object_List_Identifier(
uint32_t * instance) uint32_t * instance)
{ {
bool status = false; bool status = false;
unsigned count = 0;
unsigned object_index = 0; unsigned object_index = 0;
unsigned object_count = 0; unsigned index = 0; /* loop counter */
struct object_functions *pObject = NULL;
/* device object */ /* array index zero is length - so invalid */
if (array_index == 1) { if (array_index == 0) {
*object_type = OBJECT_DEVICE; return status;
*instance = Object_Instance_Number;
status = true;
} }
/* normalize the index since
we know it is not the previous objects */
/* array index starts at 1 */
object_index = array_index - 1; object_index = array_index - 1;
/* 1 for the device object */ /* initialize the default return values */
object_count = 1; pObject = &Object_Table[0];
/* FIXME: add objects as needed */ while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
/* binary value objects */ if (pObject->Object_Count &&
if (!status) { pObject->Object_Index_To_Instance) {
object_index -= object_count; object_index -= count;
object_count = Binary_Output_Count(); count = pObject->Object_Count();
/* is it a valid index for this object? */ if (object_index < count) {
if (object_index < object_count) { *object_type = pObject->Object_Type;
*object_type = OBJECT_BINARY_OUTPUT; *instance = pObject->Object_Index_To_Instance(object_index);
*instance = Binary_Output_Index_To_Instance(object_index); status = true;
status = true; break;
} }
}
/* analog input objects */
if (!status) {
/* array index starts at 1, and 1 for the device object */
object_index -= object_count;
object_count = Analog_Input_Count();
if (object_index < object_count) {
*object_type = OBJECT_ANALOG_INPUT;
*instance = Analog_Input_Index_To_Instance(object_index);
status = true;
}
}
/* binary input objects */
if (!status) {
/* normalize the index since
we know it is not the previous objects */
object_index -= object_count;
object_count = Binary_Input_Count();
/* is it a valid index for this object? */
if (object_index < object_count) {
*object_type = OBJECT_BINARY_INPUT;
*instance = Binary_Input_Index_To_Instance(object_index);
status = true;
}
}
/* analog value objects */
if (!status) {
/* array index starts at 1, and 1 for the device object */
object_index -= object_count;
object_count = Analog_Value_Count();
if (object_index < object_count) {
*object_type = OBJECT_ANALOG_VALUE;
*instance = Analog_Value_Index_To_Instance(object_index);
status = true;
} }
index++;
pObject = &Object_Table[index];
} }
return status; return status;
} }
bool Device_Valid_Object_Name(
const char *object_name,
int *object_type,
uint32_t * object_instance)
{
bool found = false;
int type = 0;
uint32_t instance;
unsigned max_objects = 0, i = 0;
bool check_id = false;
char *name = NULL;
max_objects = Device_Object_List_Count();
for (i = 0; i < max_objects; i++) {
check_id = Device_Object_List_Identifier(i, &type, &instance);
if (check_id) {
name = Device_Valid_Object_Id(type, instance);
if (strcmp(name, object_name) == 0) {
found = true;
if (object_type) {
*object_type = type;
}
if (object_instance) {
*object_instance = instance;
}
break;
}
}
}
return found;
}
/* returns the name or NULL if not found */
char *Device_Valid_Object_Id(
int object_type,
uint32_t object_instance)
{
char *name = NULL; /* return value */
unsigned index = 0; /* loop counter */
struct object_functions *pObject = NULL;
pObject = &Object_Table[0];
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if ((pObject->Object_Type == object_type) &&
(pObject->Object_Name)) {
name = pObject->Object_Name(object_instance);
break;
}
index++;
pObject = &Object_Table[index];
}
return name;
}
/* return the length of the apdu encoded or -1 for error */ /* return the length of the apdu encoded or -1 for error */
int Device_Encode_Property_APDU( int Device_Read_Property(
uint8_t * apdu, BACNET_READ_PROPERTY_DATA *rpdata)
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 */ int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */ int len = 0; /* apdu len intermediate value */
@@ -329,18 +611,24 @@ int Device_Encode_Property_APDU(
int object_type = 0; int object_type = 0;
uint32_t instance = 0; uint32_t instance = 0;
unsigned count = 0; unsigned count = 0;
uint8_t *apdu = NULL;
struct object_functions *pObject = NULL;
object_instance = object_instance; if ((rpdata == NULL) ||
/* FIXME: change the hardcoded names to suit your application */ (rpdata->application_data == NULL) ||
switch (property) { (rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_DEVICE, encode_application_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance_Number); Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init(&char_string, Object_Name_Encoding, characterstring_init(&char_string, My_Object_Name_Encoding,
(char *) &Object_Name[0], Object_Name_Length); (char *) &My_Object_Name[0], My_Object_Name_Length);
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -415,24 +703,29 @@ int Device_Encode_Property_APDU(
/* initialize all the object types to not-supported */ /* initialize all the object types to not-supported */
bitstring_set_bit(&bit_string, (uint8_t) i, false); bitstring_set_bit(&bit_string, (uint8_t) i, false);
} }
/* FIXME: indicate the objects that YOU support */ /* set the object types with objects to supported */
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); i = 0;
bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true); pObject = &Object_Table[i];
bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true); if ((pObject->Object_Count) &&
bitstring_set_bit(&bit_string, OBJECT_BINARY_OUTPUT, true); (pObject->Object_Count() > 0)) {
bitstring_set_bit(&bit_string, pObject->Object_Type, true);
}
i++;
pObject = &Object_Table[i];
}
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
count = Device_Object_List_Count(); count = Device_Object_List_Count();
/* Array element zero is the number of objects in the list */ /* Array element zero is the number of objects in the list */
if (array_index == 0) if (rpdata->array_index == 0)
apdu_len = encode_application_unsigned(&apdu[0], count); apdu_len = encode_application_unsigned(&apdu[0], count);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. Note that more than likely you will have */ /* into one packet. Note that more than likely you will have */
/* to return an error if the number of encoded objects exceeds */ /* to return an error if the number of encoded objects exceeds */
/* your maximum APDU size. */ /* your maximum APDU size. */
else if (array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
if (Device_Object_List_Identifier(i, &object_type, if (Device_Object_List_Identifier(i, &object_type,
&instance)) { &instance)) {
@@ -443,28 +736,28 @@ int Device_Encode_Property_APDU(
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
if ((apdu_len + len) >= MAX_APDU) { if ((apdu_len + len) >= MAX_APDU) {
*error_class = ERROR_CLASS_SERVICES; rpdata->error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; rpdata->error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1; apdu_len = -1;
break; break;
} }
} else { } else {
/* error: internal error? */ /* error: internal error? */
*error_class = ERROR_CLASS_SERVICES; rpdata->error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_OTHER; rpdata->error_code = ERROR_CODE_OTHER;
apdu_len = -1; apdu_len = -1;
break; break;
} }
} }
} else { } else {
if (Device_Object_List_Identifier(array_index, &object_type, if (Device_Object_List_Identifier(rpdata->array_index, &object_type,
&instance)) &instance))
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], object_type, encode_application_object_id(&apdu[0], object_type,
instance); instance);
else { else {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1; apdu_len = -1;
} }
} }
@@ -511,17 +804,17 @@ int Device_Encode_Property_APDU(
encode_application_unsigned(&apdu[0], rs485_baud_rate()); encode_application_unsigned(&apdu[0], rs485_baud_rate());
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
(property != PROP_OBJECT_LIST) && (rpdata->object_property != PROP_OBJECT_LIST) &&
(array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
*error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = -1; apdu_len = -1;
} }
@@ -529,19 +822,12 @@ int Device_Encode_Property_APDU(
} }
bool Device_Write_Property( bool Device_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_WRITE_PROPERTY_DATA * wp_data)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false;
}
/* decode the some of the request */ /* decode the some of the request */
len = len =
bacapp_decode_application_data(wp_data->application_data, bacapp_decode_application_data(wp_data->application_data,
@@ -557,12 +843,12 @@ bool Device_Write_Property(
/* we could send an I-Am broadcast to let the world know */ /* we could send an I-Am broadcast to let the world know */
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
case PROP_MAX_INFO_FRAMES: case PROP_MAX_INFO_FRAMES:
@@ -571,12 +857,12 @@ bool Device_Write_Property(
dlmstp_set_max_info_frames(value.type.Unsigned_Int); dlmstp_set_max_info_frames(value.type.Unsigned_Int);
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
case PROP_MAX_MASTER: case PROP_MAX_MASTER:
@@ -586,12 +872,12 @@ bool Device_Write_Property(
dlmstp_set_max_master(value.type.Unsigned_Int); dlmstp_set_max_master(value.type.Unsigned_Int);
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -599,40 +885,40 @@ bool Device_Write_Property(
size_t length = size_t length =
characterstring_length(&value.type.Character_String); characterstring_length(&value.type.Character_String);
if (length < 1) { if (length < 1) {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (length < NV_EEPROM_DEVICE_NAME_SIZE) { } else if (length < NV_EEPROM_DEVICE_NAME_SIZE) {
uint8_t encoding = uint8_t encoding =
characterstring_encoding(&value.type.Character_String); characterstring_encoding(&value.type.Character_String);
if (encoding < MAX_CHARACTER_STRING_ENCODING) { if (encoding < MAX_CHARACTER_STRING_ENCODING) {
uint8_t i; uint8_t i;
char *pCharString; char *pCharString;
Object_Name_Encoding = encoding; My_Object_Name_Encoding = encoding;
Object_Name_Length = length; My_Object_Name_Length = length;
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_ENCODING, eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_ENCODING,
&Object_Name_Encoding, 1); &My_Object_Name_Encoding, 1);
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH, eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_LENGTH,
&Object_Name_Length, 1); &My_Object_Name_Length, 1);
pCharString = pCharString =
characterstring_value(&value. characterstring_value(&value.
type.Character_String); type.Character_String);
for (i = 0; i < Object_Name_Length; i++) { for (i = 0; i < My_Object_Name_Length; i++) {
Object_Name[i] = pCharString[i]; My_Object_Name[i] = pCharString[i];
} }
eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_0, eeprom_bytes_write(NV_EEPROM_DEVICE_NAME_0,
(uint8_t *) & Object_Name[0], length); (uint8_t *) & My_Object_Name[0], length);
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
case 9600: case 9600:
@@ -641,17 +927,17 @@ bool Device_Write_Property(
(rs485_baud_rate_set(value.type.Unsigned_Int))) { (rs485_baud_rate_set(value.type.Unsigned_Int))) {
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break; break;
} }
+13 -24
View File
@@ -92,10 +92,6 @@ static void bacnet_init(
} }
/* initialize objects */ /* initialize objects */
Device_Init(); Device_Init();
Binary_Output_Init();
Analog_Input_Init();
Binary_Input_Init();
Analog_Value_Init();
/* set up our confirmed service unrecognized service handler - required! */ /* set up our confirmed service unrecognized service handler - required! */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler
@@ -123,12 +119,14 @@ static uint8_t PDUBuffer[MAX_MPDU];
static void bacnet_task( static void bacnet_task(
void) void)
{ {
uint8_t mstp_mac_address = 0; uint8_t mstp_mac_address;
uint16_t pdu_len = 0; uint16_t pdu_len;
BACNET_ADDRESS src; /* source address */ BACNET_ADDRESS src; /* source address */
uint8_t value = 0; uint8_t value;
bool button_value = false; bool button_value;
uint8_t i = 0; uint8_t i;
BACNET_BINARY_PV binary_value = BINARY_INACTIVE;
mstp_mac_address = input_address(); mstp_mac_address = input_address();
if (MSTP_MAC_Address != mstp_mac_address) { if (MSTP_MAC_Address != mstp_mac_address) {
@@ -140,12 +138,16 @@ static void bacnet_task(
/* handle the inputs */ /* handle the inputs */
value = adc_result(7); value = adc_result(7);
Analog_Input_Present_Value_Set(0, value); Analog_Input_Present_Value_Set(0, value);
for (i = 0; i < 5; i++) { for (i = 0; i < MAX_BINARY_INPUTS; i++) {
button_value = input_button_value(i); button_value = input_button_value(i);
Binary_Input_Present_Value_Set(i, button_value); if (button_value) {
binary_value = BINARY_ACTIVE;
}
Binary_Input_Present_Value_Set(i, binary_value);
} }
/* handle the communication timer */ /* handle the communication timer */
if (timer_elapsed_seconds(TIMER_DCC, 1)) { if (timer_elapsed_seconds(TIMER_DCC, 1)) {
timer_reset(TIMER_DCC);
dcc_timer_seconds(1); dcc_timer_seconds(1);
} }
/* handle the messaging */ /* handle the messaging */
@@ -155,17 +157,6 @@ static void bacnet_task(
} }
} }
void idle_init(
void)
{
}
void idle_task(
void)
{
/* do nothing */
}
void test_init( void test_init(
void) void)
{ {
@@ -252,7 +243,6 @@ int main(
rs485_init(); rs485_init();
serial_init(); serial_init();
bacnet_init(); bacnet_init();
idle_init();
test_init(); test_init();
/* Enable global interrupts */ /* Enable global interrupts */
__enable_interrupt(); __enable_interrupt();
@@ -261,7 +251,6 @@ int main(
input_task(); input_task();
bacnet_task(); bacnet_task();
led_task(); led_task();
idle_task();
test_task(); test_task();
} }
} }