Пример #1
0
void testBinary_Value(
    Test * pTest)
{
    uint8_t apdu[MAX_APDU] = { 0 };
    int len = 0;
    uint32_t len_value = 0;
    uint8_t tag_number = 0;
    uint16_t decoded_type = 0;
    uint32_t decoded_instance = 0;
    BACNET_READ_PROPERTY_DATA rpdata;

    Binary_Value_Init();
    rpdata.application_data = &apdu[0];
    rpdata.application_data_len = sizeof(apdu);
    rpdata.object_type = OBJECT_BINARY_VALUE;
    rpdata.object_instance = 1;
    rpdata.object_property = PROP_OBJECT_IDENTIFIER;
    rpdata.array_index = BACNET_ARRAY_ALL;
    len = Binary_Value_Read_Property(&rpdata);
    ct_test(pTest, len != 0);
    len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
    ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
    len = decode_object_id(&apdu[len], &decoded_type, &decoded_instance);
    ct_test(pTest, decoded_type == rpdata.object_type);
    ct_test(pTest, decoded_instance == rpdata.object_instance);

    return;
}
Пример #2
0
void testBinaryInput(
    Test * pTest)
{
    uint8_t apdu[MAX_APDU] = { 0 };
    int len = 0;
    uint32_t len_value = 0;
    uint8_t tag_number = 0;
    BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_OUTPUT;
    uint32_t decoded_instance = 0;
    uint32_t instance = 123;
    BACNET_ERROR_CLASS error_class;
    BACNET_ERROR_CODE error_code;


    /* FIXME: we should do a lot more testing here... */
    len =
        Binary_Input_Encode_Property_APDU(&apdu[0], instance,
        PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
    ct_test(pTest, len >= 0);
    len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
    ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
    len =
        decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
    ct_test(pTest, decoded_type == OBJECT_BINARY_INPUT);
    ct_test(pTest, decoded_instance == instance);

    return;
}
Пример #3
0
void testAnalog_Value(
    Test * pTest)
{
    uint8_t far apdu[MAX_APDU] = { 0 };
    int len = 0;
    uint32_t len_value = 0;
    uint8_t tag_number = 0;
    BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE;
    uint32_t decoded_instance = 0;
    uint32_t instance = 123;
    BACNET_ERROR_CLASS error_class;
    BACNET_ERROR_CODE error_code;

    len =
        Analog_Value_Encode_Property_APDU(&apdu[0], instance,
        PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
    ct_test(pTest, len != 0);
    len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
    ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
    len =
        decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
    ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE);
    ct_test(pTest, decoded_instance == instance);

    return;
}
Пример #4
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;
}
Пример #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
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;
}
Пример #8
0
/* decode the service request only */
int ihave_decode_service_request(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_I_HAVE_DATA * data)
{
    int len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value = 0;
    uint16_t decoded_type = 0;  /* for decoding */

    if (apdu_len && data) {
        /* deviceIdentifier */
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
        if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) {
            len +=
                decode_object_id(&apdu[len], &decoded_type,
                &data->device_id.instance);
            data->device_id.type = decoded_type;
        } else
            return -1;
        /* objectIdentifier */
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
        if (tag_number == BACNET_APPLICATION_TAG_OBJECT_ID) {
            len +=
                decode_object_id(&apdu[len], &decoded_type,
                &data->object_id.instance);
            data->object_id.type = decoded_type;
        } else
            return -1;
        /* objectName */
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
        if (tag_number == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
            len +=
                decode_character_string(&apdu[len], len_value,
                &data->object_name);
        } else
            return -1;
    } else
        return -1;

    return len;
}
Пример #9
0
void testReadPropertyAck(
    Test * pTest)
{
    uint8_t apdu[480] = { 0 };
    uint8_t apdu2[480] = { 0 };
    int len = 0;
    int apdu_len = 0;
    uint8_t invoke_id = 1;
    uint8_t test_invoke_id = 0;
    BACNET_READ_PROPERTY_DATA rpdata;
    BACNET_READ_PROPERTY_DATA test_data;
    BACNET_OBJECT_TYPE object_type = OBJECT_DEVICE;
    uint32_t object_instance = 0;
    uint16_t object = 0;

    rpdata.object_type = OBJECT_DEVICE;
    rpdata.object_instance = 1;
    rpdata.object_property = PROP_OBJECT_IDENTIFIER;
    rpdata.array_index = BACNET_ARRAY_ALL;

    rpdata.application_data_len =
        encode_bacnet_object_id(&apdu2[0], rpdata.object_type,
        rpdata.object_instance);
    rpdata.application_data = &apdu2[0];

    len = rp_ack_encode_apdu(&apdu[0], invoke_id, &rpdata);
    ct_test(pTest, len != 0);
    ct_test(pTest, len != -1);
    apdu_len = len;
    len = rp_ack_decode_apdu(&apdu[0], apdu_len,        /* total length of the apdu */
        &test_invoke_id, &test_data);
    ct_test(pTest, len != -1);
    ct_test(pTest, test_invoke_id == invoke_id);

    ct_test(pTest, test_data.object_type == rpdata.object_type);
    ct_test(pTest, test_data.object_instance == rpdata.object_instance);
    ct_test(pTest, test_data.object_property == rpdata.object_property);
    ct_test(pTest, test_data.array_index == rpdata.array_index);
    ct_test(pTest,
        test_data.application_data_len == rpdata.application_data_len);

    /* since object property == object_id, decode the application data using
       the appropriate decode function */
    len =
        decode_object_id(test_data.application_data, &object,
        &object_instance);
    object_type = object;
    ct_test(pTest, object_type == rpdata.object_type);
    ct_test(pTest, object_instance == rpdata.object_instance);
}
Пример #10
0
/** Decoding for WritePropertyMultiple service, object ID.
 * @ingroup DSWPM
 * This handler will be invoked by write_property_multiple handler
 * if it has been enabled by a call to apdu_set_confirmed_handler().
 * This function decodes only the first tagged entity, which is
 * an object identifier.  This function will return an error if:
 *   - the tag is not the right value
 *   - the number of bytes is not enough to decode for this entity
 *   - the subsequent tag number is incorrect
 *
 * @param apdu [in] The contents of the APDU buffer.
 * @param apdu_len [in] The length of the APDU buffer.
 * @param data [out] The BACNET_WRITE_PROPERTY_DATA structure
 *    which will contain the reponse values or error.
 */
int wpm_decode_object_id(
    uint8_t * apdu,
    uint16_t apdu_len,
    BACNET_WRITE_PROPERTY_DATA * wp_data)
{
    uint8_t tag_number = 0;
    uint32_t len_value = 0;
    uint32_t object_instance = 0;
    uint16_t object_type = 0;
    uint16_t len = 0;

    if (apdu && (apdu_len > 5) && wp_data) {
        /* Context tag 0 - Object ID */
        len +=
            decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
        if ((tag_number == 0) && (apdu_len > len)) {
            apdu_len -= len;
            if (apdu_len >= 4) {
                len +=
                    decode_object_id(&apdu[len], &object_type,
                    &object_instance);
                wp_data->object_type = object_type;
                wp_data->object_instance = object_instance;
                apdu_len -= len;
            } else {
                wp_data->error_code =
                    ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
                return BACNET_STATUS_REJECT;
            }
        } else {
            wp_data->error_code = ERROR_CODE_REJECT_INVALID_TAG;
            return BACNET_STATUS_REJECT;
        }
        /* just test for the next tag - no need to decode it here */
        /* Context tag 1: sequence of BACnetPropertyValue */
        if (apdu_len && !decode_is_opening_tag_number(&apdu[len], 1)) {
            wp_data->error_code = ERROR_CODE_REJECT_INVALID_TAG;
            return BACNET_STATUS_REJECT;
        }
    } else {
        wp_data->error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER;
        return BACNET_STATUS_REJECT;
    }

    return (int) len;
}
Пример #11
0
/* decode the service request only */
int arf_decode_service_request(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_ATOMIC_READ_FILE_DATA * data)
{
    int len = 0;
    int tag_len = 0;
    uint8_t tag_number = 0;
    uint32_t len_value_type = 0;
    uint16_t type = 0;  /* for decoding */

    /* check for value pointers */
    if (apdu_len && data) {
        len =
            decode_tag_number_and_value(&apdu[0], &tag_number,
            &len_value_type);
        if (tag_number != BACNET_APPLICATION_TAG_OBJECT_ID)
            return -1;
        len += decode_object_id(&apdu[len], &type, &data->object_instance);
        data->object_type = (BACNET_OBJECT_TYPE) type;
        if (decode_is_opening_tag_number(&apdu[len], 0)) {
            data->access = FILE_STREAM_ACCESS;
            /* a tag number is not extended so only one octet */
            len++;
            /* fileStartPosition */
            tag_len =
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value_type);
            len += tag_len;
            if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT)
                return -1;
            len +=
                decode_signed(&apdu[len], len_value_type,
                &data->type.stream.fileStartPosition);
            /* requestedOctetCount */
            tag_len =
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value_type);
            len += tag_len;
            if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
                return -1;
            len +=
                decode_unsigned(&apdu[len], len_value_type,
                &data->type.stream.requestedOctetCount);
            if (!decode_is_closing_tag_number(&apdu[len], 0))
                return -1;
            /* a tag number is not extended so only one octet */
            len++;
        } else if (decode_is_opening_tag_number(&apdu[len], 1)) {
            data->access = FILE_RECORD_ACCESS;
            /* a tag number is not extended so only one octet */
            len++;
            /* fileStartRecord */
            tag_len =
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value_type);
            len += tag_len;
            if (tag_number != BACNET_APPLICATION_TAG_SIGNED_INT)
                return -1;
            len +=
                decode_signed(&apdu[len], len_value_type,
                &data->type.record.fileStartRecord);
            /* RecordCount */
            tag_len =
                decode_tag_number_and_value(&apdu[len], &tag_number,
                &len_value_type);
            len += tag_len;
            if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
                return -1;
            len +=
                decode_unsigned(&apdu[len], len_value_type,
                &data->type.record.RecordCount);
            if (!decode_is_closing_tag_number(&apdu[len], 1))
                return -1;
            /* a tag number is not extended so only one octet */
            len++;
        } else
            return -1;
    }

    return len;
}
Пример #12
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;
}
Пример #13
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;
}