예제 #1
0
int wp_decode_apdu(
    uint8_t * apdu,
    unsigned apdu_len,
    uint8_t * invoke_id,
    BACNET_WRITE_PROPERTY_DATA * wpdata)
{
    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 = apdu[2];       /* invoke id - filled in by net layer */
    if (apdu[3] != SERVICE_CONFIRMED_WRITE_PROPERTY)
        return -1;
    offset = 4;

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

    return len;
}
예제 #2
0
파일: h_wp.c 프로젝트: HITliuyu/NES15_HEVC
/** Handler for a WriteProperty Service request.
 * @ingroup DSWP
 * This handler will be invoked by apdu_handler() if it has been enabled
 * by a call to apdu_set_confirmed_handler().
 * This handler builds a response packet, which is
 * - an Abort if
 *   - the message is segmented
 *   - if decoding fails
 * - an ACK if Device_Write_Property() succeeds
 * - an Error if Device_Write_Property() fails
 *   or there isn't enough room in the APDU to fit the data.
 *
 * @param service_request [in] The contents of the service request.
 * @param service_len [in] The length of the service_request.
 * @param src [in] BACNET_ADDRESS of the source of the message
 * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
 *                          decoded from the APDU header of this message.
 */
void handler_write_property(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src,
    BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
    BACNET_WRITE_PROPERTY_DATA wp_data;
    int len = 0;
    int pdu_len = 0;
    BACNET_NPDU_DATA npdu_data;
    int bytes_sent = 0;
    BACNET_ADDRESS my_address;

    /* 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 PRINT_ENABLED
    fprintf(stderr, "WP: Received Request!\n");
#endif
    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, "WP: Segmented message.  Sending Abort!\n");
#endif
        goto WP_ABORT;
    }   /* decode the service request only */
    len = wp_decode_service_request(service_request, service_len, &wp_data);
#if PRINT_ENABLED
    if (len > 0)
        fprintf(stderr,
            "WP: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n",
            (unsigned long) wp_data.object_type,
            (unsigned long) wp_data.object_instance,
            (unsigned long) wp_data.object_property,
            (unsigned long) wp_data.priority, (long) wp_data.array_index);
    else
        fprintf(stderr, "WP: Unable to decode Request!\n");
#endif
    /* bad decoding or something we didn't understand - 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, "WP: Bad Encoding. Sending Abort!\n");
#endif
        goto WP_ABORT;
    }
    if (Device_Write_Property(&wp_data)) {
        len =
            encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
        fprintf(stderr, "WP: Sending Simple Ack!\n");
#endif
    } else {
        len =
            bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
            wp_data.error_class, wp_data.error_code);
#if PRINT_ENABLED
        fprintf(stderr, "WP: Sending Error!\n");
#endif
    }
  WP_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, "WP: Failed to send PDU (%s)!\n", strerror(errno));
    }
#else
    bytes_sent = bytes_sent;
#endif

    return;
}
예제 #3
0
파일: h_wp.c 프로젝트: HITliuyu/NES15_HEVC
void handler_write_property(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src,
    BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
    BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
    int bytes_sent = 0;
    BACNET_ADDRESS my_address;

    /* decode the service request only */
    len = wp_decode_service_request(service_request, service_len, &wp_data);
    /* 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);
    /* bad decoding or something we didn't understand - send an abort */
    if (len <= 0) {
        len =
            abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, ABORT_REASON_OTHER, true);
    } else if (service_data->segmented_message) {
        len =
            abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
            true);
    } else {
        switch (wp_data.object_type) {
            case OBJECT_DEVICE:
                if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
                    len =
                        encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id,
                        SERVICE_CONFIRMED_WRITE_PROPERTY);
                } else {
                    len =
                        bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id,
                        SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
                        error_code);
                }
                break;
            case OBJECT_ANALOG_VALUE:
                if (Analog_Value_Write_Property(&wp_data, &error_class,
                        &error_code)) {
                    len =
                        encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id,
                        SERVICE_CONFIRMED_WRITE_PROPERTY);
                } else {
                    len =
                        bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id,
                        SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
                        error_code);
                }
                break;
            case OBJECT_BINARY_VALUE:
                if (Binary_Value_Write_Property(&wp_data, &error_class,
                        &error_code)) {
                    len =
                        encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id,
                        SERVICE_CONFIRMED_WRITE_PROPERTY);
                } else {
                    len =
                        bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                        service_data->invoke_id,
                        SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
                        error_code);
                }
                break;
            default:
                len =
                    bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
                    error_class, error_code);
                break;
        }
    }
    pdu_len += len;
    bytes_sent =
        datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
        pdu_len);

    return;
}
예제 #4
0
파일: h_wp.c 프로젝트: Jongil-Park/Lin_PRJ
void handler_write_property(
    uint8_t * service_request,
    uint16_t service_len,
    BACNET_ADDRESS * src,
    BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
    int len = 0;
    int pdu_len = 0;
    BACNET_NPDU_DATA npdu_data;
    BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
    BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
    int bytes_sent = 0;
    BACNET_ADDRESS my_address;

    /* 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);
        goto WP_ABORT;
    }
    /* decode the service request only */
    len = wp_decode_service_request(service_request, service_len, &wp_data);
    /* bad decoding or something we didn't understand - send an abort */
    if (len <= 0) {
        len =
            abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
            service_data->invoke_id, ABORT_REASON_OTHER, true);
        goto WP_ABORT;
    }
    switch (wp_data.object_type) {
        case OBJECT_DEVICE:
            if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
                len =
                    encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
                fprintf(stderr,
                    "Sending Write Property Simple Ack for Device!\n");
#endif
            } else {
                len =
                    bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
                    error_class, error_code);
#if PRINT_ENABLED
                fprintf(stderr, "Sending Write Property Error for Device!\n");
#endif
            }
            break;
        case OBJECT_ANALOG_INPUT:
        case OBJECT_BINARY_INPUT:
            error_class = ERROR_CLASS_PROPERTY;
            error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
            len =
                bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
                error_class, error_code);
#if PRINT_ENABLED
            fprintf(stderr, "Sending Write Access Error!\n");
#endif
            break;
        case OBJECT_BINARY_VALUE:
            if (Binary_Value_Write_Property(&wp_data, &error_class,
                    &error_code)) {
                len =
                    encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
                fprintf(stderr, "Sending Write Property Simple Ack for BV!\n");
#endif
            } else {
                len =
                    bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
                    error_class, error_code);
#if PRINT_ENABLED
                fprintf(stderr, "Sending Write Access Error for BV!\n");
#endif
            }
            break;
        case OBJECT_ANALOG_VALUE:
            if (Analog_Value_Write_Property(&wp_data, &error_class,
                    &error_code)) {
                len =
                    encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
                fprintf(stderr, "Sending Write Property Simple Ack for AV!\n");
#endif
            } else {
                len =
                    bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                    service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
                    error_class, error_code);
#if PRINT_ENABLED
                fprintf(stderr, "Sending Write Access Error for AV!\n");
#endif
            }
            break;
        default:
            len =
                bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
                service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
                error_class, error_code);
#if PRINT_ENABLED
            fprintf(stderr, "Sending Unknown Object Error!\n");
#endif
            break;
    }
  WP_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;
}