Corrected the NPDU encoding for the demo handlers.
This commit is contained in:
+60
-43
@@ -1040,66 +1040,83 @@ typedef enum {
|
|||||||
LAST_PROPRIETARY_ERROR_CLASS = 65535
|
LAST_PROPRIETARY_ERROR_CLASS = 65535
|
||||||
} BACNET_ERROR_CLASS;
|
} 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 {
|
typedef enum {
|
||||||
|
/* valid for all classes */
|
||||||
ERROR_CODE_OTHER = 0,
|
ERROR_CODE_OTHER = 0,
|
||||||
ERROR_CODE_AUTHENTICATION_FAILED = 1,
|
|
||||||
ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41,
|
/* Error Class - Device */
|
||||||
ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2,
|
|
||||||
ERROR_CODE_DATATYPE_NOT_SUPPORTED = 47,
|
|
||||||
ERROR_CODE_DEVICE_BUSY = 3,
|
ERROR_CODE_DEVICE_BUSY = 3,
|
||||||
ERROR_CODE_DUPLICATE_NAME = 48,
|
ERROR_CODE_CONFIGURATION_IN_PROGRESS = 2,
|
||||||
ERROR_CODE_DUPLICATE_OBJECT_ID = 49,
|
ERROR_CODE_OPERATIONAL_PROBLEM = 25,
|
||||||
|
|
||||||
|
/* Error Class - Object */
|
||||||
ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED = 4,
|
ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED = 4,
|
||||||
ERROR_CODE_FILE_ACCESS_DENIED = 5,
|
ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17,
|
||||||
ERROR_CODE_INCOMPATIBLE_SECURITY_LEVELS = 6,
|
ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23,
|
||||||
ERROR_CODE_INCONSISTENT_PARAMETERS = 7,
|
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_INCONSISTENT_SELECTION_CRITERION = 8,
|
||||||
ERROR_CODE_INVALID_ARRAY_INDEX = 42,
|
ERROR_CODE_INVALID_ARRAY_INDEX = 42,
|
||||||
ERROR_CODE_INVALID_CONFIGURATION_DATA = 46,
|
|
||||||
ERROR_CODE_INVALID_DATA_TYPE = 9,
|
ERROR_CODE_INVALID_DATA_TYPE = 9,
|
||||||
ERROR_CODE_INVALID_FILE_ACCESS_METHOD = 10,
|
ERROR_CODE_NOT_COV_PROPERTY = 44,
|
||||||
ERROR_CODE_ERROR_CODE_INVALID_FILE_START_POSITION = 11,
|
ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45,
|
||||||
ERROR_CODE_INVALID_OPERATOR_NAME = 12,
|
ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY = 50,
|
||||||
ERROR_CODE_INVALID_PARAMETER_DATA_TYPE = 13,
|
/* ERROR_CODE_READ_ACCESS_DENIED = 27, */
|
||||||
ERROR_CODE_INVALID_TIME_STAMP = 14,
|
ERROR_CODE_UNKNOWN_PROPERTY = 32,
|
||||||
ERROR_CODE_KEY_GENERATION_ERROR = 15,
|
ERROR_CODE_VALUE_OUT_OF_RANGE = 37,
|
||||||
ERROR_CODE_MISSING_REQUIRED_PARAMETER = 16,
|
ERROR_CODE_WRITE_ACCESS_DENIED = 40,
|
||||||
ERROR_CODE_NO_OBJECTS_OF_SPECIFIED_TYPE = 17,
|
|
||||||
|
/* Error Class - Resources */
|
||||||
ERROR_CODE_NO_SPACE_FOR_OBJECT = 18,
|
ERROR_CODE_NO_SPACE_FOR_OBJECT = 18,
|
||||||
ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT = 19,
|
ERROR_CODE_NO_SPACE_TO_ADD_LIST_ELEMENT = 19,
|
||||||
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY = 20,
|
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY = 20,
|
||||||
ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21,
|
|
||||||
ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED = 23,
|
/* Error Class - Security */
|
||||||
ERROR_CODE_OBJECT_IDENTIFIER_ALREADY_EXISTS = 24,
|
ERROR_CODE_AUTHENTICATION_FAILED = 1,
|
||||||
ERROR_CODE_OPERATIONAL_PROBLEM = 25,
|
/* ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED = 41, */
|
||||||
ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED = 45,
|
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_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_SECURITY_NOT_SUPPORTED = 28,
|
||||||
ERROR_CODE_SERVICE_REQUEST_DENIED = 29,
|
|
||||||
ERROR_CODE_TIMEOUT = 30,
|
ERROR_CODE_TIMEOUT = 30,
|
||||||
ERROR_CODE_UNKNOWN_OBJECT = 31,
|
|
||||||
ERROR_CODE_UNKNOWN_PROPERTY = 32,
|
/* Error Class - Services */
|
||||||
ERROR_CODE_RESERVED1 = 33,
|
/* 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_CLASS = 34,
|
||||||
ERROR_CODE_UNKNOWN_VT_SESSION = 35,
|
ERROR_CODE_UNKNOWN_VT_SESSION = 35,
|
||||||
ERROR_CODE_UNSUPPORTED_OBJECT_TYPE = 36,
|
ERROR_CODE_NO_VT_SESSIONS_AVAILABLE = 21,
|
||||||
ERROR_CODE_VALUE_OUT_OF_RANGE = 37,
|
|
||||||
ERROR_CODE_VT_SESSION_ALREADY_CLOSED = 38,
|
ERROR_CODE_VT_SESSION_ALREADY_CLOSED = 38,
|
||||||
ERROR_CODE_VT_SESSION_TERMINATION_FAILURE = 39,
|
ERROR_CODE_VT_SESSION_TERMINATION_FAILURE = 39,
|
||||||
ERROR_CODE_WRITE_ACCESS_DENIED = 40,
|
|
||||||
/* see character-set-not-supported (41), */
|
/* unused */
|
||||||
/* see invalid-array-index (42), */
|
ERROR_CODE_RESERVED1 = 33,
|
||||||
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), */
|
|
||||||
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
|
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
|
||||||
/* Enumerated values 256-65535 may be used by others subject to */
|
/* Enumerated values 256-65535 may be used by others subject to */
|
||||||
/* the procedures and constraints described in Clause 23. */
|
/* the procedures and constraints described in Clause 23. */
|
||||||
|
|||||||
+11
-3
@@ -355,10 +355,18 @@ int ucov_notify_decode_apdu(uint8_t * apdu,
|
|||||||
|
|
||||||
|
|
||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
void npdu_encode_unconfirmed_apdu(BACNET_NPDU_DATA * npdu,
|
int npdu_encode_pdu(uint8_t * npdu,
|
||||||
BACNET_MESSAGE_PRIORITY priority)
|
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 */
|
/* dummy function stubs */
|
||||||
|
|||||||
@@ -41,6 +41,57 @@
|
|||||||
#include "ao.h"
|
#include "ao.h"
|
||||||
#include "bacfile.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,
|
void handler_atomic_read_file(uint8_t * service_request,
|
||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
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;
|
bool error = false;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
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
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Received Atomic-Read-File Request!\n");
|
fprintf(stderr, "Received Atomic-Read-File Request!\n");
|
||||||
#endif
|
#endif
|
||||||
len = arf_decode_service_request(service_request, service_len, &data);
|
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 */
|
/* bad decoding - send an abort */
|
||||||
if (len < 0) {
|
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);
|
service_data->invoke_id, ABORT_REASON_OTHER);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Bad Encoding. Sending Abort!\n");
|
fprintf(stderr, "Bad Encoding. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (service_data->segmented_message) {
|
} 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,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Segmented Message. Sending Abort!\n");
|
fprintf(stderr, "Segmented Message. Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else if (data.object_type == OBJECT_FILE) {
|
||||||
if (data.access == FILE_STREAM_ACCESS) {
|
if (!bacfile_valid_instance(data.object_instance)) {
|
||||||
|
error = true;
|
||||||
|
}
|
||||||
|
else if (data.access == FILE_STREAM_ACCESS) {
|
||||||
if (data.type.stream.requestedOctetCount <
|
if (data.type.stream.requestedOctetCount <
|
||||||
octetstring_capacity(&data.fileData)) {
|
octetstring_capacity(&data.fileData)) {
|
||||||
if (bacfile_read_data(&data)) {
|
if (bacfile_read_data(&data)) {
|
||||||
pdu_len =
|
len =
|
||||||
arf_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
} else {
|
} else {
|
||||||
error = true;
|
error = true;
|
||||||
|
error_class = ERROR_CLASS_OBJECT;
|
||||||
|
error_code = ERROR_CODE_FILE_ACCESS_DENIED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
abort_encode_apdu(&Handler_Transmit_Buffer[0],
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -92,17 +155,26 @@ void handler_atomic_read_file(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
error = true;
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
error_class = ERROR_CLASS_SERVICES;
|
||||||
service_data->invoke_id,
|
error_code = ERROR_CODE_INVALID_FILE_ACCESS_METHOD;
|
||||||
SERVICE_CONFIRMED_ATOMIC_READ_FILE, ERROR_CLASS_SERVICES,
|
|
||||||
ERROR_CODE_INVALID_FILE_ACCESS_METHOD);
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Record Access Requested. Sending Error!\n");
|
fprintf(stderr, "Record Access Requested. Sending Error!\n");
|
||||||
#endif
|
#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,
|
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -51,10 +51,16 @@ void handler_device_communication_control(uint8_t * service_request,
|
|||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
|
|
||||||
/* decode the service request only */
|
/* decode the service request only */
|
||||||
len = dcc_decode_service_request(service_request,
|
len = dcc_decode_service_request(service_request,
|
||||||
service_len, &timeDuration, &state, &password);
|
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
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "DeviceCommunicationControl!\n");
|
fprintf(stderr, "DeviceCommunicationControl!\n");
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
@@ -65,14 +71,14 @@ void handler_device_communication_control(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
/* bad decoding or something we didn't understand - send an abort */
|
/* bad decoding or something we didn't understand - send an abort */
|
||||||
if (len < 0) {
|
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);
|
service_data->invoke_id, ABORT_REASON_OTHER);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "DeviceCommunicationControl: "
|
fprintf(stderr, "DeviceCommunicationControl: "
|
||||||
"Sending Abort - could not decode.\n");
|
"Sending Abort - could not decode.\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (service_data->segmented_message) {
|
} 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,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -80,7 +86,7 @@ void handler_device_communication_control(uint8_t * service_request,
|
|||||||
"Sending Abort - segmented message.\n");
|
"Sending Abort - segmented message.\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) {
|
} 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);
|
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "DeviceCommunicationControl: "
|
fprintf(stderr, "DeviceCommunicationControl: "
|
||||||
@@ -88,7 +94,7 @@ void handler_device_communication_control(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if (characterstring_ansi_same(&password, My_Password)) {
|
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_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL);
|
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -97,8 +103,8 @@ void handler_device_communication_control(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
dcc_set_status_duration(state, timeDuration);
|
dcc_set_status_duration(state, timeDuration);
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||||
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
|
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
|
||||||
@@ -109,7 +115,7 @@ void handler_device_communication_control(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -51,10 +51,16 @@ void handler_reinitialize_device(uint8_t * service_request,
|
|||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
|
|
||||||
/* decode the service request only */
|
/* decode the service request only */
|
||||||
len = rd_decode_service_request(service_request,
|
len = rd_decode_service_request(service_request,
|
||||||
service_len, &state, &their_password);
|
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
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "ReinitializeDevice!\n");
|
fprintf(stderr, "ReinitializeDevice!\n");
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
@@ -65,14 +71,14 @@ void handler_reinitialize_device(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
/* bad decoding or something we didn't understand - send an abort */
|
/* bad decoding or something we didn't understand - send an abort */
|
||||||
if (len < 0) {
|
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);
|
service_data->invoke_id, ABORT_REASON_OTHER);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"ReinitializeDevice: Sending Abort - could not decode.\n");
|
"ReinitializeDevice: Sending Abort - could not decode.\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (service_data->segmented_message) {
|
} 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,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -80,7 +86,7 @@ void handler_reinitialize_device(uint8_t * service_request,
|
|||||||
"ReinitializeDevice: Sending Abort - segmented message.\n");
|
"ReinitializeDevice: Sending Abort - segmented message.\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (state >= MAX_BACNET_REINITIALIZED_STATE) {
|
} 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);
|
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -89,7 +95,7 @@ void handler_reinitialize_device(uint8_t * service_request,
|
|||||||
} else {
|
} else {
|
||||||
characterstring_init_ansi(&My_Password, Password);
|
characterstring_init_ansi(&My_Password, Password);
|
||||||
if (characterstring_same(&their_password, &My_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_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_REINITIALIZE_DEVICE);
|
SERVICE_CONFIRMED_REINITIALIZE_DEVICE);
|
||||||
#if PRINT_ENABLED
|
#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,
|
/* Note: if you don't do something clever like actually restart,
|
||||||
you probably should clear any DCC status and timeouts */
|
you probably should clear any DCC status and timeouts */
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
||||||
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
|
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
|
||||||
@@ -111,7 +117,7 @@ void handler_reinitialize_device(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
pdu_len += len;
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void handler_read_property(uint8_t * service_request,
|
|||||||
int len = 0;
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
bool error = true;
|
bool error = false;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_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);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src,
|
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src,
|
||||||
&my_address, &npdu_data);
|
&my_address, &npdu_data);
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
fprintf(stderr, "Unable to decode Read-Property Request!\n");
|
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");
|
fprintf(stderr, "Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
/* most cases will be error */
|
||||||
|
error = true;
|
||||||
switch (data.object_type) {
|
switch (data.object_type) {
|
||||||
case OBJECT_DEVICE:
|
case OBJECT_DEVICE:
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
@@ -110,11 +111,9 @@ void handler_read_property(uint8_t * service_request,
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Sending Read Property Ack for Device!\n");
|
"Sending Read Property Ack for Device!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_INPUT:
|
case OBJECT_ANALOG_INPUT:
|
||||||
if (Analog_Input_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Ack for AI!\n");
|
fprintf(stderr, "Sending Read Property Ack for AI!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_BINARY_INPUT:
|
case OBJECT_BINARY_INPUT:
|
||||||
if (Binary_Input_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Ack for BI!\n");
|
fprintf(stderr, "Sending Read Property Ack for BI!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_BINARY_OUTPUT:
|
case OBJECT_BINARY_OUTPUT:
|
||||||
if (Binary_Output_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Ack for BO!\n");
|
fprintf(stderr, "Sending Read Property Ack for BO!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_BINARY_VALUE:
|
case OBJECT_BINARY_VALUE:
|
||||||
if (Binary_Value_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Ack for BV!\n");
|
fprintf(stderr, "Sending Read Property Ack for BV!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_OUTPUT:
|
case OBJECT_ANALOG_OUTPUT:
|
||||||
if (Analog_Output_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Ack for AO!\n");
|
fprintf(stderr, "Sending Read Property Ack for AO!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_VALUE:
|
case OBJECT_ANALOG_VALUE:
|
||||||
if (Analog_Value_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Ack for AV!\n");
|
fprintf(stderr, "Sending Read Property Ack for AV!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_LIFE_SAFETY_POINT:
|
case OBJECT_LIFE_SAFETY_POINT:
|
||||||
if (Life_Safety_Point_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Sending Read Property Ack for LSP!\n");
|
"Sending Read Property Ack for LSP!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_MULTI_STATE_OUTPUT:
|
case OBJECT_MULTI_STATE_OUTPUT:
|
||||||
if (Multistate_Output_Valid_Instance(data.object_instance)) {
|
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 = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Sending Read Property Ack for MSO!\n");
|
"Sending Read Property Ack for MSO!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
#if BACFILE
|
#if BACFILE
|
||||||
case OBJECT_FILE:
|
case OBJECT_FILE:
|
||||||
@@ -314,22 +297,19 @@ void handler_read_property(uint8_t * service_request,
|
|||||||
data.application_data = &Temp_Buf[0];
|
data.application_data = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Sending Read Property Ack for File!\n");
|
"Sending Read Property Ack for File!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
error = false;
|
||||||
} else
|
}
|
||||||
error = true;
|
}
|
||||||
} else
|
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
#endif /* BACFILE */
|
#endif /* BACFILE */
|
||||||
default:
|
default:
|
||||||
error = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,16 +320,14 @@ void handler_read_property(uint8_t * service_request,
|
|||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Read Property Error!\n");
|
fprintf(stderr, "Sending Read Property Error!\n");
|
||||||
#endif
|
#endif
|
||||||
send = true;
|
|
||||||
}
|
}
|
||||||
if (send) {
|
pdu_len += len;
|
||||||
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0)
|
if (bytes_sent <= 0)
|
||||||
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
|
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,10 +60,16 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
|
|
||||||
/* decode the service request only */
|
/* decode the service request only */
|
||||||
len = wp_decode_service_request(service_request,
|
len = wp_decode_service_request(service_request,
|
||||||
service_len, &wp_data);
|
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
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Received Write-Property Request!\n");
|
fprintf(stderr, "Received Write-Property Request!\n");
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
@@ -76,13 +82,13 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
#endif
|
#endif
|
||||||
/* bad decoding or something we didn't understand - send an abort */
|
/* bad decoding or something we didn't understand - send an abort */
|
||||||
if (len <= 0) {
|
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);
|
service_data->invoke_id, ABORT_REASON_OTHER);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Abort!\n");
|
fprintf(stderr, "Sending Abort!\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (service_data->segmented_message) {
|
} 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,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -92,8 +98,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
switch (wp_data.object_type) {
|
switch (wp_data.object_type) {
|
||||||
case OBJECT_DEVICE:
|
case OBJECT_DEVICE:
|
||||||
if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
|
if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -101,8 +107,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for Device!\n");
|
"Sending Write Property Simple Ack for Device!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -116,8 +122,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_BINARY_INPUT:
|
case OBJECT_BINARY_INPUT:
|
||||||
error_class = ERROR_CLASS_PROPERTY;
|
error_class = ERROR_CLASS_PROPERTY;
|
||||||
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||||
error_class, error_code);
|
error_class, error_code);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -127,8 +133,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_BINARY_OUTPUT:
|
case OBJECT_BINARY_OUTPUT:
|
||||||
if (Binary_Output_Write_Property(&wp_data, &error_class,
|
if (Binary_Output_Write_Property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -136,8 +142,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for BO!\n");
|
"Sending Write Property Simple Ack for BO!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -149,8 +155,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_BINARY_VALUE:
|
case OBJECT_BINARY_VALUE:
|
||||||
if (Binary_Value_Write_Property(&wp_data, &error_class,
|
if (Binary_Value_Write_Property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -158,8 +164,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for BV!\n");
|
"Sending Write Property Simple Ack for BV!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -171,8 +177,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_ANALOG_OUTPUT:
|
case OBJECT_ANALOG_OUTPUT:
|
||||||
if (Analog_Output_Write_Property(&wp_data, &error_class,
|
if (Analog_Output_Write_Property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -180,8 +186,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for AO!\n");
|
"Sending Write Property Simple Ack for AO!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -193,8 +199,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_ANALOG_VALUE:
|
case OBJECT_ANALOG_VALUE:
|
||||||
if (Analog_Value_Write_Property(&wp_data, &error_class,
|
if (Analog_Value_Write_Property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -202,8 +208,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for AV!\n");
|
"Sending Write Property Simple Ack for AV!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -215,8 +221,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_LIFE_SAFETY_POINT:
|
case OBJECT_LIFE_SAFETY_POINT:
|
||||||
if (Life_Safety_Point_Write_Property(&wp_data, &error_class,
|
if (Life_Safety_Point_Write_Property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -224,8 +230,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for LSP!\n");
|
"Sending Write Property Simple Ack for LSP!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -237,8 +243,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_MULTI_STATE_OUTPUT:
|
case OBJECT_MULTI_STATE_OUTPUT:
|
||||||
if (Multistate_Output_Write_Property(&wp_data, &error_class,
|
if (Multistate_Output_Write_Property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -246,8 +252,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for MSO!\n");
|
"Sending Write Property Simple Ack for MSO!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -260,8 +266,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
case OBJECT_FILE:
|
case OBJECT_FILE:
|
||||||
if (bacfile_write_property(&wp_data, &error_class,
|
if (bacfile_write_property(&wp_data, &error_class,
|
||||||
&error_code)) {
|
&error_code)) {
|
||||||
pdu_len =
|
len =
|
||||||
encode_simple_ack(&Handler_Transmit_Buffer[0],
|
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
SERVICE_CONFIRMED_WRITE_PROPERTY);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -269,8 +275,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
"Sending Write Property Simple Ack for File!\n");
|
"Sending Write Property Simple Ack for File!\n");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
@@ -281,8 +287,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
pdu_len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||||
error_class, error_code);
|
error_class, error_code);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
@@ -291,7 +297,7 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
pdu_len += len;
|
||||||
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -36,22 +36,28 @@
|
|||||||
|
|
||||||
void handler_unrecognized_service(uint8_t * service_request,
|
void handler_unrecognized_service(uint8_t * service_request,
|
||||||
uint16_t service_len,
|
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 pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
|
|
||||||
(void) service_request;
|
(void) service_request;
|
||||||
(void) service_len;
|
(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 */
|
/* 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 */
|
/* 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);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent > 0)
|
if (bytes_sent > 0)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
|
#include "dcc.h"
|
||||||
#include "tsm.h"
|
#include "tsm.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
@@ -46,14 +47,20 @@ uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id,
|
|||||||
int fileStartPosition, unsigned requestedOctetCount)
|
int fileStartPosition, unsigned requestedOctetCount)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_ATOMIC_READ_FILE_DATA data;
|
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? */
|
/* is the device bound? */
|
||||||
status = address_get_by_device(device_id, &max_apdu, &dest);
|
status = address_get_by_device(device_id, &max_apdu, &dest);
|
||||||
/* is there a tsm available? */
|
/* 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.access = FILE_STREAM_ACCESS;
|
||||||
data.type.stream.fileStartPosition = fileStartPosition;
|
data.type.stream.fileStartPosition = fileStartPosition;
|
||||||
data.type.stream.requestedOctetCount = requestedOctetCount;
|
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);
|
invoke_id, &data);
|
||||||
|
pdu_len += len;
|
||||||
/* will the APDU fit the target device?
|
/* will the APDU fit the target device?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
npdu_encode_confirmed_apdu(&npdu_data,
|
|
||||||
MESSAGE_PRIORITY_NORMAL);
|
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
#include "tsm.h"
|
#include "tsm.h"
|
||||||
|
#include "dcc.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "device.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)
|
int fileStartPosition, BACNET_OCTET_STRING * fileData)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_ATOMIC_WRITE_FILE_DATA data;
|
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? */
|
/* is the device bound? */
|
||||||
status = address_get_by_device(device_id, &max_apdu, &dest);
|
status = address_get_by_device(device_id, &max_apdu, &dest);
|
||||||
/* is there a tsm available? */
|
/* 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;
|
data.type.stream.fileStartPosition = fileStartPosition;
|
||||||
status = octetstring_copy(&data.fileData, fileData);
|
status = octetstring_copy(&data.fileData, fileData);
|
||||||
if (status) {
|
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);
|
invoke_id, &data);
|
||||||
|
pdu_len += len;
|
||||||
/* will the APDU fit the target device?
|
/* will the APDU fit the target device?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len <= max_apdu) {
|
if ((unsigned) pdu_len <= max_apdu) {
|
||||||
npdu_encode_confirmed_apdu(&npdu_data,
|
|
||||||
MESSAGE_PRIORITY_NORMAL);
|
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
|
|||||||
@@ -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)
|
BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password)
|
||||||
{ /* NULL=optional */
|
{ /* NULL=optional */
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_CHARACTER_STRING password_string;
|
BACNET_CHARACTER_STRING password_string;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
|
|
||||||
|
/* if we are forbidden to send, don't send! */
|
||||||
if (!dcc_communication_enabled())
|
if (!dcc_communication_enabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -63,19 +66,23 @@ uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t t
|
|||||||
if (status)
|
if (status)
|
||||||
invoke_id = tsm_next_free_invokeID();
|
invoke_id = tsm_next_free_invokeID();
|
||||||
if (invoke_id) {
|
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);
|
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,
|
invoke_id,
|
||||||
timeDuration, state, password ? &password_string : NULL);
|
timeDuration, state, password ? &password_string : NULL);
|
||||||
|
pdu_len += len;
|
||||||
/* will it fit in the sender?
|
/* will it fit in the sender?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
npdu_encode_confirmed_apdu(&npdu_data,
|
|
||||||
MESSAGE_PRIORITY_NORMAL);
|
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ void Send_I_Have(uint32_t device_id,
|
|||||||
BACNET_OBJECT_TYPE object_type,
|
BACNET_OBJECT_TYPE object_type,
|
||||||
uint32_t object_instance, char *object_name)
|
uint32_t object_instance, char *object_name)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
@@ -59,16 +60,21 @@ void Send_I_Have(uint32_t device_id,
|
|||||||
return;
|
return;
|
||||||
/* Who-Has is a global broadcast */
|
/* Who-Has is a global broadcast */
|
||||||
datalink_get_broadcast_address(&dest);
|
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 */
|
/* encode the APDU portion of the packet */
|
||||||
data.device_id.type = OBJECT_DEVICE;
|
data.device_id.type = OBJECT_DEVICE;
|
||||||
data.device_id.instance = device_id;
|
data.device_id.instance = device_id;
|
||||||
data.object_id.type = object_type;
|
data.object_id.type = object_type;
|
||||||
data.object_id.instance = object_instance;
|
data.object_id.instance = object_instance;
|
||||||
characterstring_init_ansi(&data.object_name, object_name);
|
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 */
|
/* send the data */
|
||||||
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
||||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
if (bytes_sent <= 0)
|
if (bytes_sent <= 0)
|
||||||
fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n",
|
fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n",
|
||||||
|
|||||||
@@ -46,14 +46,17 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
|
|||||||
BACNET_REINITIALIZED_STATE state, char *password)
|
BACNET_REINITIALIZED_STATE state, char *password)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_CHARACTER_STRING password_string;
|
BACNET_CHARACTER_STRING password_string;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
|
|
||||||
|
/* if we are forbidden to send, don't send! */
|
||||||
if (!dcc_communication_enabled())
|
if (!dcc_communication_enabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -63,18 +66,22 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
|
|||||||
if (status)
|
if (status)
|
||||||
invoke_id = tsm_next_free_invokeID();
|
invoke_id = tsm_next_free_invokeID();
|
||||||
if (invoke_id) {
|
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);
|
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);
|
invoke_id, state, password ? &password_string : NULL);
|
||||||
|
pdu_len += len;
|
||||||
/* will it fit in the sender?
|
/* will it fit in the sender?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
npdu_encode_confirmed_apdu(&npdu_data,
|
|
||||||
MESSAGE_PRIORITY_NORMAL);
|
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
|
|||||||
@@ -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_PROPERTY_ID object_property, int32_t array_index)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_READ_PROPERTY_DATA data;
|
BACNET_READ_PROPERTY_DATA data;
|
||||||
@@ -67,21 +69,25 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
|
|||||||
if (status)
|
if (status)
|
||||||
invoke_id = tsm_next_free_invokeID();
|
invoke_id = tsm_next_free_invokeID();
|
||||||
if (invoke_id) {
|
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_type = object_type;
|
||||||
data.object_instance = object_instance;
|
data.object_instance = object_instance;
|
||||||
data.object_property = object_property;
|
data.object_property = object_property;
|
||||||
data.array_index = array_index;
|
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);
|
invoke_id, &data);
|
||||||
|
pdu_len += len;
|
||||||
/* will it fit in the sender?
|
/* will it fit in the sender?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
npdu_encode_confirmed_apdu(&npdu_data,
|
|
||||||
MESSAGE_PRIORITY_NORMAL);
|
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime)
|
void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
@@ -54,10 +55,14 @@ void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime)
|
|||||||
|
|
||||||
/* we could use unicast or broadcast */
|
/* we could use unicast or broadcast */
|
||||||
datalink_get_broadcast_address(&dest);
|
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 */
|
/* 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);
|
bdate, btime);
|
||||||
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
pdu_len += len;
|
||||||
/* send it out the datalink */
|
/* send it out the datalink */
|
||||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&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 */
|
/* encode the APDU portion of the packet */
|
||||||
pdu_len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[0],
|
pdu_len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[0],
|
||||||
bdate, btime);
|
bdate, btime);
|
||||||
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
|
||||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
void Send_WhoHas_Name(int32_t low_limit,
|
void Send_WhoHas_Name(int32_t low_limit,
|
||||||
int32_t high_limit, char *object_name)
|
int32_t high_limit, char *object_name)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
@@ -57,13 +58,17 @@ void Send_WhoHas_Name(int32_t low_limit,
|
|||||||
return;
|
return;
|
||||||
/* Who-Has is a global broadcast */
|
/* Who-Has is a global broadcast */
|
||||||
datalink_get_broadcast_address(&dest);
|
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 */
|
/* encode the APDU portion of the packet */
|
||||||
data.low_limit = low_limit;
|
data.low_limit = low_limit;
|
||||||
data.high_limit = high_limit;
|
data.high_limit = high_limit;
|
||||||
data.object_name = true;
|
data.object_name = true;
|
||||||
characterstring_init_ansi(&data.object.name, object_name);
|
characterstring_init_ansi(&data.object.name, object_name);
|
||||||
pdu_len = whohas_encode_apdu(&Handler_Transmit_Buffer[0], &data);
|
len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
|
||||||
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
pdu_len += len;
|
||||||
/* send the data */
|
/* send the data */
|
||||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&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.type = object_type;
|
||||||
data.object.identifier.instance = object_instance;
|
data.object.identifier.instance = object_instance;
|
||||||
pdu_len = whohas_encode_apdu(&Handler_Transmit_Buffer[0], &data);
|
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,
|
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
/* find a specific device, or use -1 for limit if you want unlimited */
|
/* find a specific device, or use -1 for limit if you want unlimited */
|
||||||
void Send_WhoIs(int32_t low_limit, int32_t high_limit)
|
void Send_WhoIs(int32_t low_limit, int32_t high_limit)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
int bytes_sent = 0;
|
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 */
|
/* Who-Is is a global broadcast */
|
||||||
datalink_get_broadcast_address(&dest);
|
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 */
|
/* 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);
|
low_limit, high_limit);
|
||||||
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
|
pdu_len += len;
|
||||||
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -51,9 +51,11 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
|
|||||||
uint8_t priority, int32_t array_index)
|
uint8_t priority, int32_t array_index)
|
||||||
{
|
{
|
||||||
BACNET_ADDRESS dest;
|
BACNET_ADDRESS dest;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
unsigned max_apdu = 0;
|
unsigned max_apdu = 0;
|
||||||
uint8_t invoke_id = 0;
|
uint8_t invoke_id = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
int len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_WRITE_PROPERTY_DATA data;
|
BACNET_WRITE_PROPERTY_DATA data;
|
||||||
@@ -68,23 +70,27 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
|
|||||||
if (status)
|
if (status)
|
||||||
invoke_id = tsm_next_free_invokeID();
|
invoke_id = tsm_next_free_invokeID();
|
||||||
if (invoke_id) {
|
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_type = object_type;
|
||||||
data.object_instance = object_instance;
|
data.object_instance = object_instance;
|
||||||
data.object_property = object_property;
|
data.object_property = object_property;
|
||||||
data.array_index = array_index;
|
data.array_index = array_index;
|
||||||
bacapp_copy(&data.value, object_value);
|
bacapp_copy(&data.value, object_value);
|
||||||
data.priority = priority;
|
data.priority = priority;
|
||||||
pdu_len = wp_encode_apdu(&Handler_Transmit_Buffer[0],
|
len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
invoke_id, &data);
|
invoke_id, &data);
|
||||||
|
pdu_len += len;
|
||||||
/* will it fit in the sender?
|
/* will it fit in the sender?
|
||||||
note: if there is a bottleneck router in between
|
note: if there is a bottleneck router in between
|
||||||
us and the destination, we won't know unless
|
us and the destination, we won't know unless
|
||||||
we have a way to check for that and update the
|
we have a way to check for that and update the
|
||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
npdu_encode_confirmed_apdu(&npdu_data,
|
|
||||||
MESSAGE_PRIORITY_NORMAL);
|
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
|
|||||||
found = tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0],
|
found = tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0],
|
||||||
&apdu_len);
|
&apdu_len);
|
||||||
if (found) {
|
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)) {
|
&& (apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
|
||||||
len =
|
len =
|
||||||
apdu_decode_confirmed_service_request(&apdu[0],
|
apdu_decode_confirmed_service_request(&apdu[0],
|
||||||
|
|||||||
@@ -325,10 +325,11 @@ unsigned Device_Object_List_Count(void)
|
|||||||
unsigned count = 1;
|
unsigned count = 1;
|
||||||
|
|
||||||
count += Analog_Input_Count();
|
count += Analog_Input_Count();
|
||||||
count += Binary_Input_Count();
|
|
||||||
count += Binary_Output_Count();
|
|
||||||
count += Analog_Output_Count();
|
count += Analog_Output_Count();
|
||||||
count += Analog_Value_Count();
|
count += Analog_Value_Count();
|
||||||
|
count += Binary_Input_Count();
|
||||||
|
count += Binary_Output_Count();
|
||||||
|
count += Binary_Value_Count();
|
||||||
count += Life_Safety_Point_Count();
|
count += Life_Safety_Point_Count();
|
||||||
count += Multistate_Output_Count();
|
count += Multistate_Output_Count();
|
||||||
#if BACFILE
|
#if BACFILE
|
||||||
@@ -362,6 +363,32 @@ bool Device_Object_List_Identifier(unsigned array_index,
|
|||||||
status = true;
|
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 */
|
/* binary input objects */
|
||||||
if (!status) {
|
if (!status) {
|
||||||
/* normalize the index since
|
/* normalize the index since
|
||||||
@@ -388,29 +415,16 @@ bool Device_Object_List_Identifier(unsigned array_index,
|
|||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* analog output objects */
|
/* binary value objects */
|
||||||
if (!status) {
|
if (!status) {
|
||||||
/* normalize the index since
|
/* normalize the index since
|
||||||
we know it is not the previous objects */
|
we know it is not the previous objects */
|
||||||
object_index -= object_count;
|
object_index -= object_count;
|
||||||
object_count = Analog_Output_Count();
|
object_count = Binary_Value_Count();
|
||||||
/* is it a valid index for this object? */
|
/* is it a valid index for this object? */
|
||||||
if (object_index < object_count) {
|
if (object_index < object_count) {
|
||||||
*object_type = OBJECT_ANALOG_OUTPUT;
|
*object_type = OBJECT_BINARY_VALUE;
|
||||||
*instance = Analog_Output_Index_To_Instance(object_index);
|
*instance = Binary_Value_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;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,17 +511,20 @@ char *Device_Valid_Object_Id(int object_type, uint32_t object_instance)
|
|||||||
case OBJECT_ANALOG_INPUT:
|
case OBJECT_ANALOG_INPUT:
|
||||||
name = Analog_Input_Name(object_instance);
|
name = Analog_Input_Name(object_instance);
|
||||||
break;
|
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:
|
case OBJECT_BINARY_INPUT:
|
||||||
name = Binary_Input_Name(object_instance);
|
name = Binary_Input_Name(object_instance);
|
||||||
break;
|
break;
|
||||||
case OBJECT_BINARY_OUTPUT:
|
case OBJECT_BINARY_OUTPUT:
|
||||||
name = Binary_Output_Name(object_instance);
|
name = Binary_Output_Name(object_instance);
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_OUTPUT:
|
case OBJECT_BINARY_VALUE:
|
||||||
name = Analog_Output_Name(object_instance);
|
name = Binary_Value_Name(object_instance);
|
||||||
break;
|
|
||||||
case OBJECT_ANALOG_VALUE:
|
|
||||||
name = Analog_Value_Name(object_instance);
|
|
||||||
break;
|
break;
|
||||||
case OBJECT_LIFE_SAFETY_POINT:
|
case OBJECT_LIFE_SAFETY_POINT:
|
||||||
name = Life_Safety_Point_Name(object_instance);
|
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);
|
bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true);
|
||||||
if (Binary_Output_Count())
|
if (Binary_Output_Count())
|
||||||
bitstring_set_bit(&bit_string, OBJECT_BINARY_OUTPUT, true);
|
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())
|
if (Life_Safety_Point_Count())
|
||||||
bitstring_set_bit(&bit_string, OBJECT_LIFE_SAFETY_POINT, true);
|
bitstring_set_bit(&bit_string, OBJECT_LIFE_SAFETY_POINT, true);
|
||||||
if (Multistate_Output_Count())
|
if (Multistate_Output_Count())
|
||||||
@@ -912,7 +931,38 @@ uint32_t Analog_Input_Index_To_Instance(unsigned index)
|
|||||||
return 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)
|
char *Binary_Input_Name(uint32_t object_instance)
|
||||||
{
|
{
|
||||||
(void) object_instance;
|
(void) object_instance;
|
||||||
@@ -945,34 +995,18 @@ uint32_t Binary_Output_Index_To_Instance(unsigned index)
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Analog_Output_Name(uint32_t object_instance)
|
char *Binary_Value_Name(uint32_t object_instance)
|
||||||
{
|
{
|
||||||
(void) object_instance;
|
(void) object_instance;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Analog_Output_Count(void)
|
unsigned Binary_Value_Count(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Analog_Output_Index_To_Instance(unsigned index)
|
uint32_t Binary_Value_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;
|
return index;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "bacenum.h"
|
#include "bacenum.h"
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
|
#include "dcc.h"
|
||||||
#include "datalink.h"
|
#include "datalink.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
@@ -142,6 +143,10 @@ int iam_send(uint8_t * buffer)
|
|||||||
int bytes_sent = 0;
|
int bytes_sent = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
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 */
|
/* I-Am is a global broadcast */
|
||||||
datalink_get_broadcast_address(&dest);
|
datalink_get_broadcast_address(&dest);
|
||||||
/* encode the NPDU portion of the packet */
|
/* encode the NPDU portion of the packet */
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|||||||
uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */
|
uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */
|
||||||
int mtu_len = 0;
|
int mtu_len = 0;
|
||||||
|
|
||||||
(void)ndpu_data;
|
(void)npdu_data;
|
||||||
/* load the BACnet address for NPDU data */
|
/* load the BACnet address for NPDU data */
|
||||||
for (i = 0; i < 6; i++) {
|
for (i = 0; i < 6; i++) {
|
||||||
src.mac[i] = Ethernet_MAC_Address[i];
|
src.mac[i] = Ethernet_MAC_Address[i];
|
||||||
|
|||||||
@@ -71,14 +71,20 @@ void My_Read_Property_Handler(uint8_t * service_request,
|
|||||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
|
BACNET_ADDRESS my_address;
|
||||||
|
|
||||||
len = rp_decode_service_request(service_request, service_len, &data);
|
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 */
|
/* bad decoding - send an abort */
|
||||||
if (len < 0) {
|
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);
|
service_data->invoke_id, ABORT_REASON_OTHER);
|
||||||
} else if (service_data->segmented_message) {
|
} 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,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
|
||||||
} else {
|
} else {
|
||||||
@@ -94,8 +100,8 @@ void My_Read_Property_Handler(uint8_t * service_request,
|
|||||||
data.application_data = &Temp_Buf[0];
|
data.application_data = &Temp_Buf[0];
|
||||||
data.application_data_len = len;
|
data.application_data_len = len;
|
||||||
/* FIXME: probably need a length limitation sent with encode */
|
/* FIXME: probably need a length limitation sent with encode */
|
||||||
pdu_len =
|
len =
|
||||||
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
|
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
} else
|
} else
|
||||||
error = true;
|
error = true;
|
||||||
@@ -108,12 +114,13 @@ void My_Read_Property_Handler(uint8_t * service_request,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error) {
|
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_data->invoke_id,
|
||||||
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
||||||
}
|
}
|
||||||
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); /* number of bytes of data */
|
bytes_sent = datalink_send_pdu(src, &npdu_data,
|
||||||
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user