diff --git a/bacnet-stack/bacenum.h b/bacnet-stack/bacenum.h index 931c82b8..d34de674 100644 --- a/bacnet-stack/bacenum.h +++ b/bacnet-stack/bacenum.h @@ -1040,66 +1040,83 @@ typedef enum { LAST_PROPRIETARY_ERROR_CLASS = 65535 } BACNET_ERROR_CLASS; +/* These are sorted in the order given in + Clause 18. ERROR, REJECT AND ABORT CODES + The Class and Code pairings are required + to be used in accordance with Clause 18. */ typedef enum { + /* valid for all classes */ ERROR_CODE_OTHER = 0, - ERROR_CODE_AUTHENTICATION_FAILED = 1, - ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, - ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2, - ERROR_CODE_DATATYPE_NOT_SUPPORTED = 47, + + /* Error Class - Device */ ERROR_CODE_DEVICE_BUSY = 3, - ERROR_CODE_DUPLICATE_NAME = 48, - ERROR_CODE_DUPLICATE_OBJECT_ID = 49, + ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2, + ERROR_CODE_OPERATIONAL_PROBLEM = 25, + + /* Error Class - Object */ ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED = 4, - ERROR_CODE_FILE_ACCESS_DENIED = 5, - ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS = 6, - ERROR_CODE_INCONSISTENT_PARAMETERS = 7, + ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17, + ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23, + ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS = 24, + ERROR_CODE_READ_ACCESS_DENIED = 27, + ERROR_CODE_UNKNOWN_OBJECT = 31, + ERROR_CODE_UNSUPPORTED_OBJECT_TYPE = 36, + + /* Error Class - Property */ + ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, + ERROR_CODE_DATATYPE_NOT_SUPPORTED = 47, ERROR_CODE_INCONSISTENT_SELECTION_CRITERION = 8, ERROR_CODE_INVALID_ARRAY_INDEX = 42, - ERROR_CODE_INVALID_CONFIGURATION_DATA = 46, ERROR_CODE_INVALID_DATA_TYPE = 9, - ERROR_CODE_INVALID_FILE_ACCESS_METHOD = 10, - ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION = 11, - ERROR_CODE_INVALID_OPERATOR_NAME = 12, - ERROR_CODE_INVALID_PARAMETER_DATA_TYPE = 13, - ERROR_CODE_INVALID_TIME_STAMP = 14, - ERROR_CODE_KEY_GENERATION_ERROR = 15, - ERROR_CODE_MISSING_REQUIRED_PARAMETER = 16, - ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17, + ERROR_CODE_NOT_COV_PROPERTY = 44, + ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45, + ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY = 50, + /* ERROR_CODE_READ_ACCESS_DENIED = 27, */ + ERROR_CODE_UNKNOWN_PROPERTY = 32, + ERROR_CODE_VALUE_OUT_OF_RANGE = 37, + ERROR_CODE_WRITE_ACCESS_DENIED = 40, + + /* Error Class - Resources */ ERROR_CODE_NO_SPACE_FOR_OBJECT = 18, ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT = 19, ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY = 20, - ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21, - ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23, - ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS = 24, - ERROR_CODE_OPERATIONAL_PROBLEM = 25, - ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45, + + /* Error Class - Security */ + ERROR_CODE_AUTHENTICATION_FAILED = 1, + /* ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, */ + ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS = 6, + ERROR_CODE_INVALID_OPERATOR_NAME = 12, + ERROR_CODE_KEY_GENERATION_ERROR = 15, ERROR_CODE_PASSWORD_FAILURE = 26, - ERROR_CODE_PROPERTY_IS_NOT_A_LIST = 22, - ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY = 50, - ERROR_CODE_READ_ACCESS_DENIED = 27, ERROR_CODE_SECURITY_NOT_SUPPORTED = 28, - ERROR_CODE_SERVICE_REQUEST_DENIED = 29, ERROR_CODE_TIMEOUT = 30, - ERROR_CODE_UNKNOWN_OBJECT = 31, - ERROR_CODE_UNKNOWN_PROPERTY = 32, - ERROR_CODE_RESERVED1 = 33, + + /* Error Class - Services */ + /* ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, */ + ERROR_CODE_COV_SUBSCRIPTION_FAILED = 43, + ERROR_CODE_DUPLICATE_NAME = 48, + ERROR_CODE_DUPLICATE_OBJECT_ID = 49, + ERROR_CODE_FILE_ACCESS_DENIED = 5, + ERROR_CODE_INCONSISTENT_PARAMETERS = 7, + ERROR_CODE_INVALID_CONFIGURATION_DATA = 46, + ERROR_CODE_INVALID_FILE_ACCESS_METHOD = 10, + ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION = 11, + ERROR_CODE_INVALID_PARAMETER_DATA_TYPE = 13, + ERROR_CODE_INVALID_TIME_STAMP = 14, + ERROR_CODE_MISSING_REQUIRED_PARAMETER = 16, + /* ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45, */ + ERROR_CODE_PROPERTY_IS_NOT_A_LIST = 22, + ERROR_CODE_SERVICE_REQUEST_DENIED = 29, + + /* Error Class - VT */ ERROR_CODE_UNKNOWN_VT_CLASS = 34, ERROR_CODE_UNKNOWN_VT_SESSION = 35, - ERROR_CODE_UNSUPPORTED_OBJECT_TYPE = 36, - ERROR_CODE_VALUE_OUT_OF_RANGE = 37, + ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21, ERROR_CODE_VT_SESSION_ALREADY_CLOSED = 38, ERROR_CODE_VT_SESSION_TERMINATION_FAILURE = 39, - ERROR_CODE_WRITE_ACCESS_DENIED = 40, - /* see character-set-not-supported (41), */ - /* see invalid-array-index (42), */ - ERROR_CODE_COV_SUBSCRIPTION_FAILED = 43, - ERROR_CODE_NOT_COV_PROPERTY = 44, - /* see optional-functionality-not-supported (45), */ - /* see invalid-configuration-data (46), */ - /* see datatype-not-supported (47), */ - /* see duplicate-name (48), */ - /* see duplicate-object-id (49), */ - /* see property-is-not-an-array (50), */ + + /* unused */ + ERROR_CODE_RESERVED1 = 33, /* Enumerated values 0-255 are reserved for definition by ASHRAE. */ /* Enumerated values 256-65535 may be used by others subject to */ /* the procedures and constraints described in Clause 23. */ diff --git a/bacnet-stack/cov.c b/bacnet-stack/cov.c index 3e12b299..3ed2662f 100644 --- a/bacnet-stack/cov.c +++ b/bacnet-stack/cov.c @@ -275,7 +275,7 @@ int cov_notify_decode_service_request(uint8_t * apdu, } int ucov_notify_send(uint8_t * buffer, BACNET_COV_DATA * data) -{ +{ int len = 0; int pdu_len = 0; BACNET_ADDRESS dest; @@ -284,11 +284,11 @@ int ucov_notify_send(uint8_t * buffer, BACNET_COV_DATA * data) /* unconfirmed is a broadcast */ datalink_get_broadcast_address(&dest); - /* encode the NPDU portion of the packet */ - npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&buffer[0], &dest, NULL, &npdu_data); + /* encode the NPDU portion of the packet */ + npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&buffer[0], &dest, NULL, &npdu_data); /* encode the APDU portion of the packet */ - len = ucov_notify_encode_apdu(&buffer[pdu_len], data); + len = ucov_notify_encode_apdu(&buffer[pdu_len], data); pdu_len += len; /* send the data */ bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); @@ -355,10 +355,18 @@ int ucov_notify_decode_apdu(uint8_t * apdu, /* dummy function stubs */ -void npdu_encode_unconfirmed_apdu(BACNET_NPDU_DATA * npdu, - BACNET_MESSAGE_PRIORITY priority) +int npdu_encode_pdu(uint8_t * npdu, + BACNET_ADDRESS * dest, + BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data) { - return; + return 0; +} + +void npdu_encode_npdu_data(BACNET_NPDU_DATA * npdu, + bool data_expecting_reply, + BACNET_MESSAGE_PRIORITY priority) +{ + } /* dummy function stubs */ diff --git a/bacnet-stack/demo/handler/h_arf.c b/bacnet-stack/demo/handler/h_arf.c index 8aba4506..b208f248 100644 --- a/bacnet-stack/demo/handler/h_arf.c +++ b/bacnet-stack/demo/handler/h_arf.c @@ -41,6 +41,57 @@ #include "ao.h" #include "bacfile.h" +/* +from BACnet SSPC-135-2004 + +14. FILE ACCESS SERVICES + +This clause defines the set of services used to access and +manipulate files contained in BACnet devices. The concept of files +is used here as a network-visible representation for a collection +of octets of arbitrary length and meaning. This is an abstract +concept only and does not imply the use of disk, tape or other +mass storage devices in the server devices. These services may +be used to access vendor-defined files as well as specific +files defined in the BACnet protocol standard. +Every file that is accessible by File Access Services shall +have a corresponding File object in the BACnet device. This File +object is used to identify the particular file by name. In addition, +the File object provides access to "header information," such +as the file's total size, creation date, and type. File Access +Services may model files in two ways: as a continuous stream of +octets or as a contiguous sequence of numbered records. +The File Access Services provide atomic read and write operations. +In this context "atomic" means that during the execution +of a read or write operation, no other AtomicReadFile or +AtomicWriteFile operations are allowed for the same file. +Synchronization of these services with internal operations +of the BACnet device is a local matter and is not defined by this +standard. + +14.1 AtomicReadFile Service + +14.1.5 Service Procedure + +The responding BACnet-user shall first verify the validity +of the 'File Identifier' parameter and return a 'Result(-)' response +with the appropriate error class and code if the File object +is unknown, if there is currently another AtomicReadFile or +AtomicWriteFile service in progress, or if the File object is +currently inaccessible for another reason. If the 'File Start +Position' parameter or the 'File Start Record' parameter is +either less than 0 or exceeds the actual file size, then the appropriate +error is returned in a 'Result(-)' response. If not, then the +responding BACnet-user shall read the number of octets specified by +'Requested Octet Count' or the number of records specified by +'Requested Record Count'. If the number of remaining octets or +records is less than the requested amount, then the length of +the 'File Data' returned or 'Returned Record Count' shall indicate +the actual number read. If the returned response contains the +last octet or record of the file, then the 'End Of File' parameter +shall be TRUE, otherwise FALSE. +*/ + void handler_atomic_read_file(uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data) @@ -51,40 +102,52 @@ void handler_atomic_read_file(uint8_t * service_request, bool error = false; int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; + BACNET_ADDRESS my_address; + BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; + BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; #if PRINT_ENABLED fprintf(stderr, "Received Atomic-Read-File Request!\n"); #endif len = arf_decode_service_request(service_request, service_len, &data); - /* prepare a reply */ + /* 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 - send an abort */ if (len < 0) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER); #if PRINT_ENABLED fprintf(stderr, "Bad Encoding. Sending Abort!\n"); #endif } else if (service_data->segmented_message) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); #if PRINT_ENABLED fprintf(stderr, "Segmented Message. Sending Abort!\n"); #endif - } else { - if (data.access == FILE_STREAM_ACCESS) { + } else if (data.object_type == OBJECT_FILE) { + if (!bacfile_valid_instance(data.object_instance)) { + error = true; + } + else if (data.access == FILE_STREAM_ACCESS) { if (data.type.stream.requestedOctetCount < octetstring_capacity(&data.fileData)) { if (bacfile_read_data(&data)) { - pdu_len = - arf_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); } else { error = true; + error_class = ERROR_CLASS_OBJECT; + error_code = ERROR_CODE_FILE_ACCESS_DENIED; } } else { - pdu_len = - abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); #if PRINT_ENABLED @@ -92,17 +155,26 @@ void handler_atomic_read_file(uint8_t * service_request, #endif } } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_ATOMIC_READ_FILE, ERROR_CLASS_SERVICES, - ERROR_CODE_INVALID_FILE_ACCESS_METHOD); + error = true; + error_class = ERROR_CLASS_SERVICES; + error_code = ERROR_CODE_INVALID_FILE_ACCESS_METHOD; #if PRINT_ENABLED fprintf(stderr, "Record Access Requested. Sending Error!\n"); #endif } + } else { + error = true; + error_class = ERROR_CLASS_SERVICES; + error_code = ERROR_CODE_FILE_ACCESS_DENIED; } - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + if (error) + { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code); + } + pdu_len += len; bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/h_dcc.c b/bacnet-stack/demo/handler/h_dcc.c index 53bd62be..7faf935b 100644 --- a/bacnet-stack/demo/handler/h_dcc.c +++ b/bacnet-stack/demo/handler/h_dcc.c @@ -51,10 +51,16 @@ void handler_device_communication_control(uint8_t * service_request, int pdu_len = 0; int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; + BACNET_ADDRESS my_address; /* decode the service request only */ len = dcc_decode_service_request(service_request, service_len, &timeDuration, &state, &password); + /* 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, "DeviceCommunicationControl!\n"); if (len > 0) @@ -65,14 +71,14 @@ void handler_device_communication_control(uint8_t * service_request, #endif /* bad decoding or something we didn't understand - send an abort */ if (len < 0) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER); #if PRINT_ENABLED fprintf(stderr, "DeviceCommunicationControl: " "Sending Abort - could not decode.\n"); #endif } else if (service_data->segmented_message) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); #if PRINT_ENABLED @@ -80,7 +86,7 @@ void handler_device_communication_control(uint8_t * service_request, "Sending Abort - segmented message.\n"); #endif } else if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) { - pdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[0], + len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); #if PRINT_ENABLED fprintf(stderr, "DeviceCommunicationControl: " @@ -88,7 +94,7 @@ void handler_device_communication_control(uint8_t * service_request, #endif } else { if (characterstring_ansi_same(&password, My_Password)) { - pdu_len = encode_simple_ack(&Handler_Transmit_Buffer[0], + len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL); #if PRINT_ENABLED @@ -97,8 +103,8 @@ void handler_device_communication_control(uint8_t * service_request, #endif dcc_set_status_duration(state, timeDuration); } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE); @@ -109,7 +115,7 @@ void handler_device_communication_control(uint8_t * service_request, #endif } } - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/h_rd.c b/bacnet-stack/demo/handler/h_rd.c index 501b9b03..9c716423 100644 --- a/bacnet-stack/demo/handler/h_rd.c +++ b/bacnet-stack/demo/handler/h_rd.c @@ -51,10 +51,16 @@ void handler_reinitialize_device(uint8_t * service_request, int pdu_len = 0; BACNET_NPDU_DATA npdu_data; int bytes_sent = 0; + BACNET_ADDRESS my_address; /* decode the service request only */ len = rd_decode_service_request(service_request, service_len, &state, &their_password); + /* 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, "ReinitializeDevice!\n"); if (len > 0) @@ -65,14 +71,14 @@ void handler_reinitialize_device(uint8_t * service_request, #endif /* bad decoding or something we didn't understand - send an abort */ if (len < 0) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER); #if PRINT_ENABLED fprintf(stderr, "ReinitializeDevice: Sending Abort - could not decode.\n"); #endif } else if (service_data->segmented_message) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); #if PRINT_ENABLED @@ -80,7 +86,7 @@ void handler_reinitialize_device(uint8_t * service_request, "ReinitializeDevice: Sending Abort - segmented message.\n"); #endif } else if (state >= MAX_BACNET_REINITIALIZED_STATE) { - pdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[0], + len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); #if PRINT_ENABLED fprintf(stderr, @@ -89,7 +95,7 @@ void handler_reinitialize_device(uint8_t * service_request, } else { characterstring_init_ansi(&My_Password, Password); if (characterstring_same(&their_password, &My_Password)) { - pdu_len = encode_simple_ack(&Handler_Transmit_Buffer[0], + len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE); #if PRINT_ENABLED @@ -100,8 +106,8 @@ void handler_reinitialize_device(uint8_t * service_request, /* Note: if you don't do something clever like actually restart, you probably should clear any DCC status and timeouts */ } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE, ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE); @@ -111,7 +117,7 @@ void handler_reinitialize_device(uint8_t * service_request, #endif } } - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + pdu_len += len; bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/h_rp.c b/bacnet-stack/demo/handler/h_rp.c index eb54e549..9807a82d 100644 --- a/bacnet-stack/demo/handler/h_rp.c +++ b/bacnet-stack/demo/handler/h_rp.c @@ -59,7 +59,7 @@ void handler_read_property(uint8_t * service_request, int len = 0; int pdu_len = 0; BACNET_NPDU_DATA npdu_data; - bool error = true; + bool error = false; int bytes_sent = 0; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; @@ -71,7 +71,6 @@ void handler_read_property(uint8_t * service_request, 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 if (len <= 0) fprintf(stderr, "Unable to decode Read-Property Request!\n"); @@ -91,6 +90,8 @@ void handler_read_property(uint8_t * service_request, fprintf(stderr, "Sending Abort!\n"); #endif } else { + /* most cases will be error */ + error = true; switch (data.object_type) { case OBJECT_DEVICE: /* FIXME: probably need a length limitation sent with encode */ @@ -110,11 +111,9 @@ void handler_read_property(uint8_t * service_request, fprintf(stderr, "Sending Read Property Ack for Device!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_ANALOG_INPUT: if (Analog_Input_Valid_Instance(data.object_instance)) { @@ -127,17 +126,15 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for AI!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_BINARY_INPUT: if (Binary_Input_Valid_Instance(data.object_instance)) { @@ -150,17 +147,15 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for BI!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_BINARY_OUTPUT: if (Binary_Output_Valid_Instance(data.object_instance)) { @@ -173,17 +168,15 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for BO!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_BINARY_VALUE: if (Binary_Value_Valid_Instance(data.object_instance)) { @@ -196,17 +189,15 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for BV!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_ANALOG_OUTPUT: if (Analog_Output_Valid_Instance(data.object_instance)) { @@ -219,17 +210,15 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for AO!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_ANALOG_VALUE: if (Analog_Value_Valid_Instance(data.object_instance)) { @@ -242,17 +231,15 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for AV!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_LIFE_SAFETY_POINT: if (Life_Safety_Point_Valid_Instance(data.object_instance)) { @@ -265,18 +252,16 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for LSP!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; case OBJECT_MULTI_STATE_OUTPUT: if (Multistate_Output_Valid_Instance(data.object_instance)) { @@ -289,18 +274,16 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for MSO!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; #if BACFILE case OBJECT_FILE: @@ -314,22 +297,19 @@ void handler_read_property(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Ack for File!\n"); #endif - send = true; - } else - error = true; - } else - error = true; + error = false; + } + } break; #endif /* BACFILE */ default: - error = true; break; } } @@ -340,16 +320,14 @@ void handler_read_property(uint8_t * service_request, #if PRINT_ENABLED fprintf(stderr, "Sending Read Property Error!\n"); #endif - send = true; } - if (send) { - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */ + 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)); + if (bytes_sent <= 0) + fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno)); #endif - } return; } diff --git a/bacnet-stack/demo/handler/h_wp.c b/bacnet-stack/demo/handler/h_wp.c index 8dc4264a..62bac19d 100644 --- a/bacnet-stack/demo/handler/h_wp.c +++ b/bacnet-stack/demo/handler/h_wp.c @@ -60,10 +60,16 @@ void handler_write_property(uint8_t * service_request, 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); #if PRINT_ENABLED fprintf(stderr, "Received Write-Property Request!\n"); if (len > 0) @@ -76,13 +82,13 @@ void handler_write_property(uint8_t * service_request, #endif /* bad decoding or something we didn't understand - send an abort */ if (len <= 0) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER); #if PRINT_ENABLED fprintf(stderr, "Sending Abort!\n"); #endif } else if (service_data->segmented_message) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); #if PRINT_ENABLED @@ -92,8 +98,8 @@ void handler_write_property(uint8_t * service_request, switch (wp_data.object_type) { case OBJECT_DEVICE: if (Device_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -101,8 +107,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for Device!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -116,8 +122,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_BINARY_INPUT: error_class = ERROR_CLASS_PROPERTY; error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); #if PRINT_ENABLED @@ -127,8 +133,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_BINARY_OUTPUT: if (Binary_Output_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -136,8 +142,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for BO!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -149,8 +155,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_BINARY_VALUE: if (Binary_Value_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -158,8 +164,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for BV!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -171,8 +177,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_ANALOG_OUTPUT: if (Analog_Output_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -180,8 +186,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for AO!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -193,8 +199,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_ANALOG_VALUE: if (Analog_Value_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -202,8 +208,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for AV!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -215,8 +221,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_LIFE_SAFETY_POINT: if (Life_Safety_Point_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -224,8 +230,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for LSP!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -237,8 +243,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_MULTI_STATE_OUTPUT: if (Multistate_Output_Write_Property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -246,8 +252,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for MSO!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -260,8 +266,8 @@ void handler_write_property(uint8_t * service_request, case OBJECT_FILE: if (bacfile_write_property(&wp_data, &error_class, &error_code)) { - pdu_len = - encode_simple_ack(&Handler_Transmit_Buffer[0], + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); #if PRINT_ENABLED @@ -269,8 +275,8 @@ void handler_write_property(uint8_t * service_request, "Sending Write Property Simple Ack for File!\n"); #endif } else { - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); @@ -281,8 +287,8 @@ void handler_write_property(uint8_t * service_request, break; #endif default: - pdu_len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code); #if PRINT_ENABLED @@ -291,7 +297,7 @@ void handler_write_property(uint8_t * service_request, break; } } - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + pdu_len += len; bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/noserv.c b/bacnet-stack/demo/handler/noserv.c index de5e93a8..5d277cdd 100644 --- a/bacnet-stack/demo/handler/noserv.c +++ b/bacnet-stack/demo/handler/noserv.c @@ -36,22 +36,28 @@ void handler_unrecognized_service(uint8_t * service_request, uint16_t service_len, - BACNET_ADDRESS * dest, BACNET_CONFIRMED_SERVICE_DATA * service_data) + BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data) { + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; + BACNET_ADDRESS my_address; (void) service_request; (void) service_len; - /* encode the APDU portion of the packet */ - pdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[0], - service_data->invoke_id, REJECT_REASON_UNRECOGNIZED_SERVICE); /* encode the NPDU portion of the packet */ - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + 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); + /* encode the APDU portion of the packet */ + len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, REJECT_REASON_UNRECOGNIZED_SERVICE); + pdu_len += len; /* send the data */ - bytes_sent = datalink_send_pdu(dest, &npdu_data, + bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED if (bytes_sent > 0) diff --git a/bacnet-stack/demo/handler/s_arfs.c b/bacnet-stack/demo/handler/s_arfs.c index dbf227cc..4e4f117d 100644 --- a/bacnet-stack/demo/handler/s_arfs.c +++ b/bacnet-stack/demo/handler/s_arfs.c @@ -31,6 +31,7 @@ #include "bacdef.h" #include "bacdcode.h" #include "address.h" +#include "dcc.h" #include "tsm.h" #include "npdu.h" #include "apdu.h" @@ -46,14 +47,20 @@ uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, int fileStartPosition, unsigned requestedOctetCount) { BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; BACNET_NPDU_DATA npdu_data; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_ATOMIC_READ_FILE_DATA data; + /* if we are forbidden to send, don't send! */ + if (!dcc_communication_enabled()) + return 0; + /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ @@ -66,16 +73,20 @@ uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, data.access = FILE_STREAM_ACCESS; data.type.stream.fileStartPosition = fileStartPosition; data.type.stream.requestedOctetCount = requestedOctetCount; - pdu_len = arf_encode_apdu(&Handler_Transmit_Buffer[0], + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, + &my_address, &npdu_data); + len = arf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data); + pdu_len += len; /* will the APDU fit the target device? note: if there is a bottleneck router in between us and the destination, we won't know unless we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned) pdu_len < max_apdu) { - npdu_encode_confirmed_apdu(&npdu_data, - MESSAGE_PRIORITY_NORMAL); tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); bytes_sent = diff --git a/bacnet-stack/demo/handler/s_awfs.c b/bacnet-stack/demo/handler/s_awfs.c index 1ddd6cd2..9d2a066b 100644 --- a/bacnet-stack/demo/handler/s_awfs.c +++ b/bacnet-stack/demo/handler/s_awfs.c @@ -32,6 +32,7 @@ #include "bacdcode.h" #include "address.h" #include "tsm.h" +#include "dcc.h" #include "npdu.h" #include "apdu.h" #include "device.h" @@ -46,14 +47,20 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, int fileStartPosition, BACNET_OCTET_STRING * fileData) { BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; BACNET_NPDU_DATA npdu_data; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_ATOMIC_WRITE_FILE_DATA data; + /* if we are forbidden to send, don't send! */ + if (!dcc_communication_enabled()) + return 0; + /* is the device bound? */ status = address_get_by_device(device_id, &max_apdu, &dest); /* is there a tsm available? */ @@ -67,16 +74,21 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id, data.type.stream.fileStartPosition = fileStartPosition; status = octetstring_copy(&data.fileData, fileData); if (status) { - pdu_len = awf_encode_apdu(&Handler_Transmit_Buffer[0], + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, 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 = awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data); + pdu_len += len; /* will the APDU fit the target device? note: if there is a bottleneck router in between us and the destination, we won't know unless we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned) pdu_len <= max_apdu) { - npdu_encode_confirmed_apdu(&npdu_data, - MESSAGE_PRIORITY_NORMAL); tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); bytes_sent = diff --git a/bacnet-stack/demo/handler/s_dcc.c b/bacnet-stack/demo/handler/s_dcc.c index ef86613f..d536ce85 100644 --- a/bacnet-stack/demo/handler/s_dcc.c +++ b/bacnet-stack/demo/handler/s_dcc.c @@ -46,14 +46,17 @@ uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t t BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password) { /* NULL=optional */ BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_CHARACTER_STRING password_string; BACNET_NPDU_DATA npdu_data; + /* if we are forbidden to send, don't send! */ if (!dcc_communication_enabled()) return 0; @@ -63,19 +66,23 @@ uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t t if (status) invoke_id = tsm_next_free_invokeID(); if (invoke_id) { - /* load the data for the encoding */ + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, + &my_address, &npdu_data); + /* encode the APDU portion of the packet */ characterstring_init_ansi(&password_string, password); - pdu_len = dcc_encode_apdu(&Handler_Transmit_Buffer[0], + len = dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, timeDuration, state, password ? &password_string : NULL); + pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between us and the destination, we won't know unless we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned) pdu_len < max_apdu) { - npdu_encode_confirmed_apdu(&npdu_data, - MESSAGE_PRIORITY_NORMAL); tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); bytes_sent = diff --git a/bacnet-stack/demo/handler/s_ihave.c b/bacnet-stack/demo/handler/s_ihave.c index db26c150..a50fb726 100644 --- a/bacnet-stack/demo/handler/s_ihave.c +++ b/bacnet-stack/demo/handler/s_ihave.c @@ -48,6 +48,7 @@ void Send_I_Have(uint32_t device_id, BACNET_OBJECT_TYPE object_type, uint32_t object_instance, char *object_name) { + int len = 0; int pdu_len = 0; BACNET_ADDRESS dest; int bytes_sent = 0; @@ -59,16 +60,21 @@ void Send_I_Have(uint32_t device_id, return; /* Who-Has is a global broadcast */ datalink_get_broadcast_address(&dest); + /* 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, + NULL, &npdu_data); /* encode the APDU portion of the packet */ data.device_id.type = OBJECT_DEVICE; data.device_id.instance = device_id; data.object_id.type = object_type; data.object_id.instance = object_instance; characterstring_init_ansi(&data.object_name, object_name); - pdu_len = ihave_encode_apdu(&Handler_Transmit_Buffer[0], &data); + len = ihave_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); + pdu_len += len; /* send the data */ - npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); - bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */ + 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 I-Have Reply (%s)!\n", diff --git a/bacnet-stack/demo/handler/s_rd.c b/bacnet-stack/demo/handler/s_rd.c index 123dc3dc..bd99ae9e 100644 --- a/bacnet-stack/demo/handler/s_rd.c +++ b/bacnet-stack/demo/handler/s_rd.c @@ -46,14 +46,17 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, BACNET_REINITIALIZED_STATE state, char *password) { BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_CHARACTER_STRING password_string; BACNET_NPDU_DATA npdu_data; + /* if we are forbidden to send, don't send! */ if (!dcc_communication_enabled()) return 0; @@ -63,18 +66,22 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, if (status) invoke_id = tsm_next_free_invokeID(); if (invoke_id) { - /* load the data for the encoding */ + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, + &my_address, &npdu_data); + /* encode the APDU portion of the packet */ characterstring_init_ansi(&password_string, password); - pdu_len = rd_encode_apdu(&Handler_Transmit_Buffer[0], + len = rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, state, password ? &password_string : NULL); + pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between us and the destination, we won't know unless we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned) pdu_len < max_apdu) { - npdu_encode_confirmed_apdu(&npdu_data, - MESSAGE_PRIORITY_NORMAL); tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); bytes_sent = diff --git a/bacnet-stack/demo/handler/s_rp.c b/bacnet-stack/demo/handler/s_rp.c index 932e4670..658ef6da 100644 --- a/bacnet-stack/demo/handler/s_rp.c +++ b/bacnet-stack/demo/handler/s_rp.c @@ -50,9 +50,11 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */ BACNET_PROPERTY_ID object_property, int32_t array_index) { BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_READ_PROPERTY_DATA data; @@ -67,21 +69,25 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */ if (status) invoke_id = tsm_next_free_invokeID(); if (invoke_id) { - /* load the data for the encoding */ + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, + &my_address, &npdu_data); + /* encode the APDU portion of the packet */ data.object_type = object_type; data.object_instance = object_instance; data.object_property = object_property; data.array_index = array_index; - pdu_len = rp_encode_apdu(&Handler_Transmit_Buffer[0], + len = rp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data); + pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between us and the destination, we won't know unless we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned) pdu_len < max_apdu) { - npdu_encode_confirmed_apdu(&npdu_data, - MESSAGE_PRIORITY_NORMAL); tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); bytes_sent = diff --git a/bacnet-stack/demo/handler/s_ts.c b/bacnet-stack/demo/handler/s_ts.c index 1483e003..98130261 100644 --- a/bacnet-stack/demo/handler/s_ts.c +++ b/bacnet-stack/demo/handler/s_ts.c @@ -44,6 +44,7 @@ void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime) { + int len = 0; int pdu_len = 0; BACNET_ADDRESS dest; int bytes_sent = 0; @@ -54,10 +55,14 @@ void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime) /* we could use unicast or broadcast */ datalink_get_broadcast_address(&dest); + /* 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, + NULL, &npdu_data); /* encode the APDU portion of the packet */ - pdu_len = timesync_encode_apdu(&Handler_Transmit_Buffer[0], + len = timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime); - npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + pdu_len += len; /* send it out the datalink */ bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); @@ -84,7 +89,6 @@ void Send_TimeSyncUTC(BACNET_DATE * bdate, BACNET_TIME * btime) /* encode the APDU portion of the packet */ pdu_len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[0], bdate, btime); - npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/s_whohas.c b/bacnet-stack/demo/handler/s_whohas.c index 7127a596..8b00502a 100644 --- a/bacnet-stack/demo/handler/s_whohas.c +++ b/bacnet-stack/demo/handler/s_whohas.c @@ -46,6 +46,7 @@ void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit, char *object_name) { + int len = 0; int pdu_len = 0; BACNET_ADDRESS dest; int bytes_sent = 0; @@ -57,13 +58,17 @@ void Send_WhoHas_Name(int32_t low_limit, return; /* Who-Has is a global broadcast */ datalink_get_broadcast_address(&dest); + /* 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, + NULL, &npdu_data); /* encode the APDU portion of the packet */ data.low_limit = low_limit; data.high_limit = high_limit; data.object_name = true; characterstring_init_ansi(&data.object.name, object_name); - pdu_len = whohas_encode_apdu(&Handler_Transmit_Buffer[0], &data); - npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); + pdu_len += len; /* send the data */ bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); @@ -97,7 +102,6 @@ void Send_WhoHas_Object(int32_t low_limit, data.object.identifier.type = object_type; data.object.identifier.instance = object_instance; pdu_len = whohas_encode_apdu(&Handler_Transmit_Buffer[0], &data); - npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/s_whois.c b/bacnet-stack/demo/handler/s_whois.c index 52ddd525..e67e9a30 100644 --- a/bacnet-stack/demo/handler/s_whois.c +++ b/bacnet-stack/demo/handler/s_whois.c @@ -46,6 +46,7 @@ /* find a specific device, or use -1 for limit if you want unlimited */ void Send_WhoIs(int32_t low_limit, int32_t high_limit) { + int len = 0; int pdu_len = 0; BACNET_ADDRESS dest; int bytes_sent = 0; @@ -56,10 +57,14 @@ void Send_WhoIs(int32_t low_limit, int32_t high_limit) /* Who-Is is a global broadcast */ datalink_get_broadcast_address(&dest); + /* 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, + NULL, &npdu_data); /* encode the APDU portion of the packet */ - pdu_len = whois_encode_apdu(&Handler_Transmit_Buffer[0], + len = whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len], low_limit, high_limit); - npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); + pdu_len += len; bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); #if PRINT_ENABLED diff --git a/bacnet-stack/demo/handler/s_wp.c b/bacnet-stack/demo/handler/s_wp.c index d57fc544..260c53ed 100644 --- a/bacnet-stack/demo/handler/s_wp.c +++ b/bacnet-stack/demo/handler/s_wp.c @@ -51,9 +51,11 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */ uint8_t priority, int32_t array_index) { BACNET_ADDRESS dest; + BACNET_ADDRESS my_address; unsigned max_apdu = 0; uint8_t invoke_id = 0; bool status = false; + int len = 0; int pdu_len = 0; int bytes_sent = 0; BACNET_WRITE_PROPERTY_DATA data; @@ -68,23 +70,27 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */ if (status) invoke_id = tsm_next_free_invokeID(); if (invoke_id) { - /* load the data for the encoding */ + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, + &my_address, &npdu_data); + /* encode the APDU portion of the packet */ data.object_type = object_type; data.object_instance = object_instance; data.object_property = object_property; data.array_index = array_index; bacapp_copy(&data.value, object_value); data.priority = priority; - pdu_len = wp_encode_apdu(&Handler_Transmit_Buffer[0], + len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data); + pdu_len += len; /* will it fit in the sender? note: if there is a bottleneck router in between us and the destination, we won't know unless we have a way to check for that and update the max_apdu in the address binding table. */ if ((unsigned) pdu_len < max_apdu) { - npdu_encode_confirmed_apdu(&npdu_data, - MESSAGE_PRIORITY_NORMAL); tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); bytes_sent = diff --git a/bacnet-stack/demo/object/bacfile.c b/bacnet-stack/demo/object/bacfile.c index 583bc41a..aed3c58e 100644 --- a/bacnet-stack/demo/object/bacfile.c +++ b/bacnet-stack/demo/object/bacfile.c @@ -313,7 +313,7 @@ uint32_t bacfile_instance_from_tsm(uint8_t invokeID) found = tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0], &apdu_len); if (found) { - if (!npdu_data.network_layer_message && npdu_data.confirmed_message + if (!npdu_data.network_layer_message && npdu_data.data_expecting_reply && (apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { len = apdu_decode_confirmed_service_request(&apdu[0], diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c index 524fc694..bcf16991 100644 --- a/bacnet-stack/demo/object/device.c +++ b/bacnet-stack/demo/object/device.c @@ -325,10 +325,11 @@ unsigned Device_Object_List_Count(void) unsigned count = 1; count += Analog_Input_Count(); - count += Binary_Input_Count(); - count += Binary_Output_Count(); count += Analog_Output_Count(); count += Analog_Value_Count(); + count += Binary_Input_Count(); + count += Binary_Output_Count(); + count += Binary_Value_Count(); count += Life_Safety_Point_Count(); count += Multistate_Output_Count(); #if BACFILE @@ -362,6 +363,32 @@ bool Device_Object_List_Identifier(unsigned array_index, status = true; } } + /* analog output objects */ + if (!status) { + /* normalize the index since + we know it is not the previous objects */ + object_index -= object_count; + object_count = Analog_Output_Count(); + /* is it a valid index for this object? */ + if (object_index < object_count) { + *object_type = OBJECT_ANALOG_OUTPUT; + *instance = Analog_Output_Index_To_Instance(object_index); + status = true; + } + } + /* analog value objects */ + if (!status) { + /* normalize the index since + we know it is not the previous objects */ + object_index -= object_count; + object_count = Analog_Value_Count(); + /* is it a valid index for this object? */ + if (object_index < object_count) { + *object_type = OBJECT_ANALOG_VALUE; + *instance = Analog_Value_Index_To_Instance(object_index); + status = true; + } + } /* binary input objects */ if (!status) { /* normalize the index since @@ -388,29 +415,16 @@ bool Device_Object_List_Identifier(unsigned array_index, status = true; } } - /* analog output objects */ + /* binary value objects */ if (!status) { /* normalize the index since we know it is not the previous objects */ object_index -= object_count; - object_count = Analog_Output_Count(); + object_count = Binary_Value_Count(); /* is it a valid index for this object? */ if (object_index < object_count) { - *object_type = OBJECT_ANALOG_OUTPUT; - *instance = Analog_Output_Index_To_Instance(object_index); - status = true; - } - } - /* analog value objects */ - if (!status) { - /* normalize the index since - we know it is not the previous objects */ - object_index -= object_count; - object_count = Analog_Value_Count(); - /* is it a valid index for this object? */ - if (object_index < object_count) { - *object_type = OBJECT_ANALOG_VALUE; - *instance = Analog_Value_Index_To_Instance(object_index); + *object_type = OBJECT_BINARY_VALUE; + *instance = Binary_Value_Index_To_Instance(object_index); status = true; } } @@ -497,17 +511,20 @@ char *Device_Valid_Object_Id(int object_type, uint32_t object_instance) case OBJECT_ANALOG_INPUT: name = Analog_Input_Name(object_instance); break; + case OBJECT_ANALOG_OUTPUT: + name = Analog_Output_Name(object_instance); + break; + case OBJECT_ANALOG_VALUE: + name = Analog_Value_Name(object_instance); + break; case OBJECT_BINARY_INPUT: name = Binary_Input_Name(object_instance); break; case OBJECT_BINARY_OUTPUT: name = Binary_Output_Name(object_instance); break; - case OBJECT_ANALOG_OUTPUT: - name = Analog_Output_Name(object_instance); - break; - case OBJECT_ANALOG_VALUE: - name = Analog_Value_Name(object_instance); + case OBJECT_BINARY_VALUE: + name = Binary_Value_Name(object_instance); break; case OBJECT_LIFE_SAFETY_POINT: name = Life_Safety_Point_Name(object_instance); @@ -654,6 +671,8 @@ int Device_Encode_Property_APDU(uint8_t * apdu, bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true); if (Binary_Output_Count()) bitstring_set_bit(&bit_string, OBJECT_BINARY_OUTPUT, true); + if (Binary_Value_Count()) + bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); if (Life_Safety_Point_Count()) bitstring_set_bit(&bit_string, OBJECT_LIFE_SAFETY_POINT, true); if (Multistate_Output_Count()) @@ -912,7 +931,38 @@ uint32_t Analog_Input_Index_To_Instance(unsigned index) return index; } -/* stubs to dependencies to keep unit test simple */ +char *Analog_Output_Name(uint32_t object_instance) +{ + (void) object_instance; + return ""; +} + +unsigned Analog_Output_Count(void) +{ + return 0; +} + +uint32_t Analog_Output_Index_To_Instance(unsigned index) +{ + return index; +} + +char *Analog_Value_Name(uint32_t object_instance) +{ + (void) object_instance; + return ""; +} + +unsigned Analog_Value_Count(void) +{ + return 0; +} + +uint32_t Analog_Value_Index_To_Instance(unsigned index) +{ + return index; +} + char *Binary_Input_Name(uint32_t object_instance) { (void) object_instance; @@ -945,34 +995,18 @@ uint32_t Binary_Output_Index_To_Instance(unsigned index) return index; } -char *Analog_Output_Name(uint32_t object_instance) +char *Binary_Value_Name(uint32_t object_instance) { (void) object_instance; return ""; } -unsigned Analog_Output_Count(void) +unsigned Binary_Value_Count(void) { return 0; } -uint32_t Analog_Output_Index_To_Instance(unsigned index) -{ - return index; -} - -char *Analog_Value_Name(uint32_t object_instance) -{ - (void) object_instance; - return ""; -} - -unsigned Analog_Value_Count(void) -{ - return 0; -} - -uint32_t Analog_Value_Index_To_Instance(unsigned index) +uint32_t Binary_Value_Index_To_Instance(unsigned index) { return index; } diff --git a/bacnet-stack/iam.c b/bacnet-stack/iam.c index 79388f30..9caec26b 100755 --- a/bacnet-stack/iam.c +++ b/bacnet-stack/iam.c @@ -35,6 +35,7 @@ #include "bacenum.h" #include "bacdef.h" #include "npdu.h" +#include "dcc.h" #include "datalink.h" #include "device.h" #include "bacdcode.h" @@ -142,6 +143,10 @@ int iam_send(uint8_t * buffer) int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; + /* if we are forbidden to send, don't send! */ + if (!dcc_communication_enabled()) + return 0; + /* I-Am is a global broadcast */ datalink_get_broadcast_address(&dest); /* encode the NPDU portion of the packet */ diff --git a/bacnet-stack/ports/linux/ethernet.c b/bacnet-stack/ports/linux/ethernet.c index f9bbf5f3..8e4f5e5c 100644 --- a/bacnet-stack/ports/linux/ethernet.c +++ b/bacnet-stack/ports/linux/ethernet.c @@ -189,7 +189,7 @@ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */ uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */ int mtu_len = 0; - (void)ndpu_data; + (void)npdu_data; /* load the BACnet address for NPDU data */ for (i = 0; i < 6; i++) { src.mac[i] = Ethernet_MAC_Address[i]; diff --git a/bacnet-stack/ports/pic18/main.c b/bacnet-stack/ports/pic18/main.c index 0df3b53c..8fc845d9 100644 --- a/bacnet-stack/ports/pic18/main.c +++ b/bacnet-stack/ports/pic18/main.c @@ -71,14 +71,20 @@ void My_Read_Property_Handler(uint8_t * service_request, BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_NPDU_DATA npdu_data; + BACNET_ADDRESS my_address; len = rp_decode_service_request(service_request, service_len, &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 - send an abort */ if (len < 0) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER); } else if (service_data->segmented_message) { - pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0], + len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED); } else { @@ -94,8 +100,8 @@ void My_Read_Property_Handler(uint8_t * service_request, data.application_data = &Temp_Buf[0]; data.application_data_len = len; /* FIXME: probably need a length limitation sent with encode */ - pdu_len = - rp_ack_encode_apdu(&Handler_Transmit_Buffer[0], + len = + rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); } else error = true; @@ -108,12 +114,13 @@ void My_Read_Property_Handler(uint8_t * service_request, } } if (error) { - pdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[0], + len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code); } - npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL); - bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */ + pdu_len += len; + bytes_sent = datalink_send_pdu(src, &npdu_data, + &Handler_Transmit_Buffer[0], pdu_len); return; }