Пример #1
0
int ptransfer_ack_decode_apdu(
    uint8_t * apdu,
    int apdu_len,       /* total length of the apdu */
    uint8_t * invoke_id,
    BACNET_PRIVATE_TRANSFER_DATA * private_data)
{
    int len = 0;
    int offset = 0;

    if (!apdu)
        return -1;
    /* optional checking - most likely was already done prior to this call */
    if (apdu[0] != PDU_TYPE_COMPLEX_ACK)
        return -1;
    *invoke_id = apdu[1];
    if (apdu[2] != SERVICE_CONFIRMED_PRIVATE_TRANSFER)
        return -1;
    offset = 3;
    if (apdu_len > offset) {
        len =
            ptransfer_decode_service_request(&apdu[offset], apdu_len - offset,
            private_data);
    }

    return len;
}
Пример #2
0
int uptransfer_decode_apdu(
    uint8_t * apdu,
    unsigned apdu_len,
    BACNET_PRIVATE_TRANSFER_DATA * private_data)
{
    int len = 0;
    unsigned offset = 0;

    if (!apdu) {
        return -1;
    }
    /* optional checking - most likely was already done prior to this call */
    if (apdu[0] != PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST) {
        return -1;
    }
    if (apdu[1] != SERVICE_UNCONFIRMED_PRIVATE_TRANSFER) {
        return -1;
    }
    offset = 2;
    if (apdu_len > offset) {
        len =
            ptransfer_decode_service_request(&apdu[offset], apdu_len - offset,
            private_data);
    }

    return len;
}
Пример #3
0
int ptransfer_decode_apdu(
    uint8_t * apdu,
    unsigned apdu_len,
    uint8_t * invoke_id,
    BACNET_PRIVATE_TRANSFER_DATA * private_data)
{
    int len = 0;
    unsigned offset = 0;

    if (!apdu)
        return -1;
    /* optional checking - most likely was already done prior to this call */
    if (apdu[0] != PDU_TYPE_CONFIRMED_SERVICE_REQUEST)
        return -1;
    /*  apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU); */
    /* invoke id - filled in by net layer */
    *invoke_id = apdu[2];
    if (apdu[3] != SERVICE_CONFIRMED_PRIVATE_TRANSFER)
        return -1;
    offset = 4;

    if (apdu_len > offset) {
        len =
            ptransfer_decode_service_request(&apdu[offset], apdu_len - offset,
            private_data);
    }

    return len;
}
Пример #4
0
void handler_conf_private_trans_ack(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src,
    BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
{
    BACNET_PRIVATE_TRANSFER_DATA data;
    int len;

/*
 * Note:
 * We currently don't look at the source address and service data
 * but we probably should to verify that the ack is oneit is what
 * we were expecting. But this is just to silence some compiler
 * warnings from Borland.
 */
    src = src;
    service_data = service_data;

    len = 0;



#if PRINT_ENABLED
    printf("Received Confirmed Private Transfer Ack!\n");
#endif

    len = ptransfer_decode_service_request(service_request, service_len, &data);        /* Same decode for ack as for service request! */
    if (len < 0) {
#if PRINT_ENABLED
        printf("cpta: Bad Encoding!\n");
#endif
    }

    ProcessPTA(&data);  /* See what to do with the response */

    return;
}
Пример #5
0
void handler_unconfirmed_private_transfer(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src)
{
    BACNET_PRIVATE_TRANSFER_DATA private_data;
    int len = 0;

#if PRINT_ENABLED
    fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n");
#endif
    (void) src;
    len =
        ptransfer_decode_service_request(service_request, service_len,
        &private_data);
    if (len >= 0) {
#if PRINT_ENABLED
        fprintf(stderr,
            "UnconfirmedPrivateTransfer: " "vendorID=%u serviceNumber=%u\n",
            private_data.vendorID, private_data.serviceNumber);
#endif
    }
}
Пример #6
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;
}