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