diff --git a/bacnet-stack/demo/epics/main.c b/bacnet-stack/demo/epics/main.c index 39b70927..49d5e8fe 100644 --- a/bacnet-stack/demo/epics/main.c +++ b/bacnet-stack/demo/epics/main.c @@ -75,6 +75,8 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* target information converted from command line */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; static BACNET_ADDRESS Target_Address; +/* the invoke id is needed to filter incoming messages */ +static uint8_t Request_Invoke_ID = 0; /* loopback address to talk to myself */ /* = { 6, { 127, 0, 0, 1, 0xBA, 0xC0, 0 }, 0 }; */ #if defined(BACDL_BIP) @@ -171,18 +173,19 @@ static void MyErrorHandler( BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code) { - /* FIXME: verify src and invoke id */ - (void) src; - (void) invoke_id; + if (address_match(&Target_Address, src) && + (invoke_id == Request_Invoke_ID)) { #if PRINT_ERRORS - if (ShowValues) - fprintf(stderr, "-- BACnet Error: %s: %s\r\n", - bactext_error_class_name(error_class), - bactext_error_code_name(error_code)); + if (ShowValues) { + fprintf(stderr, "-- BACnet Error: %s: %s\r\n", + bactext_error_class_name(error_class), + bactext_error_code_name(error_code)); + } #endif - Error_Detected = true; - Last_Error_Class = error_class; - Last_Error_Code = error_code; + Error_Detected = true; + Last_Error_Class = error_class; + Last_Error_Code = error_code; + } } void MyAbortHandler( @@ -191,23 +194,24 @@ void MyAbortHandler( uint8_t abort_reason, bool server) { - /* FIXME: verify src and invoke id */ - (void) src; - (void) invoke_id; (void) server; + if (address_match(&Target_Address, src) && + (invoke_id == Request_Invoke_ID)) { #if PRINT_ERRORS - /* It is normal for this to fail, so don't print. */ - if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) - fprintf(stderr, "-- BACnet Abort: %s \r\n", - bactext_abort_reason_name(abort_reason)); + /* It is normal for this to fail, so don't print. */ + if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) { + fprintf(stderr, "-- BACnet Abort: %s \r\n", + bactext_abort_reason_name(abort_reason)); + } #endif - Error_Detected = true; - Last_Error_Class = ERROR_CLASS_SERVICES; - if (abort_reason < MAX_BACNET_ABORT_REASON) - Last_Error_Code = - (ERROR_CODE_ABORT_BUFFER_OVERFLOW - 1) + abort_reason; - else - Last_Error_Code = ERROR_CODE_ABORT_OTHER; + Error_Detected = true; + Last_Error_Class = ERROR_CLASS_SERVICES; + if (abort_reason < MAX_BACNET_ABORT_REASON) + Last_Error_Code = + (ERROR_CODE_ABORT_BUFFER_OVERFLOW - 1) + abort_reason; + else + Last_Error_Code = ERROR_CODE_ABORT_OTHER; + } } void MyRejectHandler( @@ -215,21 +219,22 @@ void MyRejectHandler( uint8_t invoke_id, uint8_t reject_reason) { - /* FIXME: verify src and invoke id */ - (void) src; - (void) invoke_id; + if (address_match(&Target_Address, src) && + (invoke_id == Request_Invoke_ID)) { #if PRINT_ERRORS - if (ShowValues) - fprintf(stderr, "BACnet Reject: %s\r\n", - bactext_reject_reason_name(reject_reason)); + if (ShowValues) { + fprintf(stderr, "BACnet Reject: %s\r\n", + bactext_reject_reason_name(reject_reason)); + } #endif - Error_Detected = true; - Last_Error_Class = ERROR_CLASS_SERVICES; - if (reject_reason < MAX_BACNET_REJECT_REASON) - Last_Error_Code = - (ERROR_CODE_REJECT_BUFFER_OVERFLOW - 1) + reject_reason; - else - Last_Error_Code = ERROR_CODE_REJECT_OTHER; + Error_Detected = true; + Last_Error_Class = ERROR_CLASS_SERVICES; + if (reject_reason < MAX_BACNET_REJECT_REASON) + Last_Error_Code = + (ERROR_CODE_REJECT_BUFFER_OVERFLOW - 1) + reject_reason; + else + Last_Error_Code = ERROR_CODE_REJECT_OTHER; + } } void MyReadPropertyAckHandler( @@ -241,22 +246,24 @@ void MyReadPropertyAckHandler( int len = 0; BACNET_READ_ACCESS_DATA *rp_data; - (void) src; - rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); - if (rp_data) { - len = - rp_ack_fully_decode_service_request(service_request, service_len, - rp_data); - } - if (len > 0) { - memmove(&Read_Property_Multiple_Data.service_data, service_data, - sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); - Read_Property_Multiple_Data.rpm_data = rp_data; - Read_Property_Multiple_Data.new_data = true; - } else { - if (len < 0) /* Eg, failed due to no segmentation */ - Error_Detected = true; - free(rp_data); + if (address_match(&Target_Address, src) && + (service_data->invoke_id == Request_Invoke_ID)) { + rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); + if (rp_data) { + len = + rp_ack_fully_decode_service_request(service_request, service_len, + rp_data); + } + if (len > 0) { + memmove(&Read_Property_Multiple_Data.service_data, service_data, + sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); + Read_Property_Multiple_Data.rpm_data = rp_data; + Read_Property_Multiple_Data.new_data = true; + } else { + if (len < 0) /* Eg, failed due to no segmentation */ + Error_Detected = true; + free(rp_data); + } } } @@ -269,23 +276,25 @@ void MyReadPropertyMultipleAckHandler( int len = 0; BACNET_READ_ACCESS_DATA *rpm_data; - (void) src; - rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); - if (rpm_data) { - len = - rpm_ack_decode_service_request(service_request, service_len, - rpm_data); - } - if (len > 0) { - memmove(&Read_Property_Multiple_Data.service_data, service_data, - sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); - Read_Property_Multiple_Data.rpm_data = rpm_data; - Read_Property_Multiple_Data.new_data = true; - /* Will process and free the RPM data later */ - } else { - if (len < 0) /* Eg, failed due to no segmentation */ - Error_Detected = true; - free(rpm_data); + if (address_match(&Target_Address, src) && + (service_data->invoke_id == Request_Invoke_ID)) { + rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); + if (rpm_data) { + len = + rpm_ack_decode_service_request(service_request, service_len, + rpm_data); + } + if (len > 0) { + memmove(&Read_Property_Multiple_Data.service_data, service_data, + sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); + Read_Property_Multiple_Data.rpm_data = rpm_data; + Read_Property_Multiple_Data.new_data = true; + /* Will process and free the RPM data later */ + } else { + if (len < 0) /* Eg, failed due to no segmentation */ + Error_Detected = true; + free(rpm_data); + } } } @@ -1229,7 +1238,6 @@ int main( time_t last_seconds = 0; time_t current_seconds = 0; time_t timeout_seconds = 0; - uint8_t invoke_id = 0; bool found = false; BACNET_OBJECT_ID myObject; uint8_t buffer[MAX_PDU] = { 0 }; @@ -1341,10 +1349,10 @@ int main( last_seconds = current_seconds; StartNextObject(rpm_object, &myObject); BuildPropRequest( rpm_object, &InitIdPropList[0] ); - invoke_id = + Request_Invoke_ID = Send_Read_Property_Multiple_Request(buffer, MAX_PDU, Target_Device_Object_Instance, rpm_object); - if (invoke_id > 0) { + if (Request_Invoke_ID > 0) { elapsed_seconds = 0; } else { /* We failed. Will hurt the header info we can show. */ @@ -1366,10 +1374,10 @@ int main( last_seconds = current_seconds; StartNextObject(rpm_object, &myObject); - invoke_id = + Request_Invoke_ID = Send_Read_Property_Multiple_Request(buffer, MAX_PDU, Target_Device_Object_Instance, rpm_object); - if (invoke_id > 0) { + if (Request_Invoke_ID > 0) { elapsed_seconds = 0; if (myState == GET_LIST_OF_ALL_REQUEST) myState = GET_LIST_OF_ALL_RESPONSE; @@ -1391,38 +1399,41 @@ int main( } if ((Read_Property_Multiple_Data.new_data) && - (invoke_id == + (Request_Invoke_ID == Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.new_data = false; myState = ProcessRPMData(Read_Property_Multiple_Data.rpm_data, myState); - if (tsm_invoke_id_free(invoke_id)) { - invoke_id = 0; + if (tsm_invoke_id_free(Request_Invoke_ID)) { + Request_Invoke_ID = 0; } else { assert(false); /* How can this be? */ - invoke_id = 0; + Request_Invoke_ID = 0; } elapsed_seconds = 0; - } else if (tsm_invoke_id_free(invoke_id)) { + } else if (tsm_invoke_id_free(Request_Invoke_ID)) { elapsed_seconds = 0; - invoke_id = 0; + Request_Invoke_ID = 0; if ( myState == GET_HEADING_RESPONSE ) myState = PRINT_HEADING; /* just press ahead without the data */ else if (Error_Detected) { - /* The normal case for Device Object */ - /* Was it because the Device can't do RPM? */ if (Last_Error_Code == ERROR_CODE_REJECT_UNRECOGNIZED_SERVICE) { + /* The normal case for Device Object */ + /* Was it because the Device can't do RPM? */ Has_RPM = false; myState = GET_PROPERTY_REQUEST; - } - /* Try again, just to get a list of properties. */ - else if (myState == GET_ALL_RESPONSE) + } else if (Last_Error_Code == + ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) { + myState = GET_PROPERTY_REQUEST; + StartNextObject(rpm_object, &myObject); + } else if (myState == GET_ALL_RESPONSE) + /* Try again, just to get a list of properties. */ myState = GET_LIST_OF_ALL_REQUEST; - /* Else drop back to RP. */ else { + /* Else drop back to RP. */ myState = GET_PROPERTY_REQUEST; StartNextObject(rpm_object, &myObject); } @@ -1430,10 +1441,10 @@ int main( myState = GET_ALL_REQUEST; /* Let's try again */ else myState = GET_PROPERTY_REQUEST; - } else if (tsm_invoke_id_failed(invoke_id)) { + } else if (tsm_invoke_id_failed(Request_Invoke_ID)) { fprintf(stderr, "\rError: TSM Timeout!\r\n"); - tsm_free_invoke_id(invoke_id); - invoke_id = 0; + tsm_free_invoke_id(Request_Invoke_ID); + Request_Invoke_ID = 0; elapsed_seconds = 0; if ( myState == GET_HEADING_RESPONSE ) myState = PRINT_HEADING; @@ -1443,7 +1454,7 @@ int main( } else if (Error_Detected) { /* Don't think we'll ever actually reach this point. */ elapsed_seconds = 0; - invoke_id = 0; + Request_Invoke_ID = 0; if ( myState == GET_HEADING_RESPONSE ) myState = PRINT_HEADING; /* just press ahead without the data */ @@ -1460,9 +1471,9 @@ int main( /* Update times; aids single-step debugging */ last_seconds = current_seconds; elapsed_seconds = 0; - invoke_id = + Request_Invoke_ID = Read_Properties(Target_Device_Object_Instance, &myObject); - if (invoke_id == 0) { + if (Request_Invoke_ID == 0) { /* Reached the end of the list. */ myState = NEXT_OBJECT; /* Move on to the next. */ } else @@ -1480,7 +1491,7 @@ int main( } if ((Read_Property_Multiple_Data.new_data) && - (invoke_id == + (Request_Invoke_ID == Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.new_data = false; PrintReadPropertyData(Read_Property_Multiple_Data. @@ -1488,11 +1499,11 @@ int main( Read_Property_Multiple_Data.rpm_data->object_instance, Read_Property_Multiple_Data.rpm_data-> listOfProperties); - if (tsm_invoke_id_free(invoke_id)) { - invoke_id = 0; + if (tsm_invoke_id_free(Request_Invoke_ID)) { + Request_Invoke_ID = 0; } else { assert(false); /* How can this be? */ - invoke_id = 0; + Request_Invoke_ID = 0; } elapsed_seconds = 0; /* Advance the property (or Array List) index */ @@ -1516,8 +1527,8 @@ int main( /* } */ /* } */ myState = GET_PROPERTY_REQUEST; /* Go fetch next Property */ - } else if (tsm_invoke_id_free(invoke_id)) { - invoke_id = 0; + } else if (tsm_invoke_id_free(Request_Invoke_ID)) { + Request_Invoke_ID = 0; elapsed_seconds = 0; myState = GET_PROPERTY_REQUEST; if (Error_Detected) { @@ -1536,16 +1547,16 @@ int main( myState = NEXT_OBJECT; /* Give up and move on to the next. */ } } - } else if (tsm_invoke_id_failed(invoke_id)) { + } else if (tsm_invoke_id_failed(Request_Invoke_ID)) { fprintf(stderr, "\rError: TSM Timeout!\r\n"); - tsm_free_invoke_id(invoke_id); + tsm_free_invoke_id(Request_Invoke_ID); elapsed_seconds = 0; - invoke_id = 0; + Request_Invoke_ID = 0; myState = GET_PROPERTY_REQUEST; /* Let's try again, same Property */ } else if (Error_Detected) { /* Don't think we'll ever actually reach this point. */ elapsed_seconds = 0; - invoke_id = 0; + Request_Invoke_ID = 0; myState = NEXT_OBJECT; /* Give up and move on to the next. */ Error_Count++; } @@ -1598,7 +1609,7 @@ int main( } /* Check for timeouts */ - if (!found || (invoke_id > 0)) { + if (!found || (Request_Invoke_ID > 0)) { /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) {