Exemple #1
0
void testAtomicReadFileAckAccess(
    Test * pTest,
    BACNET_ATOMIC_READ_FILE_DATA * data)
{
    BACNET_ATOMIC_READ_FILE_DATA test_data = { 0 };
    uint8_t apdu[480] = { 0 };
    int len = 0;
    int apdu_len = 0;
    uint8_t invoke_id = 128;
    uint8_t test_invoke_id = 0;
    unsigned int i = 0;

    len = arf_ack_encode_apdu(&apdu[0], invoke_id, data);
    ct_test(pTest, len != 0);
    apdu_len = len;

    len = arf_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id, &test_data);
    ct_test(pTest, len != -1);
    ct_test(pTest, test_data.endOfFile == data->endOfFile);
    ct_test(pTest, test_data.access == data->access);
    if (test_data.access == FILE_STREAM_ACCESS) {
        ct_test(pTest,
            test_data.type.stream.fileStartPosition ==
            data->type.stream.fileStartPosition);
        ct_test(pTest,
            octetstring_length(&test_data.fileData[0]) ==
            octetstring_length(&data->fileData[0]));
        ct_test(pTest, memcmp(octetstring_value(&test_data.fileData[0]),
                octetstring_value(&data->fileData[0]),
                octetstring_length(&test_data.fileData[0])) == 0);
    } else if (test_data.access == FILE_RECORD_ACCESS) {
        ct_test(pTest,
            test_data.type.record.fileStartRecord ==
            data->type.record.fileStartRecord);
        ct_test(pTest,
            test_data.type.record.RecordCount ==
            data->type.record.RecordCount);
        for (i = 0; i < data->type.record.RecordCount; i++) {
            ct_test(pTest,
                octetstring_length(&test_data.fileData[i]) ==
                octetstring_length(&data->fileData[i]));
            ct_test(pTest, memcmp(octetstring_value(&test_data.fileData[i]),
                    octetstring_value(&data->fileData[i]),
                    octetstring_length(&test_data.fileData[i])) == 0);
        }
    }
}
Exemple #2
0
void handler_atomic_read_file(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src,
    BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
    BACNET_ATOMIC_READ_FILE_DATA data;
    int len = 0;
    int pdu_len = 0;
    bool error = false;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;
    BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
    BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;

#if PRINT_ENABLED
    fprintf(stderr, "Received Atomic-Read-File Request!\n");
#endif
    /* encode the NPDU portion of the packet */
    datalink_get_my_address(&my_address);
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
        &npdu_data);
    if (service_data->segmented_message) {
        len =
            abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
            true);
#if PRINT_ENABLED
        fprintf(stderr, "ARF: Segmented Message. Sending Abort!\n");
#endif
        goto ARF_ABORT;
    }
    len = arf_decode_service_request(service_request, service_len, &data);
    /* bad decoding - send an abort */
    if (len < 0) {
        len =
            abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, ABORT_REASON_OTHER, true);
#if PRINT_ENABLED
        fprintf(stderr, "Bad Encoding. Sending Abort!\n");
#endif
        goto ARF_ABORT;
    }
    if (data.object_type == OBJECT_FILE) {
        if (!bacfile_valid_instance(data.object_instance)) {
            error = true;
        } else if (data.access == FILE_STREAM_ACCESS) {
            if (data.type.stream.requestedOctetCount <
                octetstring_capacity(&data.fileData[0])) {
                if (bacfile_read_stream_data(&data)) {
#if PRINT_ENABLED
                    fprintf(stderr, "ARF: Stream offset %d, %d octets.\n",
                        data.type.stream.fileStartPosition,
                        data.type.stream.requestedOctetCount);
#endif
                    len =
                        arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id, &data);
                } else {
                    error = true;
                    error_class = ERROR_CLASS_OBJECT;
                    error_code = ERROR_CODE_FILE_ACCESS_DENIED;
                }
            } else {
                len =
                    abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id,
                    ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
                fprintf(stderr, "Too Big To Send (%d >= %d). Sending Abort!\n",
                    data.type.stream.requestedOctetCount,
                    octetstring_capacity(&data.fileData[0]));
#endif
            }
        } else if (data.access == FILE_RECORD_ACCESS) {
            if (data.type.record.fileStartRecord >=
                BACNET_READ_FILE_RECORD_COUNT) {
                error_class = ERROR_CLASS_SERVICES;
                error_code = ERROR_CODE_INVALID_FILE_START_POSITION;
                error = true;
            } else if (bacfile_read_stream_data(&data)) {
#if PRINT_ENABLED
                fprintf(stderr, "ARF: fileStartRecord %d, %u RecordCount.\n",
                    data.type.record.fileStartRecord,
                    data.type.record.RecordCount);
#endif
                len =
                    arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, &data);
            } else {
                error = true;
                error_class = ERROR_CLASS_OBJECT;
                error_code = ERROR_CODE_FILE_ACCESS_DENIED;
            }
        } else {
            error = true;
            error_class = ERROR_CLASS_SERVICES;
            error_code = ERROR_CODE_INVALID_FILE_ACCESS_METHOD;
#if PRINT_ENABLED
            fprintf(stderr, "Record Access Requested. Sending Error!\n");
#endif
        }
    } else {
        error = true;
        error_class = ERROR_CLASS_SERVICES;
        error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE;
    }
    if (error) {
        len =
            bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_READ_FILE,
            error_class, error_code);
    }
  ARF_ABORT:
    pdu_len += len;
    bytes_sent =
        datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0) {
        fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
    }
#endif

    return;
}