Beispiel #1
0
void Send_UnconfirmedPrivateTransfer(
    BACNET_ADDRESS * dest,
    BACNET_PRIVATE_TRANSFER_DATA * private_data)
{
    int len = 0;
    int pdu_len = 0;
    int bytes_sent = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;
    if (!dcc_communication_enabled())
        return;
    datalink_get_my_address(&my_address);
    /* encode the NPDU portion of the packet */
    npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
    pdu_len =
        npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
        &npdu_data);
    /* encode the APDU portion of the packet */
    len =
        ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],invoke_id,
        private_data);
    pdu_len += len;
    bytes_sent =
        datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);
#if PRINT_ENABLED
    if (bytes_sent <= 0)
        fprintf(stderr,
            "Failed to Send UnconfirmedPrivateTransfer Request (%s)!\n",
            strerror(errno));
#endif
}
Beispiel #2
0
void test_Private_Transfer_Ack(
    Test * pTest)
{
    uint8_t apdu[480] = { 0 };
    int len = 0;
    int apdu_len = 0;
    uint8_t invoke_id = 128;
    uint8_t test_invoke_id = 0;
    BACNET_PRIVATE_TRANSFER_DATA private_data;
    BACNET_PRIVATE_TRANSFER_DATA test_data;
    uint8_t test_value[480] = { 0 };
    int private_data_len = 0;
    char private_data_chunk[33] = { "00112233445566778899AABBCCDDEEFF" };
    BACNET_APPLICATION_DATA_VALUE data_value;
    BACNET_APPLICATION_DATA_VALUE test_data_value;
    bool status = false;

    private_data.vendorID = BACNET_VENDOR_ID;
    private_data.serviceNumber = 1;

    status =
        bacapp_parse_application_data(BACNET_APPLICATION_TAG_OCTET_STRING,
        &private_data_chunk[0], &data_value);
    ct_test(pTest, status == true);
    private_data_len =
        bacapp_encode_application_data(&test_value[0], &data_value);

    private_data.serviceParameters = &test_value[0];
    private_data.serviceParametersLen = private_data_len;


    len = ptransfer_ack_encode_apdu(&apdu[0], invoke_id, &private_data);
    ct_test(pTest, len != 0);
    ct_test(pTest, len != -1);
    apdu_len = len;
    len =
        ptransfer_ack_decode_apdu(&apdu[0], apdu_len, &test_invoke_id,
        &test_data);
    ct_test(pTest, len != -1);
    ct_test(pTest, test_invoke_id == invoke_id);
    ct_test(pTest, test_data.vendorID == private_data.vendorID);
    ct_test(pTest, test_data.serviceNumber == private_data.serviceNumber);
    ct_test(pTest,
        test_data.serviceParametersLen == private_data.serviceParametersLen);
    len =
        bacapp_decode_application_data(test_data.serviceParameters,
        test_data.serviceParametersLen, &test_data_value);
    ct_test(pTest, bacapp_same_value(&data_value, &test_data_value) == true);
}
Beispiel #3
0
void handler_conf_private_trans(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src,
    BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
    BACNET_PRIVATE_TRANSFER_DATA data;
    int len;
    int pdu_len;
    bool error;
    int bytes_sent;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ADDRESS my_address;
    BACNET_ERROR_CLASS error_class;
    BACNET_ERROR_CODE error_code;

    len = 0;
    pdu_len = 0;
    error = false;
    bytes_sent = 0;
    error_class = ERROR_CLASS_OBJECT;
    error_code = ERROR_CODE_UNKNOWN_OBJECT;

#if PRINT_ENABLED
    fprintf(stderr, "Received Confirmed Private Transfer Request!\n");
#endif
    /* encode the NPDU portion of the response packet as it will be needed */
    /* no matter what the outcome. */

    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, "CPT: Segmented Message. Sending Abort!\n");
#endif
        goto CPT_ABORT;
    }

    len =
        ptransfer_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, "CPT: Bad Encoding. Sending Abort!\n");
#endif
        goto CPT_ABORT;
    }

    /*  Simple example with service number of 0 for
       read block and 1 for write block
       We also only support our own vendor ID.
       In theory we could support others
       for compatability purposes but these
       interfaces are rarely documented... */
    if ((data.vendorID == BACNET_VENDOR_ID) &&
        (data.serviceNumber <= MY_SVC_WRITE)) {
        /* We only try to understand our own IDs and service numbers */
        /* Will either return a result block or an app level status block */
        ProcessPT(&data);
        if (data.serviceParametersLen == 0) {
            /* No respopnse means fatal error */
            error = true;
            error_class = ERROR_CLASS_SERVICES;
            error_code = ERROR_CODE_OTHER;
#if PRINT_ENABLED
            fprintf(stderr, "CPT: Error servicing request!\n");
#endif
        }
        len =
            ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, &data);
    } else {    /* Not our vendor ID or bad service parameter */

        error = true;
        error_class = ERROR_CLASS_SERVICES;
        error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
#if PRINT_ENABLED
        fprintf(stderr, "CPT: Not our Vendor ID or invalid service code!\n");
#endif
    }

    if (error) {
        len =
            ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, error_class, error_code, &data);
    }
  CPT_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;
}