Changed the API to pass the NPDU data down through the datalink layer in order to make the dlmstp work since it needs data-expecting-reply information. Of course, this affected all the demos, all the unit tests, and most of the demo handlers. Corrected some TSM leaks in confirmed messages. Refactored the AtomicReadFile and AtomicWriteFile demos by moving the Send_ functions to the demo/handlers directory and using the s_whois common handler. Added some common defines for the BACnet version and revision since several modules were using the info. Hopefully I didn't break too many things.

This commit is contained in:
skarg
2006-08-13 00:54:05 +00:00
parent 185d02a9ff
commit 5bb205dc03
46 changed files with 793 additions and 638 deletions
+7
View File
@@ -76,6 +76,13 @@ extern "C" {
void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime);
void Send_TimeSyncUTC(BACNET_DATE * bdate, BACNET_TIME * btime);
uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id,
uint32_t file_instance, int fileStartPosition,
unsigned requestedOctetCount);
uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, BACNET_OCTET_STRING * fileData);
#ifdef __cplusplus
}
+31 -41
View File
@@ -48,75 +48,65 @@ void handler_atomic_read_file(uint8_t * service_request,
BACNET_ATOMIC_READ_FILE_DATA data;
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS my_address;
bool send = false;
bool error = false;
int bytes_sent = 0;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_NPDU_DATA npdu_data;
#if PRINT_ENABLED
fprintf(stderr, "Received Atomic-Read-File Request!\n");
#endif
len = arf_decode_service_request(service_request, service_len, &data);
if (len < 0)
fprintf(stderr, "Unable to decode Atomic-Read-File Request!\n");
/* prepare a reply */
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* bad decoding - send an abort */
if (len < 0) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, ABORT_REASON_OTHER);
fprintf(stderr, "Sending Abort!\n");
send = true;
#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[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
fprintf(stderr, "Sending Abort!\n");
send = true;
#if PRINT_ENABLED
fprintf(stderr, "Segmented Message. Sending Abort!\n");
#endif
} 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
[pdu_len], service_data->invoke_id, &data);
send = true;
pdu_len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
} else {
send = true;
error = true;
}
} else {
pdu_len +=
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
fprintf(stderr, "Sending Abort!\n");
send = true;
#if PRINT_ENABLED
fprintf(stderr, "Too Big To Send. Sending Abort!\n");
#endif
}
} else {
error_class = ERROR_CLASS_SERVICES;
error_code = ERROR_CODE_INVALID_FILE_ACCESS_METHOD;
send = true;
error = true;
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);
#if PRINT_ENABLED
fprintf(stderr, "Record Access Requested. Sending Error!\n");
#endif
}
}
if (error) {
pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code);
fprintf(stderr, "Sending Error!\n");
send = true;
}
if (send) {
bytes_sent = datalink_send_pdu(src, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
if (bytes_sent <= 0)
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
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
if (bytes_sent <= 0) {
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
}
#endif
return;
}
+6
View File
@@ -62,7 +62,9 @@ void handler_atomic_read_file_ack(uint8_t * service_request,
instance = bacfile_instance_from_tsm(service_data->invoke_id);
len = arf_ack_decode_service_request(service_request,
service_len, &data);
#if PRINT_ENABLED
fprintf(stderr, "Received Read-File Ack!\n");
#endif
if ((len > 0) && (instance <= BACNET_MAX_INSTANCE)) {
/* write the data received to the file specified */
if (data.access == FILE_STREAM_ACCESS) {
@@ -75,8 +77,12 @@ void handler_atomic_read_file_ack(uint8_t * service_request,
if (fwrite(octetstring_value(&data.fileData),
octetstring_length(&data.fileData), 1,
pFile) != 1)
{
#if PRINT_ENABLED
fprintf(stderr, "Failed to write to %s (%u)!\n",
pFilename, instance);
#endif
}
fclose(pFile);
}
}
+12 -19
View File
@@ -38,7 +38,7 @@
#include "reject.h"
#include "dcc.h"
static char *My_Password = "AnnaRoseKarg";
static char *My_Password = "filister";
void handler_device_communication_control(uint8_t * service_request,
uint16_t service_len,
@@ -49,8 +49,8 @@ void handler_device_communication_control(uint8_t * service_request,
BACNET_CHARACTER_STRING password;
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS my_address;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
/* decode the service request only */
len = dcc_decode_service_request(service_request,
@@ -62,25 +62,17 @@ void handler_device_communication_control(uint8_t * service_request,
"timeout=%u state=%u password=%s\n",
(unsigned) timeDuration,
(unsigned) state, characterstring_value(&password));
else
fprintf(stderr, "DeviceCommunicationControl: "
"Unable to decode request!\n");
#endif
/* prepare a reply */
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* bad decoding or something we didn't understand - send an abort */
if (len == -1) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
if (len < 0) {
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
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[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
#if PRINT_ENABLED
@@ -88,7 +80,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[pdu_len],
pdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
#if PRINT_ENABLED
fprintf(stderr, "DeviceCommunicationControl: "
@@ -96,7 +88,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[pdu_len],
pdu_len = encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL);
#if PRINT_ENABLED
@@ -105,8 +97,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[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
@@ -117,8 +109,9 @@ void handler_device_communication_control(uint8_t * service_request,
#endif
}
}
bytes_sent = datalink_send_pdu(src, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
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
if (bytes_sent <= 0)
fprintf(stderr, "DeviceCommunicationControl: "
+8 -1
View File
@@ -44,12 +44,19 @@ void handler_i_am_add(uint8_t * service_request,
(void) service_len;
len = iam_decode_service_request(service_request,
&device_id, &max_apdu, &segmentation, &vendor_id);
#if PRINT_ENABLED
fprintf(stderr, "Received I-Am Request");
#endif
if (len != -1) {
#if PRINT_ENABLED
fprintf(stderr, " from %u!\n", device_id);
#endif
address_add(device_id, max_apdu, src);
} else
} else {
#if PRINT_ENABLED
fprintf(stderr, "!\n");
#endif
}
return;
}
+6 -1
View File
@@ -43,13 +43,18 @@ void handler_i_have(uint8_t * service_request,
len = ihave_decode_service_request(service_request,
service_len, &data);
if (len != -1) {
#if PRINT_ENABLED
fprintf(stderr, "I-Have: %s %d from %s %u!\r\n",
bactext_object_type_name(data.object_id.type),
data.object_id.instance,
bactext_object_type_name(data.device_id.type),
data.device_id.instance);
} else
#endif
} else {
#if PRINT_ENABLED
fprintf(stderr, "I-Have: received, but unable to decode!\n");
#endif
}
return;
}
+11 -15
View File
@@ -49,7 +49,7 @@ void handler_reinitialize_device(uint8_t * service_request,
BACNET_CHARACTER_STRING their_password;
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS my_address;
BACNET_NPDU_DATA npdu_data;
int bytes_sent = 0;
/* decode the service request only */
@@ -63,21 +63,16 @@ void handler_reinitialize_device(uint8_t * service_request,
else
fprintf(stderr, "ReinitializeDevice: Unable to decode request!\n");
#endif
/* prepare a reply */
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* bad decoding or something we didn't understand - send an abort */
if (len == -1) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
if (len < 0) {
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
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[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
#if PRINT_ENABLED
@@ -85,7 +80,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[pdu_len],
pdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION);
#if PRINT_ENABLED
fprintf(stderr,
@@ -94,7 +89,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[pdu_len],
pdu_len = encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE);
#if PRINT_ENABLED
@@ -105,8 +100,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[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
ERROR_CLASS_SERVICES, ERROR_CODE_PASSWORD_FAILURE);
@@ -116,8 +111,9 @@ void handler_reinitialize_device(uint8_t * service_request,
#endif
}
}
bytes_sent = datalink_send_pdu(src, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
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
if (bytes_sent <= 0)
fprintf(stderr, "ReinitializeDevice: Failed to send PDU (%s)!\n",
+35 -41
View File
@@ -58,7 +58,7 @@ void handler_read_property(uint8_t * service_request,
BACNET_READ_PROPERTY_DATA data;
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS my_address;
BACNET_NPDU_DATA npdu_data;
bool send = false;
bool error = false;
int bytes_sent = 0;
@@ -70,21 +70,16 @@ void handler_read_property(uint8_t * service_request,
if (len <= 0)
fprintf(stderr, "Unable to decode Read-Property Request!\n");
#endif
/* prepare a reply */
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* bad decoding - send an abort */
if (len == -1) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
if (len < 0) {
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, ABORT_REASON_OTHER);
#if PRINT_ENABLED
fprintf(stderr, "Sending Abort!\n");
#endif
send = true;
} else if (service_data->segmented_message) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
#if PRINT_ENABLED
@@ -104,9 +99,8 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len = rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Read Property Ack for Device!\n");
@@ -128,9 +122,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "Sending Read Property Ack for AI!\n");
#endif
@@ -151,9 +145,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "Sending Read Property Ack for BI!\n");
#endif
@@ -174,9 +168,8 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len = rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "Sending Read Property Ack for BO!\n");
#endif
@@ -197,9 +190,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "Sending Read Property Ack for BV!\n");
#endif
@@ -220,9 +213,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "Sending Read Property Ack for AO!\n");
#endif
@@ -243,9 +236,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr, "Sending Read Property Ack for AV!\n");
#endif
@@ -266,9 +259,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Read Property Ack for LSP!\n");
@@ -290,9 +283,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Read Property Ack for MSO!\n");
@@ -315,9 +308,9 @@ 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
[pdu_len], service_data->invoke_id, &data);
pdu_len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Read Property Ack for File!\n");
@@ -335,7 +328,7 @@ void handler_read_property(uint8_t * service_request,
}
}
if (error) {
pdu_len += bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
@@ -344,7 +337,8 @@ void handler_read_property(uint8_t * service_request,
send = true;
}
if (send) {
bytes_sent = datalink_send_pdu(src, /* destination address */
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 */
#if PRINT_ENABLED
if (bytes_sent <= 0)
+87 -47
View File
@@ -56,7 +56,7 @@ void handler_write_property(uint8_t * service_request,
BACNET_WRITE_PROPERTY_DATA wp_data;
int len = 0;
int pdu_len = 0;
BACNET_ADDRESS my_address;
BACNET_NPDU_DATA npdu_data;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
int bytes_sent = 0;
@@ -64,6 +64,7 @@ void handler_write_property(uint8_t * service_request,
/* decode the service request only */
len = wp_decode_service_request(service_request,
service_len, &wp_data);
#if PRINT_ENABLED
fprintf(stderr, "Received Write-Property Request!\n");
if (len > 0)
fprintf(stderr, "type=%u instance=%u property=%u index=%d\n",
@@ -72,192 +73,231 @@ void handler_write_property(uint8_t * service_request,
wp_data.object_property, wp_data.array_index);
else
fprintf(stderr, "Unable to decode Write-Property Request!\n");
/* prepare a reply */
datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], src, &my_address, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
#endif
/* bad decoding or something we didn't understand - send an abort */
if (len == -1) {
pdu_len += abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
if (len <= 0) {
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
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[pdu_len],
pdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED);
#if PRINT_ENABLED
fprintf(stderr, "Sending Abort!\n");
#endif
} else {
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[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for Device!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Error for Device!\n");
#endif
}
break;
case OBJECT_ANALOG_INPUT:
case OBJECT_BINARY_INPUT:
error_class = ERROR_CLASS_PROPERTY;
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error!\n");
#endif
break;
case OBJECT_BINARY_OUTPUT:
if (Binary_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
pdu_len +=
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for BO!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for BO!\n");
#endif
}
break;
case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property(&wp_data, &error_class,
&error_code)) {
pdu_len +=
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for BV!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for BV!\n");
#endif
}
break;
case OBJECT_ANALOG_OUTPUT:
if (Analog_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
pdu_len +=
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for AO!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for AO!\n");
#endif
}
break;
case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property(&wp_data, &error_class,
&error_code)) {
pdu_len +=
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for AV!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for AV!\n");
#endif
}
break;
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[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for LSP!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for LSP!\n");
#endif
}
break;
case OBJECT_MULTI_STATE_OUTPUT:
if (Multistate_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
pdu_len +=
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for MSO!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for MSO!\n");
#endif
}
break;
#if BACFILE
case OBJECT_FILE:
if (bacfile_write_property(&wp_data, &error_class,
&error_code)) {
pdu_len +=
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
encode_simple_ack(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"Sending Write Property Simple Ack for File!\n");
#endif
} else {
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Write Access Error for File!\n");
#endif
}
break;
#endif
default:
pdu_len +=
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "Sending Unknown Object Error!\n");
#endif
break;
}
}
bytes_sent = datalink_send_pdu(src, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
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
if (bytes_sent <= 0)
fprintf(stderr, "Failed to send PDU (%s)!\n", strerror(errno));
#endif
return;
}
+9 -10
View File
@@ -38,26 +38,25 @@ void handler_unrecognized_service(uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * dest, BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_ADDRESS src;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
(void) service_request;
(void) service_len;
datalink_get_my_address(&src);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], dest, &src, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* encode the APDU portion of the packet */
pdu_len += reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = reject_encode_apdu(&Handler_Transmit_Buffer[0],
service_data->invoke_id, REJECT_REASON_UNRECOGNIZED_SERVICE);
bytes_sent = datalink_send_pdu(dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
/* encode the NPDU portion of the packet */
npdu_encode_confirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
/* send the data */
bytes_sent = datalink_send_pdu(dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent > 0)
fprintf(stderr, "Sent Reject!\n");
else
fprintf(stderr, "Failed to Send Reject (%s)!\n", strerror(errno));
#endif
}
+99
View File
@@ -0,0 +1,99 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include "config.h"
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "address.h"
#include "tsm.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
#include "arf.h"
/* some demo stuff needed */
#include "handlers.h"
#include "txbuf.h"
uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, unsigned requestedOctetCount)
{
BACNET_ADDRESS dest;
BACNET_NPDU_DATA npdu_data;
unsigned max_apdu = 0;
uint8_t invoke_id = 0;
bool status = false;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_ATOMIC_READ_FILE_DATA data;
/* is the device bound? */
status = address_get_by_device(device_id, &max_apdu, &dest);
/* is there a tsm available? */
if (status)
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* load the data for the encoding */
data.object_type = OBJECT_FILE;
data.object_instance = file_instance;
data.access = FILE_STREAM_ACCESS;
data.type.stream.fileStartPosition = fileStartPosition;
data.type.stream.requestedOctetCount = requestedOctetCount;
pdu_len = arf_encode_apdu(&Handler_Transmit_Buffer[0],
invoke_id, &data);
/* 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 = datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to Send AtomicReadFile Request (%s)!\n",
strerror(errno));
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send AtomicReadFile Request "
"(payload exceeds destination maximum APDU)!\n");
#endif
}
}
return invoke_id;
}
+111
View File
@@ -0,0 +1,111 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include "config.h"
#include "config.h"
#include "txbuf.h"
#include "bacdef.h"
#include "bacdcode.h"
#include "address.h"
#include "tsm.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "datalink.h"
#include "awf.h"
/* some demo stuff needed */
#include "handlers.h"
#include "txbuf.h"
uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, BACNET_OCTET_STRING * fileData)
{
BACNET_ADDRESS dest;
BACNET_NPDU_DATA npdu_data;
unsigned max_apdu = 0;
uint8_t invoke_id = 0;
bool status = false;
int pdu_len = 0;
int bytes_sent = 0;
BACNET_ATOMIC_WRITE_FILE_DATA data;
/* is the device bound? */
status = address_get_by_device(device_id, &max_apdu, &dest);
/* is there a tsm available? */
if (status)
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* load the data for the encoding */
data.object_type = OBJECT_FILE;
data.object_instance = file_instance;
data.access = FILE_STREAM_ACCESS;
data.type.stream.fileStartPosition = fileStartPosition;
status = octetstring_copy(&data.fileData, fileData);
if (status) {
pdu_len = awf_encode_apdu(&Handler_Transmit_Buffer[0],
invoke_id, &data);
/* 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 = datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to Send AtomicWriteFile Request (%s)!\n",
strerror(errno));
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds destination maximum APDU [%u])!\n",
pdu_len, max_apdu);
#endif
}
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds octet string capacity)!\n",
pdu_len);
#endif
}
}
return invoke_id;
}
+15 -12
View File
@@ -45,13 +45,13 @@ 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 pdu_len = 0;
int bytes_sent = 0;
BACNET_CHARACTER_STRING password_string;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return 0;
@@ -60,16 +60,11 @@ uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t t
status = address_get_by_device(device_id, &max_apdu, &dest);
/* is there a tsm available? */
if (status)
status = tsm_transaction_available();
if (status) {
datalink_get_my_address(&my_address);
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, &my_address, true, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* load the data for the encoding */
characterstring_init_ansi(&password_string, password);
pdu_len += dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = dcc_encode_apdu(&Handler_Transmit_Buffer[0],
invoke_id,
timeDuration, state, password ? &password_string : NULL);
/* will it fit in the sender?
@@ -78,18 +73,26 @@ uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t t
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, &Handler_Transmit_Buffer[0], pdu_len);
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
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 DeviceCommunicationControl Request (%s)!\n",
strerror(errno));
} else
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr,
"Failed to Send DeviceCommunicationControl Request "
"(exceeds destination maximum APDU)!\n");
#endif
}
}
return invoke_id;
+6 -5
View File
@@ -51,26 +51,27 @@ void Send_I_Have(uint32_t device_id,
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_I_HAVE_DATA data;
BACNET_NPDU_DATA npdu_data;
/* if we are forbidden to send, don't send! */
if (!dcc_communication_enabled())
return;
/* Who-Has is a global broadcast */
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, NULL, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* 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[pdu_len], &data);
pdu_len = ihave_encode_apdu(&Handler_Transmit_Buffer[0], &data);
/* send the data */
bytes_sent = datalink_send_pdu(&dest, /* destination address */
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 */
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n",
strerror(errno));
#endif
}
+15 -12
View File
@@ -46,13 +46,13 @@ 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 pdu_len = 0;
int bytes_sent = 0;
BACNET_CHARACTER_STRING password_string;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return 0;
@@ -61,16 +61,11 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
status = address_get_by_device(device_id, &max_apdu, &dest);
/* is there a tsm available? */
if (status)
status = tsm_transaction_available();
if (status) {
datalink_get_my_address(&my_address);
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, &my_address, true, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* load the data for the encoding */
characterstring_init_ansi(&password_string, password);
pdu_len += rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = rd_encode_apdu(&Handler_Transmit_Buffer[0],
invoke_id, state, password ? &password_string : NULL);
/* will it fit in the sender?
note: if there is a bottleneck router in between
@@ -78,17 +73,25 @@ uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
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, &Handler_Transmit_Buffer[0], pdu_len);
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
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 ReinitializeDevice Request (%s)!\n",
strerror(errno));
} else
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send ReinitializeDevice Request "
"(exceeds destination maximum APDU)!\n");
#endif
}
}
return invoke_id;
+15 -12
View File
@@ -49,13 +49,13 @@ 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 pdu_len = 0;
int bytes_sent = 0;
BACNET_READ_PROPERTY_DATA data;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return 0;
@@ -64,19 +64,14 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
status = address_get_by_device(device_id, &max_apdu, &dest);
/* is there a tsm available? */
if (status)
status = tsm_transaction_available();
if (status) {
datalink_get_my_address(&my_address);
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, &my_address, true, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* load the data for the encoding */
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[pdu_len],
pdu_len = rp_encode_apdu(&Handler_Transmit_Buffer[0],
invoke_id, &data);
/* will it fit in the sender?
note: if there is a bottleneck router in between
@@ -84,17 +79,25 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
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, &Handler_Transmit_Buffer[0], pdu_len);
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
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 ReadProperty Request (%s)!\n",
strerror(errno));
} else
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send ReadProperty Request "
"(exceeds destination maximum APDU)!\n");
#endif
}
}
return invoke_id;
+12 -11
View File
@@ -47,25 +47,26 @@ void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime)
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return;
/* we could use unicast or broadcast */
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, NULL, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* encode the APDU portion of the packet */
pdu_len += timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = timesync_encode_apdu(&Handler_Transmit_Buffer[0],
bdate, btime);
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
/* send it out the datalink */
bytes_sent = datalink_send_pdu(&dest,
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 Time-Synchronization Request (%s)!\n",
strerror(errno));
#endif
}
void Send_TimeSyncUTC(BACNET_DATE * bdate, BACNET_TIME * btime)
@@ -73,23 +74,23 @@ void Send_TimeSyncUTC(BACNET_DATE * bdate, BACNET_TIME * btime)
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return;
/* we could use unicast or broadcast */
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, NULL, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* encode the APDU portion of the packet */
pdu_len += timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[0],
bdate, btime);
/* send it out the datalink */
bytes_sent = datalink_send_pdu(&dest,
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
if (bytes_sent <= 0)
fprintf(stderr,
"Failed to Send UTC-Time-Synchronization Request (%s)!\n",
strerror(errno));
#endif
}
+14 -14
View File
@@ -50,28 +50,29 @@ void Send_WhoHas_Name(int32_t low_limit,
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_WHO_HAS_DATA data;
BACNET_NPDU_DATA npdu_data;
/* if we are forbidden to send, don't send! */
if (!dcc_communication_enabled())
return;
/* Who-Has is a global broadcast */
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, NULL, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* 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[pdu_len],
pdu_len = whohas_encode_apdu(&Handler_Transmit_Buffer[0],
&data);
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
/* send the data */
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&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 Who-Has Request (%s)!\n",
strerror(errno));
#endif
}
/* find a specific device, or use -1 for limit if you want unlimited */
@@ -83,27 +84,26 @@ void Send_WhoHas_Object(int32_t low_limit,
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_WHO_HAS_DATA data;
BACNET_NPDU_DATA npdu_data;
/* if we are forbidden to send, don't send! */
if (!dcc_communication_enabled())
return;
/* Who-Has is a global broadcast */
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, NULL, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* encode the APDU portion of the packet */
data.low_limit = low_limit;
data.high_limit = high_limit;
data.object_name = false;
data.object.identifier.type = object_type;
data.object.identifier.instance = object_instance;
pdu_len += whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
&data);
/* send the data */
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
pdu_len = whohas_encode_apdu(&Handler_Transmit_Buffer[0], &data);
npdu_encode_unconfirmed_apdu(&npdu_data, MESSAGE_PRIORITY_NORMAL);
bytes_sent = datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n",
strerror(errno));
#endif
}
+7 -9
View File
@@ -48,24 +48,22 @@ void Send_WhoIs(int32_t low_limit, int32_t high_limit)
int pdu_len = 0;
BACNET_ADDRESS dest;
int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return;
/* Who-Is is a global broadcast */
datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, NULL, false, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
/* encode the APDU portion of the packet */
pdu_len += whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = whois_encode_apdu(&Handler_Transmit_Buffer[0],
low_limit, high_limit);
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of 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
if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Who-Is Request (%s)!\n",
strerror(errno));
#endif
}
+15 -12
View File
@@ -51,13 +51,13 @@ 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 pdu_len = 0;
int bytes_sent = 0;
BACNET_WRITE_PROPERTY_DATA data;
BACNET_NPDU_DATA npdu_data;
if (!dcc_communication_enabled())
return 0;
@@ -66,13 +66,8 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
status = address_get_by_device(device_id, &max_apdu, &dest);
/* is there a tsm available? */
if (status)
status = tsm_transaction_available();
if (status) {
datalink_get_my_address(&my_address);
pdu_len = npdu_encode_apdu(&Handler_Transmit_Buffer[0], &dest, &my_address, true, /* true for confirmed messages */
MESSAGE_PRIORITY_NORMAL);
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
/* load the data for the encoding */
data.object_type = object_type;
data.object_instance = object_instance;
@@ -80,7 +75,7 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
data.array_index = array_index;
bacapp_copy(&data.value, object_value);
data.priority = priority;
pdu_len += wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
pdu_len = wp_encode_apdu(&Handler_Transmit_Buffer[0],
invoke_id, &data);
/* will it fit in the sender?
note: if there is a bottleneck router in between
@@ -88,17 +83,25 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
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, &Handler_Transmit_Buffer[0], pdu_len);
bytes_sent = datalink_send_pdu(&dest, /* destination address */
&Handler_Transmit_Buffer[0], pdu_len); /* number of bytes of data */
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
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 WriteProperty Request (%s)!\n",
strerror(errno));
} else
#endif
} else {
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send WriteProperty Request "
"(exceeds destination maximum APDU)!\n");
#endif
}
}
return invoke_id;