/*************************************************** ** ** Decodes the service data part of Event Notification ** ****************************************************/ int alarm_ack_decode_service_request( uint8_t * apdu, unsigned apdu_len, BACNET_ALARM_ACK_DATA * data) { int len = 0; int section_len; uint32_t enumValue; /* unused parameter */ unused_var(apdu_len); if (-1 == (section_len = decode_context_unsigned(&apdu[len], 0, &data->ackProcessIdentifier))) { return -1; } len += section_len; if (-1 == (section_len = decode_context_object_id(&apdu[len], 1, &data->eventObjectIdentifier.type, &data->eventObjectIdentifier.instance))) { return -1; } len += section_len; if (-1 == (section_len = decode_context_enumerated(&apdu[len], 2, &enumValue))) { return -1; } data->eventStateAcked = (BACNET_EVENT_STATE) enumValue; len += section_len; if (-1 == (section_len = bacapp_decode_context_timestamp(&apdu[len], 3, &data->eventTimeStamp))) { return -1; } len += section_len; if (-1 == (section_len = decode_context_character_string(&apdu[len], 4, &data->ackSource))) { return -1; } len += section_len; if (-1 == (section_len = bacapp_decode_context_timestamp(&apdu[len], 5, &data->ackTimeStamp))) { return -1; } len += section_len; return len; }
int lso_decode_service_request( uint8_t * apdu, unsigned apdu_len, BACNET_LSO_DATA * data) { int len = 0; /* return value */ int section_length = 0; /* length returned from decoding */ uint32_t operation = 0; /* handles decoded value */ /* check for value pointers */ if (apdu_len && data) { /* Tag 0: Object ID */ if ((section_length = decode_context_unsigned(&apdu[len], 0, &data->processId)) == -1) { return -1; } len += section_length; if ((section_length = decode_context_character_string(&apdu[len], 1, &data->requestingSrc)) == -1) { return -1; } len += section_length; if ((section_length = decode_context_enumerated(&apdu[len], 2, &operation)) == -1) { return -1; } data->operation = (BACNET_LIFE_SAFETY_OPERATION) operation; len += section_length; /* ** This is an optional parameter, so dont fail if it doesnt exist */ if (decode_is_context_tag(&apdu[len], 3)) { if ((section_length = decode_context_object_id(&apdu[len], 3, &data->targetObject.type, &data->targetObject.instance)) == -1) { return -1; } len += section_length; } else { data->targetObject.type = 0; data->targetObject.instance = 0; } return len; } return 0; }
/* decode the service request only */ int ptransfer_decode_service_request( uint8_t * apdu, unsigned apdu_len, BACNET_PRIVATE_TRANSFER_DATA * private_data) { int len = 0; /* return value */ int decode_len = 0; /* return value */ uint32_t unsigned_value = 0; /* check for value pointers */ if (apdu_len && private_data) { /* Tag 0: vendorID */ decode_len = decode_context_unsigned(&apdu[len], 0, &unsigned_value); if (decode_len < 0) { return -1; } len = decode_len; private_data->vendorID = (uint16_t) unsigned_value; /* Tag 1: serviceNumber */ decode_len = decode_context_unsigned(&apdu[len], 1, &unsigned_value); if (decode_len < 0) { return -1; } len += decode_len; private_data->serviceNumber = unsigned_value; /* Tag 2: serviceParameters */ if (decode_is_opening_tag_number(&apdu[len], 2)) { /* a tag number of 2 is not extended so only one octet */ len++; /* don't decode the serviceParameters here */ private_data->serviceParameters = &apdu[len]; private_data->serviceParametersLen = (int) apdu_len - len - 1 /*closing tag */ ; /* len includes the data and the closing tag */ len = (int) apdu_len; } else { return -1; } } return len; }
/* BACnetDeviceObjectPropertyReference ::= SEQUENCE { object-identifier [0] BACnetObjectIdentifier, property-identifier [1] BACnetPropertyIdentifier, property-array-index [2] Unsigned OPTIONAL, -- used only with array datatype -- if omitted with an array then -- the entire array is referenced device-identifier [3] BACnetObjectIdentifier OPTIONAL } */ int bacapp_decode_device_obj_property_ref( uint8_t * apdu, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) { int len; int apdu_len = 0; uint32_t enumValue; /* object-identifier [0] BACnetObjectIdentifier */ if (-1 == (len = decode_context_object_id(&apdu[apdu_len], 0, &value->objectIdentifier.type, &value->objectIdentifier.instance))) { return -1; } apdu_len += len; /* property-identifier [1] BACnetPropertyIdentifier */ if (-1 == (len = decode_context_enumerated(&apdu[apdu_len], 1, &enumValue))) { return -1; } value->propertyIdentifier = (BACNET_PROPERTY_ID) enumValue; apdu_len += len; /* property-array-index [2] Unsigned OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 2) && !decode_is_closing_tag(&apdu[apdu_len])) { if (-1 == (len = decode_context_unsigned(&apdu[apdu_len], 2, &value->arrayIndex))) { return -1; } apdu_len += len; } else { value->arrayIndex = BACNET_ARRAY_ALL; } /* device-identifier [3] BACnetObjectIdentifier OPTIONAL */ if (decode_is_context_tag(&apdu[apdu_len], 3) && !decode_is_closing_tag(&apdu[apdu_len])) { if (-1 == (len = decode_context_object_id(&apdu[apdu_len], 3, &value->deviceIndentifier.type, &value->deviceIndentifier.instance))) { return -1; } apdu_len += len; } else { value->deviceIndentifier.type = BACNET_NO_DEV_TYPE; value->deviceIndentifier.instance = BACNET_NO_DEV_ID; } return apdu_len; }
int bacapp_decode_device_obj_property_ref( uint8_t * apdu, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) { int len; int apdu_len = 0; uint32_t enumValue; if (-1 == (len = decode_context_object_id(&apdu[apdu_len], 0, &value->objectIdentifier.type, &value->objectIdentifier.instance))) { return -1; } apdu_len += len; if (-1 == (len = decode_context_enumerated(&apdu[apdu_len], 1, &enumValue))) { return -1; } value->propertyIdentifier = (BACNET_PROPERTY_ID) enumValue; apdu_len += len; if (decode_is_context_tag(&apdu[apdu_len], 2)) { if (-1 == (len = decode_context_unsigned(&apdu[apdu_len], 2, &value->arrayIndex))) { return -1; } apdu_len += len; } else { value->arrayIndex = BACNET_ARRAY_ALL; } if (decode_is_context_tag(&apdu[apdu_len], 3)) { if (-1 == (len = decode_context_object_id(&apdu[apdu_len], 3, &value->deviceIndentifier.type, &value->deviceIndentifier.instance))) { return -1; } apdu_len += len; } else { value->deviceIndentifier.type = BACNET_NO_DEV_TYPE; value->deviceIndentifier.instance = BACNET_NO_DEV_ID; } return apdu_len; }
/* decode the service request only */ int ptransfer_error_decode_service_request( uint8_t * apdu, unsigned apdu_len, BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code, BACNET_PRIVATE_TRANSFER_DATA * private_data) { int len = 0; /* return value */ int decode_len = 0; /* return value */ uint8_t tag_number = 0; uint32_t len_value_type = 0; uint32_t unsigned_value = 0; /* check for value pointers */ if (apdu_len && private_data) { /* Tag 0: Error */ if (decode_is_opening_tag_number(&apdu[len], 0)) { /* a tag number of 0 is not extended so only one octet */ len++; /* error class */ decode_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += decode_len; if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return 0; } decode_len = decode_enumerated(&apdu[len], len_value_type, &unsigned_value); len += decode_len; if (error_class) { *error_class = (BACNET_ERROR_CLASS) unsigned_value; } /* error code */ decode_len = decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type); len += decode_len; if (tag_number != BACNET_APPLICATION_TAG_ENUMERATED) { return 0; } decode_len = decode_enumerated(&apdu[len], len_value_type, &unsigned_value); len += decode_len; if (error_code) { *error_code = (BACNET_ERROR_CODE) unsigned_value; } if (decode_is_closing_tag_number(&apdu[len], 0)) { /* a tag number of 0 is not extended so only one octet */ len++; } else { return 0; } } /* Tag 1: vendorID */ decode_len = decode_context_unsigned(&apdu[len], 1, &unsigned_value); if (decode_len < 0) { return -1; } len += decode_len; private_data->vendorID = (uint16_t) unsigned_value; /* Tag 2: serviceNumber */ decode_len = decode_context_unsigned(&apdu[len], 2, &unsigned_value); if (decode_len < 0) { return -1; } len += decode_len; private_data->serviceNumber = unsigned_value; /* Tag 3: serviceParameters */ if (decode_is_opening_tag_number(&apdu[len], 3)) { /* a tag number of 2 is not extended so only one octet */ len++; /* don't decode the serviceParameters here */ private_data->serviceParameters = &apdu[len]; private_data->serviceParametersLen = (int) apdu_len - len - 1 /*closing tag */ ; } else { return -1; } /* we could check for a closing tag of 3 */ } return len; }
int bacapp_decode_timestamp( uint8_t * apdu, BACNET_TIMESTAMP * value) { int len = 0; int section_len; uint32_t len_value_type; uint32_t sequenceNum; if (apdu) { section_len = decode_tag_number_and_value(&apdu[len], &value->tag, &len_value_type); if (-1 == section_len) { return -1; } switch (value->tag) { case TIME_STAMP_TIME: if ((section_len = decode_context_bacnet_time(&apdu[len], TIME_STAMP_TIME, &value->value.time)) == -1) { return -1; } else { len += section_len; } break; case TIME_STAMP_SEQUENCE: if ((section_len = decode_context_unsigned(&apdu[len], TIME_STAMP_SEQUENCE, &sequenceNum)) == -1) { return -1; } else { if (sequenceNum <= 0xffff) { len += section_len; value->value.sequenceNum = (uint16_t) sequenceNum; } else { return -1; } } break; case TIME_STAMP_DATETIME: if ((section_len = bacapp_decode_context_datetime(&apdu[len], TIME_STAMP_DATETIME, &value->value.dateTime)) == -1) { return -1; } else { len += section_len; } break; default: return -1; } } return len; }