Updated ports/bdk-atxx4-mstp to use demo handlers for RP,RPM,WP.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user