From 993acb494affae95312958dd4cba2e9860143779 Mon Sep 17 00:00:00 2001 From: Roy Schneider Date: Thu, 13 Aug 2020 17:18:50 +0200 Subject: [PATCH] Replaced gotos in handler code (#109) --- src/bacnet/basic/service/h_rp.c | 129 +++++++++++++++++--------------- src/bacnet/basic/service/h_rr.c | 120 ++++++++++++++++------------- 2 files changed, 137 insertions(+), 112 deletions(-) diff --git a/src/bacnet/basic/service/h_rp.c b/src/bacnet/basic/service/h_rp.c index f4a3f2e6..a408b693 100644 --- a/src/bacnet/basic/service/h_rp.c +++ b/src/bacnet/basic/service/h_rp.c @@ -86,77 +86,82 @@ void handler_read_property(uint8_t *service_request, npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_len = npdu_encode_pdu( &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); - if (service_data->segmented_message) { + if (npdu_len <= 0) { + /* If 0 or negative, there were problems with the data or encoding. */ + len = BACNET_STATUS_ABORT; + #if PRINT_ENABLED + fprintf(stderr, "RP: npdu_encode_pdu error. Sending Abort!\n"); + #endif + } else if (service_data->segmented_message) { /* we don't support segmentation - send an abort */ len = BACNET_STATUS_ABORT; #if PRINT_ENABLED fprintf(stderr, "RP: Segmented message. Sending Abort!\n"); #endif - goto RP_FAILURE; - } - len = rp_decode_service_request(service_request, service_len, &rpdata); -#if PRINT_ENABLED - if (len <= 0) { - fprintf(stderr, "RP: Unable to decode Request!\n"); - } -#endif - if (len < 0) { - /* bad decoding - skip to error/reject/abort handling */ - error = true; -#if PRINT_ENABLED - fprintf(stderr, "RP: Bad Encoding.\n"); -#endif - goto RP_FAILURE; - } - /* Test for case of indefinite Device object instance */ - if ((rpdata.object_type == OBJECT_DEVICE) && - (rpdata.object_instance == BACNET_MAX_INSTANCE)) { - rpdata.object_instance = Device_Object_Instance_Number(); - } - - apdu_len = rp_ack_encode_apdu_init( - &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, &rpdata); - /* configure our storage */ - rpdata.application_data = &Handler_Transmit_Buffer[npdu_len + apdu_len]; - rpdata.application_data_len = - sizeof(Handler_Transmit_Buffer) - (npdu_len + apdu_len); - len = Device_Read_Property(&rpdata); - if (len >= 0) { - apdu_len += len; - len = rp_ack_encode_apdu_object_property_end( - &Handler_Transmit_Buffer[npdu_len + apdu_len]); - apdu_len += len; - if (apdu_len > service_data->max_resp) { - /* too big for the sender - send an abort - * Setting of error code needed here as read property processing may - * have overriden the default set at start */ - rpdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; - len = BACNET_STATUS_ABORT; -#if PRINT_ENABLED - fprintf(stderr, "RP: Message too large.\n"); -#endif - } else { -#if PRINT_ENABLED - fprintf(stderr, "RP: Sending Ack!\n"); -#endif - error = false; - } } else { -#if PRINT_ENABLED - fprintf(stderr, "RP: Device_Read_Property: "); - if (len == BACNET_STATUS_ABORT) { - fprintf(stderr, "Abort!\n"); - } else if (len == BACNET_STATUS_ERROR) { - fprintf(stderr, "Error!\n"); - } else if (len == BACNET_STATUS_REJECT) { - fprintf(stderr, "Reject!\n"); - } else { - fprintf(stderr, "Unknown Len=%d\n", len); + len = rp_decode_service_request(service_request, service_len, &rpdata); + #if PRINT_ENABLED + if (len <= 0) { + fprintf(stderr, "RP: Unable to decode Request!\n"); + } + #endif + if (len < 0) { + /* bad decoding - skip to error/reject/abort handling */ + error = true; + #if PRINT_ENABLED + fprintf(stderr, "RP: Bad Encoding.\n"); + #endif + } else { + /* Test for case of indefinite Device object instance */ + if ((rpdata.object_type == OBJECT_DEVICE) && + (rpdata.object_instance == BACNET_MAX_INSTANCE)) { + rpdata.object_instance = Device_Object_Instance_Number(); + } + + apdu_len = rp_ack_encode_apdu_init( + &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id, &rpdata); + /* configure our storage */ + rpdata.application_data = &Handler_Transmit_Buffer[npdu_len + apdu_len]; + rpdata.application_data_len = + sizeof(Handler_Transmit_Buffer) - (npdu_len + apdu_len); + len = Device_Read_Property(&rpdata); + if (len >= 0) { + apdu_len += len; + len = rp_ack_encode_apdu_object_property_end( + &Handler_Transmit_Buffer[npdu_len + apdu_len]); + apdu_len += len; + if (apdu_len > service_data->max_resp) { + /* too big for the sender - send an abort + * Setting of error code needed here as read property processing may + * have overriden the default set at start */ + rpdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; + len = BACNET_STATUS_ABORT; + #if PRINT_ENABLED + fprintf(stderr, "RP: Message too large.\n"); + #endif + } else { + #if PRINT_ENABLED + fprintf(stderr, "RP: Sending Ack!\n"); + #endif + error = false; + } + } else { + #if PRINT_ENABLED + fprintf(stderr, "RP: Device_Read_Property: "); + if (len == BACNET_STATUS_ABORT) { + fprintf(stderr, "Abort!\n"); + } else if (len == BACNET_STATUS_ERROR) { + fprintf(stderr, "Error!\n"); + } else if (len == BACNET_STATUS_REJECT) { + fprintf(stderr, "Reject!\n"); + } else { + fprintf(stderr, "Unknown Len=%d\n", len); + } + #endif + } } -#endif } -RP_FAILURE: if (error) { if (len == BACNET_STATUS_ABORT) { apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], diff --git a/src/bacnet/basic/service/h_rr.c b/src/bacnet/basic/service/h_rr.c index b98399f2..8b0a9e8e 100644 --- a/src/bacnet/basic/service/h_rr.c +++ b/src/bacnet/basic/service/h_rr.c @@ -45,8 +45,20 @@ static uint8_t Temp_Buf[MAX_APDU] = { 0 }; -/* Encodes the property APDU and returns the length, - or sets the error, and returns -1 */ +/** + * Encodes the property APDU and returns the length, + * or sets the error, and returns -1. + * + * @param apdu Pointer to the APDU buffer. + * @param pRequest Pointer to the request to encode. + * + * @return Bytes encoded or -1 on an error. The error code + * may also be a negative return value from the called + * handler of 'PropInfo.Handler' type from within + * this function. The error code might be -2, if an + * abort message has been encoded, because the APDU + * was too small to fit the data. + */ static int Encode_RR_payload(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) { int apdu_len = -1; @@ -99,6 +111,15 @@ static int Encode_RR_payload(uint8_t *apdu, BACNET_READ_RANGE_DATA *pRequest) return apdu_len; } +/** + * Handle the received ReadRange request and encode a response. + * + * @param service_request Pointer to the service request. + * @param service_len Bytes valid in the service request. + * @param src Pointer to the BACnet addresss. + * @param service_data Pointer to the service data, + * taken from the request. + */ void handler_read_range(uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src, @@ -129,58 +150,57 @@ void handler_read_range(uint8_t *service_request, #if PRINT_ENABLED fprintf(stderr, "RR: Segmented message. Sending Abort!\n"); #endif - goto RR_ABORT; - } - memset(&data, 0, sizeof(data)); /* start with blank canvas */ - len = rr_decode_service_request(service_request, service_len, &data); -#if PRINT_ENABLED - if (len <= 0) - fprintf(stderr, "RR: Unable to decode Request!\n"); -#endif - if (len < 0) { - /* bad decoding - send an abort */ - len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); -#if PRINT_ENABLED - fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n"); -#endif - goto RR_ABORT; - } - - /* assume that there is an error */ - error = true; - len = Encode_RR_payload(&Temp_Buf[0], &data); - if (len >= 0) { - /* encode the APDU portion of the packet */ - data.application_data = &Temp_Buf[0]; - data.application_data_len = len; - /* FIXME: probably need a length limitation sent with encode */ - len = rr_ack_encode_apdu( - &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); -#if PRINT_ENABLED - fprintf(stderr, "RR: Sending Ack!\n"); -#endif - error = false; - } - if (error) { - if (len == -2) { - /* BACnet APDU too small to fit data, so proper response is Abort */ + } else { + memset(&data, 0, sizeof(data)); /* start with blank canvas */ + len = rr_decode_service_request(service_request, service_len, &data); + #if PRINT_ENABLED + if (len <= 0) + fprintf(stderr, "RR: Unable to decode Request!\n"); + #endif + if (len < 0) { + /* bad decoding - send an abort */ len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); -#if PRINT_ENABLED - fprintf(stderr, "RR: Reply too big to fit into APDU!\n"); -#endif + service_data->invoke_id, ABORT_REASON_OTHER, true); + #if PRINT_ENABLED + fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n"); + #endif } else { - len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_READ_RANGE, - data.error_class, data.error_code); -#if PRINT_ENABLED - fprintf(stderr, "RR: Sending Error!\n"); -#endif + /* assume that there is an error */ + error = true; + len = Encode_RR_payload(&Temp_Buf[0], &data); + if (len >= 0) { + /* encode the APDU portion of the packet */ + data.application_data = &Temp_Buf[0]; + data.application_data_len = len; + /* FIXME: probably need a length limitation sent with encode */ + len = rr_ack_encode_apdu( + &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); + #if PRINT_ENABLED + fprintf(stderr, "RR: Sending Ack!\n"); + #endif + error = false; + } + if (error) { + if (len == -2) { + /* BACnet APDU too small to fit data, so proper response is Abort */ + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + #if PRINT_ENABLED + fprintf(stderr, "RR: Reply too big to fit into APDU!\n"); + #endif + } else { + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_READ_RANGE, + data.error_class, data.error_code); + #if PRINT_ENABLED + fprintf(stderr, "RR: Sending Error!\n"); + #endif + } + } } } -RR_ABORT: + pdu_len += len; #if PRINT_ENABLED bytes_sent =