Corrected the NPDU encoding for the demo handlers.

This commit is contained in:
skarg
2006-09-23 22:02:04 +00:00
parent 07a1077b2d
commit 337bc5ab4e
23 changed files with 502 additions and 289 deletions
+60 -43
View File
@@ -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
View File
@@ -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 */
+87 -15
View File
@@ -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
+13 -7
View File
@@ -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
+13 -7
View File
@@ -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
+56 -78
View File
@@ -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;
}
+45 -39
View File
@@ -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
+12 -6
View File
@@ -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)
+14 -3
View File
@@ -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 =
+15 -3
View File
@@ -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 =
+11 -4
View File
@@ -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 =
+9 -3
View File
@@ -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",
+11 -4
View File
@@ -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 =
+10 -4
View File
@@ -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 =
+7 -3
View File
@@ -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
+7 -3
View File
@@ -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
+7 -2
View File
@@ -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
+10 -4
View File
@@ -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 =
+1 -1
View File
@@ -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],
+78 -44
View File
@@ -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;
}
+5
View File
@@ -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 */
+1 -1
View File
@@ -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];
+14 -7
View File
@@ -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;
}