Пример #1
0
int bacapp_decode_assigned_access_rights(
    uint8_t * apdu,
    BACNET_ASSIGNED_ACCESS_RIGHTS * aar)
{
    int len;
    int apdu_len = 0;

    if (decode_is_context_tag(&apdu[apdu_len], 0)) {
        len =
            bacapp_decode_context_device_obj_ref(&apdu[apdu_len], 0,
            &aar->assigned_access_rights);
        if (len < 0)
            return -1;
        else
            apdu_len += len;
    } else
        return -1;

    if (decode_is_context_tag(&apdu[apdu_len], 1)) {
        len = decode_context_boolean2(&apdu[apdu_len], 1, &aar->enable);
        if (len < 0)
            return -1;
        else
            apdu_len += len;
    } else
        return -1;

    return apdu_len;
}
Пример #2
0
/* decode the service request only */
int whohas_decode_service_request(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_WHO_HAS_DATA * data)
{
    int len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value = 0;
    uint32_t decoded_value = 0; /* for decoding */
    uint16_t decoded_type = 0;  /* for decoding */

    if (apdu_len && data) {
        /* optional limits - must be used as a pair */
        if (decode_is_context_tag(&apdu[len], 0)) {
            len +=
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value);
            len += decode_unsigned(&apdu[len], len_value, &decoded_value);
            if (decoded_value <= BACNET_MAX_INSTANCE)
                data->low_limit = decoded_value;
            if (!decode_is_context_tag(&apdu[len], 1))
                return -1;
            len +=
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value);
            len += decode_unsigned(&apdu[len], len_value, &decoded_value);
            if (decoded_value <= BACNET_MAX_INSTANCE)
                data->high_limit = decoded_value;
        } else {
            data->low_limit = -1;
            data->high_limit = -1;
        }
        /* object id */
        if (decode_is_context_tag(&apdu[len], 2)) {
            data->object_name = false;
            len +=
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value);
            len +=
                decode_object_id(&apdu[len], &decoded_type,
                &data->object.identifier.instance);
            data->object.identifier.type = decoded_type;
        }
        /* object name */
        else if (decode_is_context_tag(&apdu[len], 3)) {
            data->object_name = true;
            len +=
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value);
            len +=
                decode_character_string(&apdu[len], len_value,
                &data->object.name);
        }
        /* missing required parameters */
        else
            return -1;
    }

    return len;
}
Пример #3
0
/* 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;
}
Пример #4
0
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;
}
Пример #5
0
/* decode the object portion of the service request only */
int rpm_ack_decode_object_id(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_OBJECT_TYPE * object_type,
    uint32_t * object_instance)
{
    unsigned len = 0;
    uint16_t type = 0;  /* for decoding */

    /* check for value pointers */
    if (apdu && apdu_len && object_type && object_instance) {
        /* Tag 0: objectIdentifier */
        if (!decode_is_context_tag(&apdu[len++], 0))
            return -1;
        len += decode_object_id(&apdu[len], &type, object_instance);
        if (object_type)
            *object_type = (BACNET_OBJECT_TYPE) type;
        /* Tag 1: listOfResults */
        if (!decode_is_opening_tag_number(&apdu[len], 1))
            return -1;
        len++;  /* opening tag is only one octet */
    }

    return (int) len;
}
Пример #6
0
/* decode the object portion of the service request only. Bails out if
 * tags are wrong or missing/incomplete
 */
int rpm_decode_object_id(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_RPM_DATA * rpmdata)
{
    unsigned len = 0;
    uint16_t type = 0;  /* for decoding */

    /* check for value pointers */
    if (apdu && apdu_len && rpmdata) {
        if (apdu_len < 5) {     /* Must be at least 2 tags and an object id */
            rpmdata->error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
            return BACNET_STATUS_REJECT;
        }
        /* Tag 0: Object ID */
        if (!decode_is_context_tag(&apdu[len++], 0)) {
            rpmdata->error_code = ERROR_CODE_REJECT_INVALID_TAG;
            return BACNET_STATUS_REJECT;
        }
        len += decode_object_id(&apdu[len], &type, &rpmdata->object_instance);
        rpmdata->object_type = (BACNET_OBJECT_TYPE) type;
        /* Tag 1: sequence of ReadAccessSpecification */
        if (!decode_is_opening_tag_number(&apdu[len], 1)) {
            rpmdata->error_code = ERROR_CODE_REJECT_INVALID_TAG;
            return BACNET_STATUS_REJECT;
        }
        len++;  /* opening tag is only one octet */
    }

    return (int) len;
}
Пример #7
0
/* BACnetDeviceObjectReference ::= SEQUENCE {
    device-identifier [0] BACnetObjectIdentifier OPTIONAL,
    object-identifier [1] BACnetObjectIdentifier
}*/
int bacapp_decode_device_obj_ref(
    uint8_t * apdu,
    BACNET_DEVICE_OBJECT_REFERENCE * value)
{
    int len;
    int apdu_len = 0;

    /* device-identifier [0] BACnetObjectIdentifier OPTIONAL */
    if (decode_is_context_tag(&apdu[apdu_len], 0) &&
        !decode_is_closing_tag(&apdu[apdu_len])) {
        if (-1 == (len =
                decode_context_object_id(&apdu[apdu_len], 0,
                    &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;
    }
    /* object-identifier [1] BACnetObjectIdentifier */
    if (-1 == (len =
            decode_context_object_id(&apdu[apdu_len], 1,
                &value->objectIdentifier.type,
                &value->objectIdentifier.instance))) {
        return -1;
    }
    apdu_len += len;

    return apdu_len;
}
Пример #8
0
int bacapp_decode_device_obj_ref(
    uint8_t * apdu,
    BACNET_DEVICE_OBJECT_REFERENCE * value)
{
    int len;
    int apdu_len = 0;

    /* Device ID is optional */
    if (decode_is_context_tag(&apdu[apdu_len], 0)) {
        if (-1 == (len =
                decode_context_object_id(&apdu[apdu_len], 0,
                    &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;
    }

    if (-1 == (len =
            decode_context_object_id(&apdu[apdu_len], 1,
                &value->objectIdentifier.type,
                &value->objectIdentifier.instance))) {
        return -1;
    }
    apdu_len += len;

    return apdu_len;
}
Пример #9
0
int rp_ack_decode_service_request(
    uint8_t * apdu,
    int apdu_len,       /* total length of the apdu */
    BACNET_READ_PROPERTY_DATA * rpdata)
{

    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    int tag_len = 0;    /* length of tag decode */
    int len = 0;        /* total length of decodes */
    uint16_t object = 0;        /* object type */
    uint32_t property = 0;      /* for decoding */
    uint32_t array_value = 0;   /* for decoding */


	memset(prop_name,0,100);
    /* FIXME: check apdu_len against the len during decode   */
    /* Tag 0: Object ID */
    if (!decode_is_context_tag(&apdu[0], 0))
        return -1;
    len = 1;
    len += decode_object_id(&apdu[len], &object, &rpdata->object_instance);
    rpdata->object_type = (BACNET_OBJECT_TYPE) object;
    /* Tag 1: Property ID */
    len +=
        decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type);
    if (tag_number != 1)
        return -1;
    len += decode_enumerated(&apdu[len], len_value_type, &property);
    rpdata->object_property = (BACNET_PROPERTY_ID) property;
	

	if(rpdata->object_property < PROP_EGRESS_ACTIVE)
		strcpy_s(prop_name,100,bacnet_property_names[rpdata->object_property ].pString);
    /* Tag 2: Optional Array Index */
    tag_len =
        decode_tag_number_and_value(&apdu[len], &tag_number, &len_value_type);
    if (tag_number == 2) {
        len += tag_len;
        len += decode_unsigned(&apdu[len], len_value_type, &array_value);
        rpdata->array_index = array_value;
    } else
        rpdata->array_index = BACNET_ARRAY_ALL;
    /* Tag 3: opening context tag */
    if (decode_is_opening_tag_number(&apdu[len], 3)) {
        /* a tag number of 3 is not extended so only one octet */
        len++;
        /* don't decode the application tag number or its data here */
        rpdata->application_data = &apdu[len];
        rpdata->application_data_len = apdu_len - len - 1 /*closing tag */ ;
        /* len includes the data and the closing tag */
        len = apdu_len;
    } else {
        return -1;
    }

    return len;
}
Пример #10
0
int Lighting_Output_Decode_Lighting_Command(
    uint8_t * apdu,
    unsigned apdu_max_len,
    BACNET_LIGHTING_COMMAND * data)
{
    int len = 0;
    int apdu_len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    float real_value = 0.0;

    apdu_max_len = apdu_max_len;

    /* check for value pointers */
    if (apdu_len && data) {
        /* Tag 0: operation */
        if (!decode_is_context_tag(&apdu[apdu_len], 0))
            return -1;
        len =
            decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
            &len_value_type);
        apdu_len += len;
        len =
            decode_enumerated(&apdu[apdu_len], len_value_type,
            (uint32_t *) & data->operation);
        apdu_len += len;
        /* Tag 1: level - OPTIONAL */
        if (decode_is_context_tag(&apdu[apdu_len], 1)) {
            len =
                decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
                &len_value_type);
            apdu_len += len;
            len = decode_real(&apdu[apdu_len], &real_value);
            apdu_len += len;
            data->level = (uint8_t) real_value;
            /* FIXME: are we going to flag errors in decoding values here? */
        }
        /* FIXME: finish me! */
        /* Tag 2:  */

    }

    return len;
}
Пример #11
0
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;
}
Пример #12
0
/* decode the service request only */
int rd_decode_service_request(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_REINITIALIZED_STATE * state,
    BACNET_CHARACTER_STRING * password)
{
    unsigned len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    uint32_t value = 0;

    /* check for value pointers */
    if (apdu_len) {
        /* Tag 0: reinitializedStateOfDevice */
        if (!decode_is_context_tag(&apdu[len], 0))
            return -1;
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number,
            &len_value_type);
        len += decode_enumerated(&apdu[len], len_value_type, &value);
        if (state)
            *state = (BACNET_REINITIALIZED_STATE) value;
        /* Tag 1: password - optional */
        if (len < apdu_len) {
            if (!decode_is_context_tag(&apdu[len], 1))
                return -1;
            len +=
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value_type);
            len +=
                decode_character_string(&apdu[len], len_value_type, password);
        }
    }

    return (int) len;
}
Пример #13
0
/* decode the service request only */
int rp_decode_service_request(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_READ_PROPERTY_DATA * rpdata)
{
    unsigned len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    uint16_t type = 0;  /* for decoding */
    uint32_t property = 0;      /* for decoding */
    uint32_t array_value = 0;   /* for decoding */

    /* check for value pointers */
    if (rpdata != NULL) {
        /* Must have at least 2 tags, an object id and a property identifier
         * of at least 1 byte in length to have any chance of parsing */
        if (apdu_len < 7) {
            rpdata->error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
            return BACNET_STATUS_REJECT;
        }

        /* Tag 0: Object ID          */
        if (!decode_is_context_tag(&apdu[len++], 0)) {
            rpdata->error_code = ERROR_CODE_REJECT_INVALID_TAG;
            return BACNET_STATUS_REJECT;
        }
        len += decode_object_id(&apdu[len], &type, &rpdata->object_instance);
        rpdata->object_type = (BACNET_OBJECT_TYPE) type;
        /* Tag 1: Property ID */
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number,
            &len_value_type);
        if (tag_number != 1) {
            rpdata->error_code = ERROR_CODE_REJECT_INVALID_TAG;
            return BACNET_STATUS_REJECT;
        }
        len += decode_enumerated(&apdu[len], len_value_type, &property);
        rpdata->object_property = (BACNET_PROPERTY_ID) property;
        /* Tag 2: Optional Array Index */
        if (len < apdu_len) {
            len +=
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value_type);
            if ((tag_number == 2) && (len < apdu_len)) {
                len +=
                    decode_unsigned(&apdu[len], len_value_type, &array_value);
                rpdata->array_index = array_value;
            } else {
                rpdata->error_code = ERROR_CODE_REJECT_INVALID_TAG;
                return BACNET_STATUS_REJECT;
            }
        } else
            rpdata->array_index = BACNET_ARRAY_ALL;
    }

    if (len < apdu_len) {
        /* If something left over now, we have an invalid request */
        rpdata->error_code = ERROR_CODE_REJECT_TOO_MANY_ARGUMENTS;
        return BACNET_STATUS_REJECT;
    }

    return (int) len;
}
Пример #14
0
/**
 * Decodes from bytes into the lighting-command structure
 *
 * @param apdu - buffer to hold the bytes
 * @param apdu_max_len - number of bytes in the buffer to decode
 * @param value - lighting command value to place the decoded values
 *
 * @return  number of bytes encoded
 */
int lighting_command_decode(
    uint8_t * apdu,
    unsigned apdu_max_len,
    BACNET_LIGHTING_COMMAND * data)
{
    int len = 0;
    int apdu_len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    uint32_t unsigned_value = 0;
    float real_value = 0.0;

    unused_var(apdu_max_len);
    /* check for value pointers */
    if (apdu_max_len && data) {
        /* Tag 0: operation */
        if (!decode_is_context_tag(&apdu[apdu_len], 0))
            return BACNET_STATUS_ERROR;
        len =
            decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
            &len_value_type);
        apdu_len += len;
        len =
            decode_enumerated(&apdu[apdu_len], len_value_type, &unsigned_value);
        if (len > 0) {
            data->operation = unsigned_value;
        }
        apdu_len += len;
        /* Tag 1: target-level - OPTIONAL */
        if (decode_is_context_tag(&apdu[apdu_len], 1)) {
            len =
                decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
                &len_value_type);
            apdu_len += len;
            len = decode_real(&apdu[apdu_len], &real_value);
            data->target_level = real_value;
            apdu_len += len;
            data->use_target_level = true;
        } else {
            data->use_target_level = false;
        }
        /* Tag 2: ramp-rate - OPTIONAL */
        if (decode_is_context_tag(&apdu[apdu_len], 2)) {
            len =
                decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
                &len_value_type);
            apdu_len += len;
            len = decode_real(&apdu[apdu_len], &real_value);
            data->ramp_rate = real_value;
            data->use_ramp_rate = true;
        } else {
            data->use_ramp_rate = false;
        }
        /* Tag 3: step-increment - OPTIONAL */
        if (decode_is_context_tag(&apdu[apdu_len], 3)) {
            len =
                decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
                &len_value_type);
            apdu_len += len;
            len = decode_real(&apdu[apdu_len], &real_value);
            data->step_increment = real_value;
            data->use_step_increment = true;
        } else {
            data->use_step_increment = false;
        }
        /* Tag 4: fade-time - OPTIONAL */
        if (decode_is_context_tag(&apdu[apdu_len], 4)) {
            len =
                decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
                &len_value_type);
            apdu_len += len;
            len = decode_unsigned(&apdu[apdu_len], len_value_type,
                &unsigned_value);
            data->fade_time = unsigned_value;
            data->use_fade_time = true;
        } else {
            data->use_fade_time = false;
        }
        /* Tag 5: priority - OPTIONAL */
        if (decode_is_context_tag(&apdu[apdu_len], 4)) {
            len =
                decode_tag_number_and_value(&apdu[apdu_len], &tag_number,
                &len_value_type);
            apdu_len += len;
            len = decode_unsigned(&apdu[apdu_len], len_value_type,
                &unsigned_value);
            data->priority = unsigned_value;
            data->use_priority = true;
        } else {
            data->use_priority = false;
        }
    }

    return len;
}
Пример #15
0
bool Notification_Class_Write_Property(
    BACNET_WRITE_PROPERTY_DATA * wp_data)
{
    NOTIFICATION_CLASS_INFO *CurrentNotify;
    NOTIFICATION_CLASS_INFO TmpNotify;
    BACNET_APPLICATION_DATA_VALUE value;
    bool status = false;
    int iOffset = 0;
    uint8_t idx = 0;
    int len = 0;



    CurrentNotify =
        &NC_Info[Notification_Class_Instance_To_Index(wp_data->
            object_instance)];

    /* decode the some of the request
     */
    len =
        bacapp_decode_application_data(wp_data->application_data,
        wp_data->application_data_len, &value);
    if (len < 0) {
        /* error while decoding - a value larger than we can handle */
        wp_data->error_class = ERROR_CLASS_PROPERTY;
        wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
        return false;
    }
    if ((wp_data->object_property != PROP_PRIORITY) &&
        (wp_data->array_index != BACNET_ARRAY_ALL)) {
        /*  only array properties can have array options */
        wp_data->error_class = ERROR_CLASS_PROPERTY;
        wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
        return false;
    }
    switch (wp_data->object_property) {
        case PROP_PRIORITY:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_UNSIGNED_INT,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                if (wp_data->array_index == 0) {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
                } else if (wp_data->array_index == BACNET_ARRAY_ALL) {
                    /* FIXME: wite all array */
                } else if (wp_data->array_index <= 3) {
                    CurrentNotify->Priority[wp_data->array_index - 1] =
                        value.type.Unsigned_Int;
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
                }
            }
            break;

        case PROP_ACK_REQUIRED:
            status =
                WPValidateArgType(&value, BACNET_APPLICATION_TAG_BIT_STRING,
                &wp_data->error_class, &wp_data->error_code);

            if (status) {
                if (value.type.Bit_String.bits_used == 3) {
                    CurrentNotify->Ack_Required =
                        value.type.Bit_String.value[0];
                } else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
                }
            }
            break;

        case PROP_RECIPIENT_LIST:

            memset(&TmpNotify, 0x00, sizeof(NOTIFICATION_CLASS_INFO));

            /* decode all packed */
            while (iOffset < wp_data->application_data_len) {
                /* Decode Valid Days */
                len =
                    bacapp_decode_application_data(&wp_data->
                    application_data[iOffset], wp_data->application_data_len,
                    &value);

                if ((len == 0) ||
                    (value.tag != BACNET_APPLICATION_TAG_BIT_STRING)) {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }

                if (value.type.Bit_String.bits_used == MAX_BACNET_DAYS_OF_WEEK)
                    /* store value */
                    TmpNotify.Recipient_List[idx].ValidDays =
                        value.type.Bit_String.value[0];
                else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_OTHER;
                    return false;
                }

                iOffset += len;
                /* Decode From Time */
                len =
                    bacapp_decode_application_data(&wp_data->
                    application_data[iOffset], wp_data->application_data_len,
                    &value);

                if ((len == 0) || (value.tag != BACNET_APPLICATION_TAG_TIME)) {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }
                /* store value */
                TmpNotify.Recipient_List[idx].FromTime = value.type.Time;

                iOffset += len;
                /* Decode To Time */
                len =
                    bacapp_decode_application_data(&wp_data->
                    application_data[iOffset], wp_data->application_data_len,
                    &value);

                if ((len == 0) || (value.tag != BACNET_APPLICATION_TAG_TIME)) {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }
                /* store value */
                TmpNotify.Recipient_List[idx].ToTime = value.type.Time;

                iOffset += len;
                /* context tag [0] - Device */
                if (decode_is_context_tag(&wp_data->application_data[iOffset],
                        0)) {
                    TmpNotify.Recipient_List[idx].Recipient.RecipientType =
                        RECIPIENT_TYPE_DEVICE;
                    /* Decode Network Number */
                    len =
                        bacapp_decode_context_data(&wp_data->
                        application_data[iOffset],
                        wp_data->application_data_len, &value,
                        PROP_RECIPIENT_LIST);

                    if ((len == 0) ||
                        (value.tag != BACNET_APPLICATION_TAG_OBJECT_ID)) {
                        /* Bad decode, wrong tag or following required parameter missing */
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                        return false;
                    }
                    /* store value */
                    TmpNotify.Recipient_List[idx].Recipient._.
                        DeviceIdentifier = value.type.Object_Id.instance;

                    iOffset += len;
                }
                /* opening tag [1] - Recipient */
                else if (decode_is_opening_tag_number(&wp_data->
                        application_data[iOffset], 1)) {
                    iOffset++;
                    TmpNotify.Recipient_List[idx].Recipient.RecipientType =
                        RECIPIENT_TYPE_ADDRESS;
                    /* Decode Network Number */
                    len =
                        bacapp_decode_application_data(&wp_data->
                        application_data[iOffset],
                        wp_data->application_data_len, &value);

                    if ((len == 0) ||
                        (value.tag != BACNET_APPLICATION_TAG_UNSIGNED_INT)) {
                        /* Bad decode, wrong tag or following required parameter missing */
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                        return false;
                    }
                    /* store value */
                    TmpNotify.Recipient_List[idx].Recipient._.Address.net =
                        value.type.Unsigned_Int;

                    iOffset += len;
                    /* Decode Address */
                    len =
                        bacapp_decode_application_data(&wp_data->
                        application_data[iOffset],
                        wp_data->application_data_len, &value);

                    if ((len == 0) ||
                        (value.tag != BACNET_APPLICATION_TAG_OCTET_STRING)) {
                        /* Bad decode, wrong tag or following required parameter missing */
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                        return false;
                    }
                    /* store value */
                    if (TmpNotify.Recipient_List[idx].Recipient._.Address.
                        net == 0) {
                        memcpy(TmpNotify.Recipient_List[idx].Recipient._.
                            Address.mac, value.type.Octet_String.value,
                            value.type.Octet_String.length);
                        TmpNotify.Recipient_List[idx].Recipient._.Address.
                            mac_len = value.type.Octet_String.length;
                    } else {
                        memcpy(TmpNotify.Recipient_List[idx].Recipient._.
                            Address.adr, value.type.Octet_String.value,
                            value.type.Octet_String.length);
                        TmpNotify.Recipient_List[idx].Recipient._.Address.len =
                            value.type.Octet_String.length;
                    }

                    iOffset += len;
                    /* closing tag [1] - Recipient */
                    if (decode_is_closing_tag_number(&wp_data->
                            application_data[iOffset], 1))
                        iOffset++;
                    else {
                        /* Bad decode, wrong tag or following required parameter missing */
                        wp_data->error_class = ERROR_CLASS_PROPERTY;
                        wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                        return false;
                    }
                } else {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }

                /* Process Identifier */
                len =
                    bacapp_decode_application_data(&wp_data->
                    application_data[iOffset], wp_data->application_data_len,
                    &value);

                if ((len == 0) ||
                    (value.tag != BACNET_APPLICATION_TAG_UNSIGNED_INT)) {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }
                /* store value */
                TmpNotify.Recipient_List[idx].ProcessIdentifier =
                    value.type.Unsigned_Int;

                iOffset += len;
                /* Issue Confirmed Notifications */
                len =
                    bacapp_decode_application_data(&wp_data->
                    application_data[iOffset], wp_data->application_data_len,
                    &value);

                if ((len == 0) ||
                    (value.tag != BACNET_APPLICATION_TAG_BOOLEAN)) {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }
                /* store value */
                TmpNotify.Recipient_List[idx].ConfirmedNotify =
                    value.type.Boolean;

                iOffset += len;
                /* Transitions */
                len =
                    bacapp_decode_application_data(&wp_data->
                    application_data[iOffset], wp_data->application_data_len,
                    &value);

                if ((len == 0) ||
                    (value.tag != BACNET_APPLICATION_TAG_BIT_STRING)) {
                    /* Bad decode, wrong tag or following required parameter missing */
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
                    return false;
                }

                if (value.type.Bit_String.bits_used ==
                    MAX_BACNET_EVENT_TRANSITION)
                    /* store value */
                    TmpNotify.Recipient_List[idx].Transitions =
                        value.type.Bit_String.value[0];
                else {
                    wp_data->error_class = ERROR_CLASS_PROPERTY;
                    wp_data->error_code = ERROR_CODE_OTHER;
                    return false;
                }
                iOffset += len;

                /* Increasing element of list */
                if (++idx >= NC_MAX_RECIPIENTS) {
                    wp_data->error_class = ERROR_CLASS_RESOURCES;
                    wp_data->error_code =
                        ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
                    return false;
                }
            }

            /* Decoded all recipient list */
            /* copy elements from temporary object */
            for (idx = 0; idx < NC_MAX_RECIPIENTS; idx++) {
                BACNET_ADDRESS src = { 0 };
                unsigned max_apdu = 0;
                int32_t DeviceID;

                CurrentNotify->Recipient_List[idx] =
                    TmpNotify.Recipient_List[idx];

                if (CurrentNotify->Recipient_List[idx].Recipient.
                    RecipientType == RECIPIENT_TYPE_DEVICE) {
                    /* copy Device_ID */
                    DeviceID =
                        CurrentNotify->Recipient_List[idx].Recipient._.
                        DeviceIdentifier;
                    address_bind_request(DeviceID, &max_apdu, &src);

                } else if (CurrentNotify->Recipient_List[idx].Recipient.
                    RecipientType == RECIPIENT_TYPE_ADDRESS) {
                    /* copy Address */
                    /* src = CurrentNotify->Recipient_List[idx].Recipient._.Address; */
                    /* address_bind_request(BACNET_MAX_INSTANCE, &max_apdu, &src); */
                }
            }

            status = true;

            break;

        default:
            wp_data->error_class = ERROR_CLASS_PROPERTY;
            wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
            break;
    }

    return status;
}
Пример #16
0
int bacapp_decode_access_rule(
    uint8_t * apdu,
    BACNET_ACCESS_RULE * rule)
{
    int len;
    int apdu_len = 0;

    if (decode_is_context_tag(&apdu[apdu_len], 0)) {
        len =
            decode_context_enumerated(&apdu[apdu_len], 0,
            &rule->time_range_specifier);
        if (len < 0)
            return -1;
        else
            apdu_len += len;
    } else
        return -1;

    if (rule->time_range_specifier == TIME_RANGE_SPECIFIER_SPECIFIED) {
        if (decode_is_context_tag(&apdu[apdu_len], 1)) {
            len =
                bacapp_decode_context_device_obj_property_ref(&apdu[apdu_len],
                1, &rule->time_range);
            if (len < 0)
                return -1;
            else
                apdu_len += len;
        } else
            return -1;
    }

    if (decode_is_context_tag(&apdu[apdu_len], 2)) {
        len =
            decode_context_enumerated(&apdu[apdu_len], 2,
            &rule->location_specifier);
        if (len < 0)
            return -1;
        else
            apdu_len += len;
    } else
        return -1;

    if (rule->location_specifier == LOCATION_SPECIFIER_SPECIFIED) {
        if (decode_is_context_tag(&apdu[apdu_len], 3)) {
            len =
                bacapp_decode_context_device_obj_property_ref(&apdu[apdu_len],
                3, &rule->location);
            if (len < 0)
                return -1;
            else
                apdu_len += len;
        } else
            return -1;
    }

    if (decode_is_context_tag(&apdu[apdu_len], 4)) {
        len = decode_context_boolean2(&apdu[apdu_len], 4, &rule->enable);
        if (len < 0)
            return -1;
        else
            apdu_len += len;
    } else
        return -1;

    return apdu_len;
}
Пример #17
0
/* FIXME: there could be various error messages returned
   using unique values less than zero */
int wp_decode_service_request(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_WRITE_PROPERTY_DATA * wpdata)
{
    int len = 0;
    int tag_len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    uint16_t type = 0;  /* for decoding */
    uint32_t property = 0;      /* for decoding */
    uint32_t unsigned_value = 0;
    int i = 0;  /* loop counter */

    /* check for value pointers */
    if (apdu_len && wpdata) {
        /* Tag 0: Object ID          */
        if (!decode_is_context_tag(&apdu[len++], 0))
            return -1;
        len += decode_object_id(&apdu[len], &type, &wpdata->object_instance);
        wpdata->object_type = (BACNET_OBJECT_TYPE) type;
        /* Tag 1: Property ID */
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number,
            &len_value_type);
        if (tag_number != 1)
            return -1;
        len += decode_enumerated(&apdu[len], len_value_type, &property);
        wpdata->object_property = (BACNET_PROPERTY_ID) property;
        /* Tag 2: Optional Array Index */
        /* note: decode without incrementing len so we can check for opening tag */
        tag_len =
            decode_tag_number_and_value(&apdu[len], &tag_number,
            &len_value_type);
        if (tag_number == 2) {
            len += tag_len;
            len +=
                decode_unsigned(&apdu[len], len_value_type, &unsigned_value);
            wpdata->array_index = unsigned_value;
        } else
            wpdata->array_index = BACNET_ARRAY_ALL;
        /* Tag 3: opening context tag */
        if (!decode_is_opening_tag_number(&apdu[len], 3))
            return -1;
        /* determine the length of the data blob */
        wpdata->application_data_len =
            bacapp_data_len(&apdu[len], apdu_len - len,
            (BACNET_PROPERTY_ID) property);
        /* a tag number of 3 is not extended so only one octet */
        len++;
        /* copy the data from the APDU */
        for (i = 0; i < wpdata->application_data_len; i++) {
            wpdata->application_data[i] = apdu[len + i];
        }
        /* add on the data length */
        len += wpdata->application_data_len;
        if (!decode_is_closing_tag_number(&apdu[len], 3))
            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 */
        wpdata->priority = BACNET_MAX_PRIORITY;
        if ((unsigned) 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);
                if ((unsigned_value >= BACNET_MIN_PRIORITY)
                    && (unsigned_value <= BACNET_MAX_PRIORITY)) {
                    wpdata->priority = (uint8_t) unsigned_value;
                } else
                    return -5;
            }
        }
    }

    return len;
}