Modified WriteProperty handler to handle context-specific, application, and constructed data. Fixed up all the demos to use new API.

This commit is contained in:
skarg
2007-01-18 21:22:40 +00:00
parent 69e9cf4ee1
commit c9e1382044
10 changed files with 132 additions and 75 deletions
+2 -2
View File
@@ -121,7 +121,7 @@ int bacapp_decode_application_data(uint8_t * apdu,
/* FIXME: use max_apdu_len! */
(void) max_apdu_len;
if (apdu) {
if (apdu && !decode_is_context_specific(apdu)) {
tag_len = decode_tag_number_and_value(&apdu[0],
&tag_number, &len_value_type);
if (tag_len) {
@@ -215,7 +215,7 @@ int bacapp_decode_context_data(uint8_t * apdu,
/* FIXME: use max_apdu_len! */
(void) max_apdu_len;
if (apdu) {
if (apdu && decode_is_context_specific(apdu)) {
tag_len = decode_tag_number_and_value(&apdu[0],
&tag_number, &len_value_type);
if (tag_len) {
+1 -1
View File
@@ -41,7 +41,7 @@
#include "bacstr.h"
typedef struct BACnet_Application_Data_Value {
uint8_t tag;
uint8_t tag; /* application or context-specific number */
union {
/* NULL - not needed as it is encoded in the tag alone */
bool Boolean;
+16 -7
View File
@@ -31,6 +31,7 @@
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
@@ -274,6 +275,8 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
unsigned int object_index = 0;
unsigned int priority = 0;
uint8_t level = AO_LEVEL_NULL;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
Analog_Output_Init();
if (!Analog_Output_Valid_Instance(wp_data->object_instance)) {
@@ -282,18 +285,24 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL) {
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(wp_data->value.type.Real >= 0.0) &&
(wp_data->value.type.Real <= 100.0)) {
level = (uint8_t) wp_data->value.type.Real;
(value.type.Real >= 0.0) &&
(value.type.Real <= 100.0)) {
level = (uint8_t) value.type.Real;
object_index =
Analog_Output_Instance_To_Index(wp_data->
object_instance);
@@ -315,7 +324,7 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = AO_LEVEL_NULL;
object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance);
@@ -340,11 +349,11 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
}
break;
case PROP_OUT_OF_SERVICE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance);
Analog_Output_Out_Of_Service[object_index] =
wp_data->value.type.Boolean;
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
+16 -7
View File
@@ -31,6 +31,7 @@
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
@@ -271,6 +272,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
unsigned int object_index = 0;
unsigned int priority = 0;
uint8_t level = ANALOG_LEVEL_NULL;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
Analog_Value_Init();
if (!Analog_Value_Valid_Instance(wp_data->object_instance)) {
@@ -279,18 +282,24 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL) {
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(wp_data->value.type.Real >= 0.0) &&
(wp_data->value.type.Real <= 100.0)) {
level = (uint8_t) wp_data->value.type.Real;
(value.type.Real >= 0.0) &&
(value.type.Real <= 100.0)) {
level = (uint8_t) value.type.Real;
object_index =
Analog_Value_Instance_To_Index(wp_data->
object_instance);
@@ -312,7 +321,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = ANALOG_LEVEL_NULL;
object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance);
@@ -337,11 +346,11 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
}
break;
case PROP_OUT_OF_SERVICE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance);
Analog_Value_Out_Of_Service[object_index] =
wp_data->value.type.Boolean;
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
+17 -8
View File
@@ -30,7 +30,8 @@
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
@@ -272,6 +273,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
unsigned int object_index = 0;
unsigned int priority = 0;
BACNET_BINARY_PV level = BINARY_NULL;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
Binary_Output_Init();
if (!Binary_Output_Valid_Instance(wp_data->object_instance)) {
@@ -280,18 +283,24 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(wp_data->value.type.Enumerated >= MIN_BINARY_PV) &&
(wp_data->value.type.Enumerated <= MAX_BINARY_PV)) {
level = wp_data->value.type.Enumerated;
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = value.type.Enumerated;
object_index =
Binary_Output_Instance_To_Index(wp_data->
object_instance);
@@ -313,7 +322,7 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
@@ -338,11 +347,11 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
}
break;
case PROP_OUT_OF_SERVICE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
Binary_Output_Out_Of_Service[object_index] =
wp_data->value.type.Boolean;
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
+17 -8
View File
@@ -30,7 +30,8 @@
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
@@ -269,6 +270,8 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
unsigned int object_index = 0;
unsigned int priority = 0;
BACNET_BINARY_PV level = BINARY_NULL;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
Binary_Value_Init();
if (!Binary_Value_Valid_Instance(wp_data->object_instance)) {
@@ -277,18 +280,24 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(wp_data->value.type.Enumerated >= MIN_BINARY_PV) &&
(wp_data->value.type.Enumerated <= MAX_BINARY_PV)) {
level = wp_data->value.type.Enumerated;
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = value.type.Enumerated;
object_index =
Binary_Value_Instance_To_Index(wp_data->
object_instance);
@@ -310,7 +319,7 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
@@ -335,11 +344,11 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
}
break;
case PROP_OUT_OF_SERVICE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
Binary_Value_Out_Of_Service[object_index] =
wp_data->value.type.Boolean;
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
+25 -16
View File
@@ -29,6 +29,7 @@
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "apdu.h"
#include "ai.h" /* object list dependency */
@@ -766,6 +767,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
*error_class = ERROR_CLASS_OBJECT;
@@ -773,13 +776,19 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_OBJECT_IDENTIFIER:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
if ((wp_data->value.type.Object_Id.type == OBJECT_DEVICE) &&
(Device_Set_Object_Instance_Number(wp_data->value.type.
Object_Id.instance))) {
/* we could send an I-Am broadcast to let the world know */
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
(Device_Set_Object_Instance_Number(
value.type.Object_Id.instance))) {
/* FIXME: we could send an I-Am broadcast to let the world know */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
@@ -792,9 +801,9 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
break;
case PROP_NUMBER_OF_APDU_RETRIES:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
/* FIXME: bounds check? */
Device_Set_Number_Of_APDU_Retries((uint8_t) wp_data->value.
Device_Set_Number_Of_APDU_Retries((uint8_t) value.
type.Unsigned_Int);
status = true;
} else {
@@ -804,9 +813,9 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
break;
case PROP_APDU_TIMEOUT:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
/* FIXME: bounds check? */
Device_Set_APDU_Timeout((uint16_t) wp_data->value.type.
Device_Set_APDU_Timeout((uint16_t) value.type.
Unsigned_Int);
status = true;
} else {
@@ -816,9 +825,9 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
break;
case PROP_VENDOR_IDENTIFIER:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
/* FIXME: bounds check? */
Device_Set_Vendor_Identifier((uint16_t) wp_data->value.type.
Device_Set_Vendor_Identifier((uint16_t) value.type.
Unsigned_Int);
status = true;
} else {
@@ -828,8 +837,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
break;
case PROP_SYSTEM_STATUS:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
Device_Set_System_Status(wp_data->value.type.Enumerated);
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
Device_Set_System_Status(value.type.Enumerated);
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
@@ -838,16 +847,16 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
break;
case PROP_OBJECT_NAME:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
uint8_t encoding;
encoding =
characterstring_encoding(&wp_data->value.type.
characterstring_encoding(&value.type.
Character_String);
if (encoding == CHARACTER_ANSI_X34) {
status =
Device_Set_Object_Name(characterstring_value(&wp_data->
value.type.Character_String),
characterstring_length(&wp_data->value.type.
characterstring_length(&value.type.
Character_String));
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
+16 -7
View File
@@ -30,7 +30,8 @@
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
@@ -243,6 +244,8 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
Life_Safety_Point_Init();
@@ -251,16 +254,22 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_MODE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((wp_data->value.type.Enumerated >= MIN_LIFE_SAFETY_MODE) &&
case PROP_MODE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value.type.Enumerated >= MIN_LIFE_SAFETY_MODE) &&
(value.type.Enumerated <= MIN_LIFE_SAFETY_MODE)) {
object_index =
Life_Safety_Point_Instance_To_Index(wp_data->
object_instance);
Life_Safety_Point_Mode[object_index] =
Life_Safety_Point_Mode[object_index] =
value.type.Enumerated;
status = true;
} else {
@@ -272,12 +281,12 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Life_Safety_Point_Instance_To_Index(wp_data->
object_instance);
Life_Safety_Point_Out_Of_Service[object_index] =
Life_Safety_Point_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
+16 -7
View File
@@ -30,7 +30,8 @@
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
@@ -281,6 +282,8 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
unsigned int object_index = 0;
unsigned int priority = 0;
uint32_t level = 0;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
Multistate_Output_Init();
if (!Multistate_Output_Valid_Instance(wp_data->object_instance)) {
@@ -289,18 +292,24 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(
wp_data->application_data,
wp_data->application_data_len,
&value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(wp_data->value.type.Unsigned_Int <=
(value.type.Unsigned_Int <=
MULTISTATE_NUMBER_OF_STATES)) {
level = wp_data->value.type.Unsigned_Int;
level = value.type.Unsigned_Int;
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
@@ -322,7 +331,7 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = MULTISTATE_NULL;
object_index =
Multistate_Output_Instance_To_Index(wp_data->
@@ -348,12 +357,12 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
}
break;
case PROP_OUT_OF_SERVICE:
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
Multistate_Output_Out_Of_Service[object_index] =
wp_data->value.type.Boolean;
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
+6 -12
View File
@@ -126,21 +126,15 @@ int wp_decode_service_request(uint8_t * apdu,
/* Tag 3: opening context tag */
if (!decode_is_opening_tag_number(&apdu[len], 3))
return -1;
/* determine the length of the data blob */
data->application_data_len = bacapp_data_len(&apdu[len],
apdu_len-len, property);
/* a tag number of 3 is not extended so only one octet */
len++;
/* determine the length of the data blob */
/* FIXME: decode the length of the context specific tag value */
if (decode_is_context_specific(&apdu[len]))
return -2;
/* FIXME: what if the length is more than 255 */
len += bacapp_decode_application_data(&apdu[len],
(uint8_t)(apdu_len - len), &data->value);
/* FIXME: check the return value; abort if no valid data? */
/* FIXME: there might be more than one data element in here! */
/* add on the data length */
len += data->application_data_len;
if (!decode_is_closing_tag_number(&apdu[len], 3))
return -4;
return -2;
/* a tag number of 3 is not extended so only one octet */
len++;
/* Tag 4: optional Priority - assumed MAX if not explicitly set */