rewrote the write property to handle most basic tag types
This commit is contained in:
+20
-61
@@ -258,13 +258,6 @@ bool Analog_Output_Write_Property(
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
bool status = false; // return value
|
||||
uint8_t *apdu = NULL;
|
||||
int len = 0;
|
||||
int tag_len = 0;
|
||||
int apdu_len = 0;
|
||||
uint8_t tag_number = 0;
|
||||
uint32_t len_value_type = 0;
|
||||
float real_value = 0.0;
|
||||
unsigned int object_index = 0;
|
||||
unsigned int priority = 0;
|
||||
uint8_t level = AO_LEVEL_NULL;
|
||||
@@ -281,61 +274,27 @@ bool Analog_Output_Write_Property(
|
||||
switch (wp_data->object_property)
|
||||
{
|
||||
case PROP_PRESENT_VALUE:
|
||||
apdu = wp_data->property_value;
|
||||
tag_len = decode_tag_number_and_value(&apdu[0],
|
||||
&tag_number, &len_value_type);
|
||||
if (tag_len)
|
||||
if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL)
|
||||
{
|
||||
if (tag_number == BACNET_APPLICATION_TAG_REAL)
|
||||
{
|
||||
len = decode_real(&apdu[tag_len],&real_value);
|
||||
if (len && (real_value >= 0.0) && (real_value <= 100.0))
|
||||
level = real_value;
|
||||
else
|
||||
{
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
object_index = Analog_Output_Instance_To_Index(
|
||||
wp_data->object_instance);
|
||||
apdu_len = tag_len + len;
|
||||
if (decode_is_closing_tag_number(&apdu[apdu_len], 3))
|
||||
{
|
||||
// decode the optional priority
|
||||
apdu_len++;
|
||||
if (apdu_len <= wp_data->property_value_len)
|
||||
priority = BACNET_MAX_PRIORITIES;
|
||||
else
|
||||
{
|
||||
tag_len = decode_tag_number_and_value(&apdu[0],
|
||||
&tag_number, &len_value_type);
|
||||
if (tag_number == 4)
|
||||
{
|
||||
apdu_len += tag_len;
|
||||
len = decode_unsigned(&apdu[len], len_value_type,
|
||||
&priority);
|
||||
}
|
||||
}
|
||||
priority--;
|
||||
if (priority < BACNET_MAX_PRIORITIES)
|
||||
{
|
||||
Analog_Output_Level[object_index][priority] = level;
|
||||
status = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INCONSISTENT_PARAMETERS;
|
||||
return false;
|
||||
}
|
||||
fprintf(stderr, "Real=%f\n",wp_data->value.type.Real);
|
||||
if ((wp_data->value.type.Real >= 0.0) &&
|
||||
(wp_data->value.type.Real <= 100.0))
|
||||
level = wp_data->value.type.Real;
|
||||
else
|
||||
{
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
object_index = Analog_Output_Instance_To_Index(
|
||||
wp_data->object_instance);
|
||||
priority = wp_data->priority;
|
||||
fprintf(stderr, "Priority=%u\n",wp_data->priority);
|
||||
if (priority && (priority <= BACNET_MAX_PRIORITIES))
|
||||
{
|
||||
priority--;
|
||||
Analog_Output_Level[object_index][priority] = level;
|
||||
status = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+5
-19
@@ -454,13 +454,6 @@ bool Device_Write_Property(
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
{
|
||||
bool status = false; // return value
|
||||
uint8_t *apdu = NULL;
|
||||
int len = 0;
|
||||
int tag_len = 0;
|
||||
uint8_t tag_number = 0;
|
||||
uint32_t len_value_type = 0;
|
||||
int object_type = 0;
|
||||
uint32_t instance = 0;
|
||||
|
||||
if (!Device_Valid_Object_Instance_Number(wp_data->object_instance))
|
||||
{
|
||||
@@ -470,23 +463,16 @@ bool Device_Write_Property(
|
||||
}
|
||||
|
||||
// decode the some of the request
|
||||
apdu = wp_data->property_value;
|
||||
tag_len = decode_tag_number_and_value(&apdu[0],
|
||||
&tag_number, &len_value_type);
|
||||
switch (wp_data->object_property)
|
||||
{
|
||||
case PROP_OBJECT_IDENTIFIER:
|
||||
if (tag_len && (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID))
|
||||
if (wp_data->value.tag == BACNET_APPLICATION_TAG_OBJECT_ID)
|
||||
{
|
||||
// FIXME: are we exceeding the property_value_len?
|
||||
len = decode_object_id(&apdu[tag_len],
|
||||
&object_type,
|
||||
&instance);
|
||||
if (len &&
|
||||
(object_type == OBJECT_DEVICE) &&
|
||||
(instance <= BACNET_MAX_INSTANCE))
|
||||
if ((wp_data->value.type.Object_ID.type == OBJECT_DEVICE) &&
|
||||
(wp_data->value.type.Object_ID.instance <= BACNET_MAX_INSTANCE))
|
||||
{
|
||||
Device_Set_Object_Instance_Number(instance);
|
||||
Device_Set_Object_Instance_Number(
|
||||
wp_data->value.type.Object_ID.instance);
|
||||
I_Am_Request = true;
|
||||
status = true;
|
||||
}
|
||||
|
||||
+124
-14
@@ -44,7 +44,6 @@ int wp_encode_apdu(
|
||||
uint8_t invoke_id,
|
||||
BACNET_WRITE_PROPERTY_DATA *data)
|
||||
{
|
||||
int len = 0; // length of each encoding
|
||||
int apdu_len = 0; // total length of the apdu, return value
|
||||
|
||||
if (apdu)
|
||||
@@ -64,10 +63,38 @@ int wp_encode_apdu(
|
||||
data->array_index);
|
||||
// propertyValue
|
||||
apdu_len += encode_opening_tag(&apdu[apdu_len], 3);
|
||||
for (len = 0; len < data->property_value_len; len++)
|
||||
{
|
||||
apdu[apdu_len++] = data->property_value[len];
|
||||
}
|
||||
if (data->value.tag == BACNET_APPLICATION_TAG_NULL)
|
||||
apdu[apdu_len++] = data->value.tag;
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN)
|
||||
apdu_len += encode_tagged_boolean(&apdu[apdu_len],
|
||||
data->value.type.Boolean);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)
|
||||
apdu_len += encode_tagged_unsigned(&apdu[apdu_len],
|
||||
data->value.type.Unsigned_Int);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_SIGNED_INT)
|
||||
apdu_len += encode_tagged_signed(&apdu[apdu_len],
|
||||
data->value.type.Signed_Int);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_REAL)
|
||||
apdu_len += encode_tagged_real(&apdu[apdu_len],
|
||||
data->value.type.Real);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_ENUMERATED)
|
||||
apdu_len += encode_tagged_enumerated(&apdu[apdu_len],
|
||||
data->value.type.Enumerated);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_DATE)
|
||||
apdu_len += encode_tagged_date(&apdu[apdu_len],
|
||||
data->value.type.Date.year,
|
||||
data->value.type.Date.month,
|
||||
data->value.type.Date.day,
|
||||
data->value.type.Date.wday);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_TIME)
|
||||
apdu_len += encode_tagged_time(&apdu[apdu_len],
|
||||
data->value.type.Time.hour,
|
||||
data->value.type.Time.min,
|
||||
data->value.type.Time.sec,
|
||||
data->value.type.Time.hundredths);
|
||||
else if (data->value.tag == BACNET_APPLICATION_TAG_OBJECT_ID)
|
||||
apdu_len += encode_tagged_object_id(&apdu[apdu_len],
|
||||
data->value.type.Object_ID.type,data->value.type.Object_ID.instance);
|
||||
apdu_len += encode_closing_tag(&apdu[apdu_len], 3);
|
||||
// optional priority - 0 if not set, 1..16 if set
|
||||
if (data->priority)
|
||||
@@ -91,6 +118,10 @@ int wp_decode_service_request(
|
||||
int type = 0; // for decoding
|
||||
int property = 0; // for decoding
|
||||
unsigned unsigned_value = 0;
|
||||
int hour, min, sec, hundredths;
|
||||
int year, month, day, wday;
|
||||
int object_type = 0;
|
||||
uint32_t instance = 0;
|
||||
|
||||
// check for value pointers
|
||||
if (apdu_len && data)
|
||||
@@ -121,20 +152,99 @@ int wp_decode_service_request(
|
||||
else
|
||||
data->array_index = BACNET_ARRAY_ALL;
|
||||
// Tag 3: opening context tag */
|
||||
if (decode_is_opening_tag_number(&apdu[len], 3))
|
||||
if (!decode_is_opening_tag_number(&apdu[len], 3))
|
||||
return -1;
|
||||
// a tag number of 3 is not extended so only one octet
|
||||
len++;
|
||||
tag_len = decode_tag_number_and_value(&apdu[len],
|
||||
&tag_number, &len_value_type);
|
||||
if (tag_len)
|
||||
{
|
||||
// a tag number of 3 is not extended so only one octet
|
||||
len++;
|
||||
// don't decode the property value here
|
||||
data->property_value = &apdu[len];
|
||||
data->property_value_len = apdu_len - len;
|
||||
len += tag_len;
|
||||
if (tag_number == BACNET_APPLICATION_TAG_NULL)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_BOOLEAN)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
data->value.type.Boolean = decode_boolean(len_value_type);
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_UNSIGNED_INT)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_unsigned(&apdu[len],
|
||||
len_value_type,
|
||||
&data->value.type.Unsigned_Int);
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_SIGNED_INT)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_unsigned(&apdu[len],
|
||||
len_value_type,
|
||||
&data->value.type.Signed_Int);
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_REAL)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_real(&apdu[len],&(data->value.type.Real));
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_ENUMERATED)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_enumerated(&apdu[len],
|
||||
len_value_type,
|
||||
&data->value.type.Enumerated);
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_DATE)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_date(&apdu[len], &year, &month, &day, &wday);
|
||||
data->value.type.Date.year = year;
|
||||
data->value.type.Date.month = month;
|
||||
data->value.type.Date.day = day;
|
||||
data->value.type.Date.wday = wday;
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_TIME)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_bacnet_time(&apdu[len], &hour, &min, &sec, &hundredths);
|
||||
data->value.type.Time.hour = hour;
|
||||
data->value.type.Time.min = min;
|
||||
data->value.type.Time.sec = sec;
|
||||
data->value.type.Time.hundredths = hundredths;
|
||||
}
|
||||
else if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID)
|
||||
{
|
||||
data->value.tag = tag_number;
|
||||
len += decode_object_id(&apdu[tag_len],
|
||||
&object_type,
|
||||
&instance);
|
||||
data->value.type.Object_ID.type = object_type;
|
||||
data->value.type.Object_ID.instance = instance;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
if (!decode_is_closing_tag_number(&apdu[len], 3))
|
||||
return -1;
|
||||
// a tag number of 3 is not extended so only one octet
|
||||
len++;
|
||||
// Tag 4: optional Priority
|
||||
// FIXME: if the property value is not easily sized here,
|
||||
// then just have the application decode the property value
|
||||
// and the priority
|
||||
data->priority = BACNET_MAX_PRIORITIES;
|
||||
if (len < apdu_len)
|
||||
{
|
||||
tag_len = decode_tag_number_and_value(&apdu[len],
|
||||
&tag_number, &len_value_type);
|
||||
if (tag_number == 4)
|
||||
{
|
||||
len += tag_len;
|
||||
len = decode_unsigned(&apdu[len], len_value_type, &unsigned_value);
|
||||
data->priority = unsigned_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
|
||||
+8
-4
@@ -41,7 +41,7 @@
|
||||
typedef struct BACnet_Write_Property_Value
|
||||
{
|
||||
uint8_t tag;
|
||||
union tag_value
|
||||
union
|
||||
{
|
||||
// NULL - not needed as it is encoded in the tag alone
|
||||
bool Boolean;
|
||||
@@ -57,8 +57,13 @@ typedef struct BACnet_Write_Property_Value
|
||||
unsigned int Enumerated;
|
||||
BACNET_DATE Date;
|
||||
BACNET_TIME Time;
|
||||
struct
|
||||
{
|
||||
uint16_t type;
|
||||
uint32_t instance;
|
||||
} Object_ID;
|
||||
uint32_t Object_Identifier;
|
||||
}
|
||||
} type;
|
||||
} BACNET_WRITE_PROPERTY_VALUE;
|
||||
|
||||
typedef struct BACnet_Write_Property_Data
|
||||
@@ -67,8 +72,7 @@ typedef struct BACnet_Write_Property_Data
|
||||
uint32_t object_instance;
|
||||
BACNET_PROPERTY_ID object_property;
|
||||
int32_t array_index; // use BACNET_ARRAY_ALL when not setting
|
||||
uint8_t *property_value;
|
||||
int property_value_len;
|
||||
BACNET_WRITE_PROPERTY_VALUE value;
|
||||
uint8_t priority; // use 0 if not setting the priority
|
||||
} BACNET_WRITE_PROPERTY_DATA;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user