Corrected the NPDU encoding for the demo handlers.
This commit is contained in:
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user