Run clang-format and enable CI check for it (#755)

* pre-commit: Update and enable clang-format check

There is newer version from clang-format so use that. We do not yet want
18 as that is little bit too new.

* Format some thing by hand which clang-format "breaks"

Clang-format will format some things little bit off in some cases.
Format some things by hand so we get cleaner end result.

* Run clang-format with

```
pre-commit run --all-files clang-format
```

We have already in previously checked places where clang-format does not
make good format and ignored those (hopefully most of the things).

---------

Co-authored-by: Kari Argillander <kari.argillander@fidelix.com>
This commit is contained in:
Kari Argillander
2024-08-30 19:20:58 +03:00
committed by GitHub
parent 622a9e609e
commit f806c5829b
547 changed files with 18286 additions and 16575 deletions
+4 -5
View File
@@ -47,11 +47,10 @@ repos:
args: ["--whitespaces-count", "2"] args: ["--whitespaces-count", "2"]
files: '.*\.(yaml|yml|html|htm)|Dockerfile$' files: '.*\.(yaml|yml|html|htm)|Dockerfile$'
# We will enable this in future. - repo: https://github.com/pre-commit/mirrors-clang-format
# - repo: https://github.com/pre-commit/mirrors-clang-format rev: 05241dc3def184dba136e62d54ff57f1c8a497a9 # v17.0.6
# rev: 3b03191b6a60cba0fc25c2dc2e30ea4854d897eb # v17.0.5 hooks:
# hooks: - id: clang-format
# - id: clang-format
# We might enable this in future. # We might enable this in future.
# - repo: https://github.com/pre-commit/mirrors-prettier # - repo: https://github.com/pre-commit/mirrors-prettier
+22 -19
View File
@@ -46,8 +46,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -85,31 +85,33 @@ static void print_help(const char *filename)
{ {
printf("Send BACnet Abort message to the network.\n"); printf("Send BACnet Abort message to the network.\n");
printf("--mac A\n" printf("--mac A\n"
"Optional destination BACnet mac address." "Optional destination BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf(
"--dnet N\n"
"Optional destination BACnet network number N for directed requests.\n" "Optional destination BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"Optional BACnet mac address on the destination BACnet network " "Optional BACnet mac address on the destination BACnet network "
"number.\n" "number.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("abort-reason:\n" printf("abort-reason:\n"
" number from 0 to 65535\n" " number from 0 to 65535\n"
"invoke-id:\n" "invoke-id:\n"
" number from 1 to 255\n" " number from 1 to 255\n"
"server:\n" "server:\n"
" 0=false, 1=true\n"); " 0=false, 1=true\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"Example:\n"
"%s 3 2 1\n", "%s 3 2 1\n",
filename); filename);
} }
@@ -214,7 +216,8 @@ int main(int argc, char *argv[])
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
/* send the request */ /* send the request */
Send_Abort_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID, Send_Abort_To_Network(
&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
Target_Abort_Reason, Target_Server); Target_Abort_Reason, Target_Server);
return 0; return 0;
+38 -31
View File
@@ -51,14 +51,16 @@ static bool Error_Detected = false;
* @param error_class [in] the error class * @param error_class [in] the error class
* @param error_code [in] the error code * @param error_code [in] the error code
*/ */
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -90,12 +92,13 @@ static void MyAbortHandler(
* @param invoke_id [in] the invokeID from the rejected message * @param invoke_id [in] the invokeID from the rejected message
* @param reject_reason [in] the reason for the rejection * @param reject_reason [in] the reason for the rejection
*/ */
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -106,8 +109,8 @@ static void MyRejectHandler(
* @param src [in] BACNET_ADDRESS of the source of the message * @param src [in] BACNET_ADDRESS of the source of the message
* @param invoke_id [in] the invokeID from the rejected message * @param invoke_id [in] the invokeID from the rejected message
*/ */
static void MyWritePropertySimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -143,9 +146,10 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-id process-id\n" printf(
" event-object-type event-object-instance event-state-acked\n" "Usage: %s device-id process-id\n"
" event-time-stamp ack-source-name ack-time-stamp\n", " event-object-type event-object-instance event-state-acked\n"
" event-time-stamp ack-source-name ack-time-stamp\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -154,51 +158,53 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Send BACnet AcknowledgedAlarm, message to a device.\n"); printf("Send BACnet AcknowledgedAlarm, message to a device.\n");
printf("device-id:\n" printf(
"device-id:\n"
"BACnet Device Object Instance number that you are trying to\n" "BACnet Device Object Instance number that you are trying to\n"
"communicate to. This number will be used to try and bind with\n" "communicate to. This number will be used to try and bind with\n"
"the device using Who-Is and I-Am services. For example, if you were\n" "the device using Who-Is and I-Am services. For example, if you were\n"
"notifying Device Object 123, the device-instance would be 123.\n"); "notifying Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf("process-id:\n" printf("process-id:\n"
"Process Identifier in the receiving device for which the\n" "Process Identifier in the receiving device for which the\n"
"notification is intended.\n"); "notification is intended.\n");
printf("\n"); printf("\n");
printf("event-object-type:\n" printf(
"event-object-type:\n"
"The object type is defined either as the object-type name string\n" "The object type is defined either as the object-type name string\n"
"as defined in the BACnet specification, or as the integer value.\n"); "as defined in the BACnet specification, or as the integer value.\n");
printf("\n"); printf("\n");
printf("event-object-instance:\n" printf("event-object-instance:\n"
"The object instance number of the event object.\n"); "The object instance number of the event object.\n");
printf("\n"); printf("\n");
printf("event-state-acked:\n" printf("event-state-acked:\n"
"The event-state that for this alarm acknowledge.\n"); "The event-state that for this alarm acknowledge.\n");
printf("\n"); printf("\n");
printf("event-time-stamp:\n" printf("event-time-stamp:\n"
"The time-stamp of the event.\n"); "The time-stamp of the event.\n");
printf("\n"); printf("\n");
printf("ack-source-name\n" printf("ack-source-name\n"
"The source name of the alarm acknowledge.\n"); "The source name of the alarm acknowledge.\n");
printf("\n"); printf("\n");
printf("ack-time-stamp\n" printf("ack-time-stamp\n"
"The time-stamp of the alarm acknowledge.\n"); "The time-stamp of the alarm acknowledge.\n");
printf("\n"); printf("\n");
printf("--mac A\n" printf("--mac A\n"
"Optional BACnet mac address." "Optional BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf("--dnet N\n"
"Optional BACnet network number N for directed requests.\n" "Optional BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"Optional BACnet mac address on the destination BACnet network.\n" "Optional BACnet mac address on the destination BACnet network.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
(void)filename; (void)filename;
} }
@@ -345,7 +351,8 @@ int main(int argc, char *argv[])
dest.len = 0; dest.len = 0;
} }
address_add(Target_Device_Object_Instance, MAX_APDU, &dest); address_add(Target_Device_Object_Instance, MAX_APDU, &dest);
printf("Added Device %u to address cache\n", printf(
"Added Device %u to address cache\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
/* setup my info */ /* setup my info */
+37 -25
View File
@@ -57,7 +57,8 @@ static bool Error_Detected = false;
/* Used for verbose */ /* Used for verbose */
static bool Verbose = false; static bool Verbose = false;
static void MyAddListElementErrorHandler(BACNET_ADDRESS *src, static void MyAddListElementErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
uint8_t service_choice, uint8_t service_choice,
uint8_t *service_request, uint8_t *service_request,
@@ -72,7 +73,8 @@ static void MyAddListElementErrorHandler(BACNET_ADDRESS *src,
len = list_element_error_ack_decode( len = list_element_error_ack_decode(
service_request, service_len, &list_element); service_request, service_len, &list_element);
if (len > 0) { if (len > 0) {
printf("BACnet Error: %s: %s [first-failed=%u]\n", printf(
"BACnet Error: %s: %s [first-failed=%u]\n",
bactext_error_class_name((int)list_element.error_class), bactext_error_class_name((int)list_element.error_class),
bactext_error_code_name((int)list_element.error_code), bactext_error_code_name((int)list_element.error_code),
(unsigned)list_element.first_failed_element_number); (unsigned)list_element.first_failed_element_number);
@@ -81,8 +83,8 @@ static void MyAddListElementErrorHandler(BACNET_ADDRESS *src,
} }
} }
static void MyAddListElementSimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyAddListElementSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -102,13 +104,14 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -139,8 +142,9 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance " printf(
"property array-index tag value\n", "Usage: %s device-instance object-type object-instance "
"property array-index tag value\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help][--verbose]\n"); printf(" [--version][--help][--verbose]\n");
@@ -211,10 +215,11 @@ static void print_help(const char *filename)
"the Any property type in the schedule object and the Present Value\n" "the Any property type in the schedule object and the Present Value\n"
"accepting REAL, BOOLEAN, NULL, etc.\n"); "accepting REAL, BOOLEAN, NULL, etc.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"If you want to AddListElement to the Recipient-List property in\n" "Example:\n"
"Notification Class 1 of Device 123, send the following command:\n" "If you want to AddListElement to the Recipient-List property in\n"
"%s 123 15 1 102 -1 4 100\n", "Notification Class 1 of Device 123, send the following command:\n"
"%s 123 15 1 102 -1 4 100\n",
filename); filename);
} }
@@ -287,8 +292,8 @@ int main(int argc, char *argv[])
if (target_args == 0) { if (target_args == 0) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
object_instance, BACNET_MAX_INSTANCE); object_instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -305,8 +310,8 @@ int main(int argc, char *argv[])
} else if (target_args == 2) { } else if (target_args == 2) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -330,7 +335,8 @@ int main(int argc, char *argv[])
property_array_index = strtol(argv[argi], NULL, 0); property_array_index = strtol(argv[argi], NULL, 0);
Target_Object_Array_Index = property_array_index; Target_Object_Array_Index = property_array_index;
if (Verbose) { if (Verbose) {
printf("Array_Index=%i=%s\n", property_array_index, printf(
"Array_Index=%i=%s\n", property_array_index,
argv[argi]); argv[argi]);
} }
target_args++; target_args++;
@@ -357,14 +363,16 @@ int main(int argc, char *argv[])
} else if (tag_value_arg == 1) { } else if (tag_value_arg == 1) {
value_string = argv[argi]; value_string = argv[argi];
if (Verbose) { if (Verbose) {
printf("tag=%ld value=%s\n", property_tag, value_string); printf(
"tag=%ld value=%s\n", property_tag, value_string);
} }
if (property_tag < 0) { if (property_tag < 0) {
/* find the application tag for internal properties */ /* find the application tag for internal properties */
property_tag = bacapp_known_property_tag( property_tag = bacapp_known_property_tag(
Target_Object_Type, Target_Object_Property); Target_Object_Type, Target_Object_Property);
} else if (property_tag >= MAX_BACNET_APPLICATION_TAG) { } else if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, fprintf(
stderr,
"Error: tag=%ld - it must be less than %u\n", "Error: tag=%ld - it must be less than %u\n",
property_tag, MAX_BACNET_APPLICATION_TAG); property_tag, MAX_BACNET_APPLICATION_TAG);
return 1; return 1;
@@ -374,13 +382,15 @@ int main(int argc, char *argv[])
status = bacapp_parse_application_data( status = bacapp_parse_application_data(
property_tag, value_string, application_value); property_tag, value_string, application_value);
if (!status) { if (!status) {
fprintf(stderr, fprintf(
stderr,
"Error: unable to parse the tag value\n"); "Error: unable to parse the tag value\n");
return 1; return 1;
} }
} else { } else {
/* FIXME: show the expected entry format for the tag */ /* FIXME: show the expected entry format for the tag */
fprintf(stderr, fprintf(
stderr,
"Error: unable to parse the known property" "Error: unable to parse the known property"
" \"%s\"\r\n", " \"%s\"\r\n",
value_string); value_string);
@@ -422,7 +432,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance, &max_apdu, &Target_Address); Target_Device_Object_Instance, &max_apdu, &Target_Address);
if (found) { if (found) {
if (Verbose) { if (Verbose) {
printf("Found Device %u in address_cache.\n", printf(
"Found Device %u in address_cache.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
} else { } else {
@@ -435,7 +446,8 @@ int main(int argc, char *argv[])
/* device is bound! */ /* device is bound! */
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
if (Verbose) { if (Verbose) {
printf("Sending AddListElement to Device %u.\n", printf(
"Sending AddListElement to Device %u.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
Request_Invoke_ID = Send_Add_List_Element_Request( Request_Invoke_ID = Send_Add_List_Element_Request(
@@ -465,7 +477,7 @@ int main(int argc, char *argv[])
mstimer_reset(&maintenance_timer); mstimer_reset(&maintenance_timer);
tsm_timer_milliseconds(mstimer_interval(&maintenance_timer)); tsm_timer_milliseconds(mstimer_interval(&maintenance_timer));
datalink_maintenance_timer( datalink_maintenance_timer(
mstimer_interval(&maintenance_timer)/1000L); mstimer_interval(&maintenance_timer) / 1000L);
} }
if (mstimer_expired(&apdu_timer)) { if (mstimer_expired(&apdu_timer)) {
printf("\rError: APDU Timeout!\n"); printf("\rError: APDU Timeout!\n");
+29 -19
View File
@@ -57,13 +57,15 @@ static bool BACnet_Debug_Enabled;
/** /**
* @brief Print error messages * @brief Print error messages
*/ */
static void MyPrintHandler(const char *hex_ascii, static void MyPrintHandler(
const char *hex_ascii,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
debug_printf("[{\n"); debug_printf("[{\n");
debug_printf(" \"%s\": {\n" debug_printf(
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"", " \"%s\": {\n"
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"",
hex_ascii, bactext_error_class_name((int)error_class), hex_ascii, bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
debug_printf("\n }\n}]\n"); debug_printf("\n }\n}]\n");
@@ -78,7 +80,8 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
MyPrintHandler(APDU_Hex_ASCII, ERROR_CLASS_SERVICES, MyPrintHandler(
APDU_Hex_ASCII, ERROR_CLASS_SERVICES,
abort_convert_to_error_code(abort_reason)); abort_convert_to_error_code(abort_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -87,12 +90,13 @@ static void MyAbortHandler(
/** /**
* @brief Handler for reject messages * @brief Handler for reject messages
*/ */
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
MyPrintHandler(APDU_Hex_ASCII, ERROR_CLASS_SERVICES, MyPrintHandler(
APDU_Hex_ASCII, ERROR_CLASS_SERVICES,
reject_convert_to_error_code(reject_reason)); reject_convert_to_error_code(reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -178,17 +182,21 @@ static void print_help(const char *filename)
"Default delay is 100ms.\n"); "Default delay is 100ms.\n");
printf("\n"); printf("\n");
printf("Example:\n"); printf("Example:\n");
printf("Send an APDU to DNET 123:\n" printf(
"%s 1 --dnet 123 0123456789ABCDEF\n", "Send an APDU to DNET 123:\n"
"%s 1 --dnet 123 0123456789ABCDEF\n",
filename); filename);
printf("Send an APDU to MAC 10.0.0.1 DNET 123 DADR 05h:\n" printf(
"%s 1 --mac 10.0.0.1 --dnet 123 --dadr 05 0123456789ABCDEF\n", "Send an APDU to MAC 10.0.0.1 DNET 123 DADR 05h:\n"
"%s 1 --mac 10.0.0.1 --dnet 123 --dadr 05 0123456789ABCDEF\n",
filename); filename);
printf("Send APDU to MAC 10.1.2.3:47808:\n" printf(
"%s 1 --mac 10.1.2.3:47808 0123456789ABCDEF\n", "Send APDU to MAC 10.1.2.3:47808:\n"
"%s 1 --mac 10.1.2.3:47808 0123456789ABCDEF\n",
filename); filename);
printf("Send an APDU to Device 1:\n" printf(
"%s 1 0123456789ABCDEF\n", "Send an APDU to Device 1:\n"
"%s 1 0123456789ABCDEF\n",
filename); filename);
} }
@@ -228,8 +236,8 @@ static void Send_APDU_To_Network(
* @param ascii_hex [in] The string of ASCII hex. * @param ascii_hex [in] The string of ASCII hex.
* @return number of bytes converted, or 0 if error. * @return number of bytes converted, or 0 if error.
*/ */
static size_t ascii_hex_to_binary( static size_t
uint8_t *buffer, size_t buffer_size, const char *ascii_hex) ascii_hex_to_binary(uint8_t *buffer, size_t buffer_size, const char *ascii_hex)
{ {
unsigned index = 0; /* offset into buffer */ unsigned index = 0; /* offset into buffer */
uint8_t value = 0; uint8_t value = 0;
@@ -401,7 +409,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance, &max_apdu, &Target_Address); Target_Device_Object_Instance, &max_apdu, &Target_Address);
if (found) { if (found) {
if (BACnet_Debug_Enabled) { if (BACnet_Debug_Enabled) {
debug_printf("Found Device %u in address_cache.\n", debug_printf(
"Found Device %u in address_cache.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
} else { } else {
@@ -432,7 +441,8 @@ int main(int argc, char *argv[])
if (found) { if (found) {
/* device is bound! */ /* device is bound! */
if (BACnet_Debug_Enabled) { if (BACnet_Debug_Enabled) {
printf("Sending APDU to Device %u.\n", printf(
"Sending APDU to Device %u.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
if (mstimer_expired(&apdu_timer)) { if (mstimer_expired(&apdu_timer)) {
+8 -4
View File
@@ -52,8 +52,9 @@ void blinkt_clear(void)
*/ */
void blinkt_set_pixel(uint8_t led, uint8_t r, uint8_t g, uint8_t b) void blinkt_set_pixel(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{ {
if (led >= BLINKT_NUM_LEDS) if (led >= BLINKT_NUM_LEDS) {
return; return;
}
Blinkt_LED[led] = blinkt_rgbb(r, g, b, Blinkt_LED[led] & 0x1F); Blinkt_LED[led] = blinkt_rgbb(r, g, b, Blinkt_LED[led] & 0x1F);
} }
@@ -65,8 +66,9 @@ void blinkt_set_pixel(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
*/ */
void blinkt_set_pixel_brightness(uint8_t led, uint8_t brightness) void blinkt_set_pixel_brightness(uint8_t led, uint8_t brightness)
{ {
if (led >= BLINKT_NUM_LEDS) if (led >= BLINKT_NUM_LEDS) {
return; return;
}
Blinkt_LED[led] = (Blinkt_LED[led] & 0xFFFFFF00) | (brightness & 0x1F); Blinkt_LED[led] = (Blinkt_LED[led] & 0xFFFFFF00) | (brightness & 0x1F);
} }
@@ -78,8 +80,9 @@ void blinkt_set_pixel_brightness(uint8_t led, uint8_t brightness)
*/ */
void blinkt_set_pixel_uint32(uint8_t led, uint32_t color) void blinkt_set_pixel_uint32(uint8_t led, uint32_t color)
{ {
if (led >= BLINKT_NUM_LEDS) if (led >= BLINKT_NUM_LEDS) {
return; return;
}
Blinkt_LED[led] = color; Blinkt_LED[led] = color;
} }
@@ -206,8 +209,9 @@ void blinkt_test_task(void)
} }
blinkt_show(); blinkt_show();
test_y += 1; test_y += 1;
if (test_y > 254) if (test_y > 254) {
test_column++; test_column++;
}
test_column %= 3; test_column %= 3;
test_y %= 255; test_y %= 255;
} }
+227 -98
View File
@@ -48,76 +48,172 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
static object_functions_t *Object_Table; static object_functions_t *Object_Table;
static object_functions_t My_Object_Table[] = { static object_functions_t My_Object_Table[] = {
{ OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, { OBJECT_DEVICE,
Device_Count, Device_Index_To_Instance, NULL /* Init - don't init Device or it will recourse! */,
Device_Valid_Object_Instance_Number, Device_Object_Name, Device_Count,
Device_Read_Property_Local, Device_Write_Property_Local, Device_Index_To_Instance,
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, Device_Valid_Object_Instance_Number,
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, Device_Object_Name,
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */, Device_Read_Property_Local,
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */, Device_Write_Property_Local,
NULL /* Timer */ }, Device_Property_Lists,
DeviceGetRRInfo,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ },
#if (BACNET_PROTOCOL_REVISION >= 17) #if (BACNET_PROTOCOL_REVISION >= 17)
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, { OBJECT_NETWORK_PORT,
Network_Port_Index_To_Instance, Network_Port_Valid_Instance, Network_Port_Init,
Network_Port_Object_Name, Network_Port_Read_Property, Network_Port_Count,
Network_Port_Write_Property, Network_Port_Property_Lists, Network_Port_Index_To_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, Network_Port_Valid_Instance,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Network_Port_Object_Name,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Network_Port_Read_Property,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ }, Network_Port_Write_Property,
Network_Port_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ },
#endif #endif
{ OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count, { OBJECT_LOAD_CONTROL,
Load_Control_Index_To_Instance, Load_Control_Valid_Instance, Load_Control_Init,
Load_Control_Object_Name, Load_Control_Read_Property, Load_Control_Count,
Load_Control_Write_Property, Load_Control_Property_Lists, Load_Control_Index_To_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, Load_Control_Valid_Instance,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Load_Control_Object_Name,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Load_Control_Read_Property,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ }, Load_Control_Write_Property,
Load_Control_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ },
#if (BACNET_PROTOCOL_REVISION >= 14) #if (BACNET_PROTOCOL_REVISION >= 14)
{ OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count, { OBJECT_LIGHTING_OUTPUT,
Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance, Lighting_Output_Init,
Lighting_Output_Object_Name, Lighting_Output_Read_Property, Lighting_Output_Count,
Lighting_Output_Write_Property, Lighting_Output_Property_Lists, Lighting_Output_Index_To_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, Lighting_Output_Valid_Instance,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Lighting_Output_Object_Name,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Lighting_Output_Read_Property,
Lighting_Output_Create, Lighting_Output_Delete, Lighting_Output_Timer }, Lighting_Output_Write_Property,
{ OBJECT_CHANNEL, Channel_Init, Channel_Count, Channel_Index_To_Instance, Lighting_Output_Property_Lists,
Channel_Valid_Instance, Channel_Object_Name, Channel_Read_Property, NULL /* ReadRangeInfo */,
Channel_Write_Property, Channel_Property_Lists, NULL /* Iterator */,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* COV */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* COV Clear */,
Channel_Create, Channel_Delete, NULL /* Timer */ }, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
Lighting_Output_Create,
Lighting_Output_Delete,
Lighting_Output_Timer },
{ OBJECT_CHANNEL,
Channel_Init,
Channel_Count,
Channel_Index_To_Instance,
Channel_Valid_Instance,
Channel_Object_Name,
Channel_Read_Property,
Channel_Write_Property,
Channel_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
Channel_Create,
Channel_Delete,
NULL /* Timer */ },
#endif #endif
#if (BACNET_PROTOCOL_REVISION >= 24) #if (BACNET_PROTOCOL_REVISION >= 24)
{ OBJECT_COLOR, Color_Init, Color_Count, Color_Index_To_Instance, { OBJECT_COLOR,
Color_Valid_Instance, Color_Object_Name, Color_Read_Property, Color_Init,
Color_Write_Property, Color_Property_Lists, NULL /* ReadRangeInfo */, Color_Count,
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, Color_Index_To_Instance,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Color_Valid_Instance,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Color_Object_Name,
Color_Create, Color_Delete, Color_Timer }, Color_Read_Property,
{ OBJECT_COLOR_TEMPERATURE, Color_Temperature_Init, Color_Temperature_Count, Color_Write_Property,
Color_Temperature_Index_To_Instance, Color_Temperature_Valid_Instance, Color_Property_Lists,
Color_Temperature_Object_Name, Color_Temperature_Read_Property, NULL /* ReadRangeInfo */,
Color_Temperature_Write_Property, Color_Temperature_Property_Lists, NULL /* Iterator */,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, NULL /* Value_Lists */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* COV */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* COV Clear */,
Color_Temperature_Create, Color_Temperature_Delete, NULL /* Intrinsic Reporting */,
Color_Temperature_Timer }, NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
Color_Create,
Color_Delete,
Color_Timer },
{ OBJECT_COLOR_TEMPERATURE,
Color_Temperature_Init,
Color_Temperature_Count,
Color_Temperature_Index_To_Instance,
Color_Temperature_Valid_Instance,
Color_Temperature_Object_Name,
Color_Temperature_Read_Property,
Color_Temperature_Write_Property,
Color_Temperature_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
Color_Temperature_Create,
Color_Temperature_Delete,
Color_Temperature_Timer },
#endif #endif
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, { MAX_BACNET_OBJECT_TYPE,
NULL /* Index_To_Instance */, NULL /* Valid_Instance */, NULL /* Init */,
NULL /* Object_Name */, NULL /* Read_Property */, NULL /* Count */,
NULL /* Write_Property */, NULL /* Property_Lists */, NULL /* Index_To_Instance */,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, NULL /* Valid_Instance */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* Object_Name */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* Read_Property */,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ } NULL /* Write_Property */,
NULL /* Property_Lists */,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ }
}; };
/** Glue function to let the Device object, when called by a handler, /** Glue function to let the Device object, when called by a handler,
@@ -128,8 +224,8 @@ static object_functions_t My_Object_Table[] = {
* @return Pointer to the group of object helper functions that implement this * @return Pointer to the group of object helper functions that implement this
* type of Object. * type of Object.
*/ */
static struct object_functions *Device_Objects_Find_Functions( static struct object_functions *
BACNET_OBJECT_TYPE Object_Type) Device_Objects_Find_Functions(BACNET_OBJECT_TYPE Object_Type)
{ {
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
@@ -175,7 +271,8 @@ rr_info_function Device_Objects_RR_Info(BACNET_OBJECT_TYPE object_type)
* list, separately, the Required, Optional, and Proprietary object * list, separately, the Required, Optional, and Proprietary object
* properties with their counts. * properties with their counts.
*/ */
void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, void Device_Objects_Property_List(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
struct special_property_list_t *pPropertyList) struct special_property_list_t *pPropertyList)
{ {
@@ -193,8 +290,9 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
pObject = Device_Objects_Find_Functions(object_type); pObject = Device_Objects_Find_Functions(object_type);
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) { if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
pObject->Object_RPM_List(&pPropertyList->Required.pList, pObject->Object_RPM_List(
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList); &pPropertyList->Required.pList, &pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
} }
/* Fetch the counts if available otherwise zero them */ /* Fetch the counts if available otherwise zero them */
@@ -214,25 +312,47 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
} }
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, static const int Device_Properties_Required[] = {
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, PROP_OBJECT_IDENTIFIER,
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, PROP_OBJECT_NAME,
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, PROP_OBJECT_TYPE,
PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_SYSTEM_STATUS,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, PROP_VENDOR_NAME,
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, PROP_VENDOR_IDENTIFIER,
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, PROP_MODEL_NAME,
PROP_DATABASE_REVISION, -1 }; PROP_FIRMWARE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION,
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_REVISION,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_OBJECT_LIST,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_DEVICE_ADDRESS_BINDING,
PROP_DATABASE_REVISION,
-1
};
static const int Device_Properties_Optional[] = { static const int Device_Properties_Optional[] = {
#if defined(BACDL_MSTP) #if defined(BACDL_MSTP)
PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
#endif #endif
PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE, PROP_DESCRIPTION,
PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS, PROP_LOCAL_TIME,
PROP_UTC_OFFSET,
PROP_LOCAL_DATE,
PROP_DAYLIGHT_SAVINGS_STATUS,
PROP_LOCATION,
PROP_ACTIVE_COV_SUBSCRIPTIONS,
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_TIME_SYNCHRONIZATION_INTERVAL, PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, PROP_TIME_SYNCHRONIZATION_INTERVAL,
PROP_ALIGN_INTERVALS,
PROP_INTERVAL_OFFSET,
#endif #endif
-1 -1
}; };
@@ -803,7 +923,8 @@ int Device_Object_List_Element_Encode(
* Object. * Object.
* @return True on success or else False if not found. * @return True on success or else False if not found.
*/ */
bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1, bool Device_Valid_Object_Name(
BACNET_CHARACTER_STRING *object_name1,
BACNET_OBJECT_TYPE *object_type, BACNET_OBJECT_TYPE *object_type,
uint32_t *object_instance) uint32_t *object_instance)
{ {
@@ -822,7 +943,7 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
pObject = Device_Objects_Find_Functions(type); pObject = Device_Objects_Find_Functions(type);
if ((pObject != NULL) && (pObject->Object_Name != NULL) && if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
(pObject->Object_Name(instance, &object_name2) && (pObject->Object_Name(instance, &object_name2) &&
characterstring_same(object_name1, &object_name2))) { characterstring_same(object_name1, &object_name2))) {
found = true; found = true;
if (object_type) { if (object_type) {
*object_type = type; *object_type = type;
@@ -863,7 +984,8 @@ bool Device_Valid_Object_Id(
* @param object_name [out] The Object Name found for this child Object. * @param object_name [out] The Object Name found for this child Object.
* @return True on success or else False if not found. * @return True on success or else False if not found.
*/ */
bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, bool Device_Object_Name_Copy(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
@@ -1081,7 +1203,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
bitstring_init(&bit_string); bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */ /* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t)i, bitstring_set_bit(
&bit_string, (uint8_t)i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
} }
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
@@ -1108,9 +1231,9 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
break; break;
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
count = Device_Object_List_Count(); count = Device_Object_List_Count();
apdu_len = bacnet_array_encode(rpdata->object_instance, apdu_len = bacnet_array_encode(
rpdata->array_index, Device_Object_List_Element_Encode, count, rpdata->object_instance, rpdata->array_index,
apdu, apdu_max); Device_Object_List_Element_Encode, count, apdu, apdu_max);
if (apdu_len == BACNET_STATUS_ABORT) { if (apdu_len == BACNET_STATUS_ABORT) {
rpdata->error_code = rpdata->error_code =
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -1233,8 +1356,9 @@ static int Read_Property_Common(
} else if (rpdata->object_property == PROP_PROPERTY_LIST) { } else if (rpdata->object_property == PROP_PROPERTY_LIST) {
Device_Objects_Property_List( Device_Objects_Property_List(
rpdata->object_type, rpdata->object_instance, &property_list); rpdata->object_type, rpdata->object_instance, &property_list);
apdu_len = property_list_encode(rpdata, property_list.Required.pList, apdu_len = property_list_encode(
property_list.Optional.pList, property_list.Proprietary.pList); rpdata, property_list.Required.pList, property_list.Optional.pList,
property_list.Proprietary.pList);
#endif #endif
} else if (pObject->Object_Read_Property) { } else if (pObject->Object_Read_Property) {
apdu_len = pObject->Object_Read_Property(rpdata); apdu_len = pObject->Object_Read_Property(rpdata);
@@ -1372,8 +1496,9 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
wp_data, &value, characterstring_capacity(&My_Object_Name)); wp_data, &value, characterstring_capacity(&My_Object_Name));
if (status) { if (status) {
/* All the object names in a device must be unique */ /* All the object names in a device must be unique */
if (Device_Valid_Object_Name(&value.type.Character_String, if (Device_Valid_Object_Name(
&object_type, &object_instance)) { &value.type.Character_String, &object_type,
&object_instance)) {
if ((object_type == wp_data->object_type) && if ((object_type == wp_data->object_type) &&
(object_instance == wp_data->object_instance)) { (object_instance == wp_data->object_instance)) {
/* writing same name to same object */ /* writing same name to same object */
@@ -1737,7 +1862,8 @@ int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
* @param [out] The value list * @param [out] The value list
* @return True if the object instance supports this feature and value changed. * @return True if the object instance supports this feature and value changed.
*/ */
bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type, bool Device_Encode_Value_List(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list) BACNET_PROPERTY_VALUE *value_list)
{ {
@@ -1822,7 +1948,8 @@ bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
object for some other reason.*/ object for some other reason.*/
data->error_class = ERROR_CLASS_OBJECT; data->error_class = ERROR_CLASS_OBJECT;
data->error_code = ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED; data->error_code = ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED;
} else if (pObject->Object_Valid_Instance && } else if (
pObject->Object_Valid_Instance &&
pObject->Object_Valid_Instance(data->object_instance)) { pObject->Object_Valid_Instance(data->object_instance)) {
/* The object being created already exists */ /* The object being created already exists */
data->error_class = ERROR_CLASS_OBJECT; data->error_class = ERROR_CLASS_OBJECT;
@@ -1880,7 +2007,8 @@ bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
object for some reason.*/ object for some reason.*/
data->error_class = ERROR_CLASS_OBJECT; data->error_class = ERROR_CLASS_OBJECT;
data->error_code = ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED; data->error_code = ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED;
} else if (pObject->Object_Valid_Instance && } else if (
pObject->Object_Valid_Instance &&
pObject->Object_Valid_Instance(data->object_instance)) { pObject->Object_Valid_Instance(data->object_instance)) {
/* The object being deleted must already exist */ /* The object being deleted must already exist */
status = pObject->Object_Delete(data->object_instance); status = pObject->Object_Delete(data->object_instance);
@@ -1955,7 +2083,8 @@ void Device_Init(object_functions_t *object_table)
#endif #endif
} }
bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */ bool DeviceGetRRInfo(
BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
RR_PROP_INFO *pInfo) RR_PROP_INFO *pInfo)
{ /* Where to put the response */ { /* Where to put the response */
bool status = false; /* return value */ bool status = false; /* return value */
+25 -16
View File
@@ -100,7 +100,8 @@ static void Init_Service_Handlers(void)
apdu_set_unconfirmed_handler( apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
/* configure the cyclic timers */ /* configure the cyclic timers */
mstimer_set(&BACnet_Task_Timer, 1000UL); mstimer_set(&BACnet_Task_Timer, 1000UL);
@@ -141,7 +142,8 @@ static void Lighting_Output_Write_Value_Handler(
brightness = 0; brightness = 0;
} }
blinkt_set_pixel_brightness(index, brightness); blinkt_set_pixel_brightness(index, brightness);
printf("LED[%u]=%.1f%% (%u)\n", (unsigned)index, value, printf(
"LED[%u]=%.1f%% (%u)\n", (unsigned)index, value,
(unsigned)brightness); (unsigned)brightness);
} }
} }
@@ -165,7 +167,8 @@ static void Color_Temperature_Write_Value_Handler(
if (index < blinkt_led_count()) { if (index < blinkt_led_count()) {
color_rgb_from_temperature(value, &red, &green, &blue); color_rgb_from_temperature(value, &red, &green, &blue);
blinkt_set_pixel(index, red, green, blue); blinkt_set_pixel(index, red, green, blue);
printf("%u Kelvin RGB[%u]=%u,%u,%u\n", (unsigned)value, (unsigned)index, printf(
"%u Kelvin RGB[%u]=%u,%u,%u\n", (unsigned)value, (unsigned)index,
(unsigned)red, (unsigned)green, (unsigned)blue); (unsigned)red, (unsigned)green, (unsigned)blue);
} }
} }
@@ -176,7 +179,8 @@ static void Color_Temperature_Write_Value_Handler(
* @param old_value - BACnetXYColor value prior to write * @param old_value - BACnetXYColor value prior to write
* @param value - BACnetXYColor value of the write * @param value - BACnetXYColor value of the write
*/ */
static void Color_Write_Value_Handler(uint32_t object_instance, static void Color_Write_Value_Handler(
uint32_t object_instance,
BACNET_XY_COLOR *old_value, BACNET_XY_COLOR *old_value,
BACNET_XY_COLOR *value) BACNET_XY_COLOR *value)
{ {
@@ -189,12 +193,14 @@ static void Color_Write_Value_Handler(uint32_t object_instance,
index = object_instance - 1; index = object_instance - 1;
} }
if (index < blinkt_led_count()) { if (index < blinkt_led_count()) {
color_rgb_from_xy(&red, &green, &blue, value->x_coordinate, color_rgb_from_xy(
value->y_coordinate, brightness_percent); &red, &green, &blue, value->x_coordinate, value->y_coordinate,
brightness_percent);
blinkt_set_pixel(index, red, green, blue); blinkt_set_pixel(index, red, green, blue);
printf("x,y=%0.2f,%0.2f(%.1f%%) RGB[%u]=%u,%u,%u\n", printf(
value->x_coordinate, value->y_coordinate, brightness_percent, "x,y=%0.2f,%0.2f(%.1f%%) RGB[%u]=%u,%u,%u\n", value->x_coordinate,
(unsigned)index, (unsigned)red, (unsigned)green, (unsigned)blue); value->y_coordinate, brightness_percent, (unsigned)index,
(unsigned)red, (unsigned)green, (unsigned)blue);
} }
} }
@@ -315,8 +321,9 @@ static void print_help(const char *filename)
printf("--test:\n" printf("--test:\n"
"Test the Blinkt! RGB LEDs with a cycling pattern.\n"); "Test the Blinkt! RGB LEDs with a cycling pattern.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"%s 9009\n", "Example:\n"
"%s 9009\n",
filename); filename);
} }
@@ -375,15 +382,17 @@ int main(int argc, char *argv[])
} }
} }
if (device_id > BACNET_MAX_INSTANCE) { if (device_id > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device=%u - not greater than %u\n", device_id, fprintf(
stderr, "device=%u - not greater than %u\n", device_id,
BACNET_MAX_INSTANCE); BACNET_MAX_INSTANCE);
return 1; return 1;
} }
Device_Set_Object_Instance_Number(device_id); Device_Set_Object_Instance_Number(device_id);
printf("BACnet Raspberry Pi Blinkt! Demo\n" printf(
"BACnet Stack Version %s\n" "BACnet Raspberry Pi Blinkt! Demo\n"
"BACnet Device ID: %u\n" "BACnet Stack Version %s\n"
"Max APDU: %d\n", "BACnet Device ID: %u\n"
"Max APDU: %d\n",
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU); BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
/* load any static address bindings to show up /* load any static address bindings to show up
in our device bindings list */ in our device bindings list */
+47 -36
View File
@@ -63,22 +63,24 @@ static void MyPrintHandler(
BACNET_ERROR_CODE error_code, BACNET_ERROR_CODE error_code,
uint32_t first_failed_element_number) uint32_t first_failed_element_number)
{ {
printf("[{\n \"%s\": {\n" printf(
"[{\n \"%s\": {\n"
" \"object-type\": \"%s\",\n \"object-instance\": %lu,\n" " \"object-type\": \"%s\",\n \"object-instance\": %lu,\n"
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"", " \"error-class\": \"%s\",\n \"error-code\": \"%s\"",
bactext_confirmed_service_name(SERVICE_CONFIRMED_CREATE_OBJECT), bactext_confirmed_service_name(SERVICE_CONFIRMED_CREATE_OBJECT),
bactext_object_type_name(object_type), bactext_object_type_name(object_type), (unsigned long)object_instance,
(unsigned long)object_instance,
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
if (first_failed_element_number > 0) { if (first_failed_element_number > 0) {
printf(",\n \"first-failed-element-number\": %lu", printf(
",\n \"first-failed-element-number\": %lu",
(unsigned long)first_failed_element_number); (unsigned long)first_failed_element_number);
} }
printf("\n }\n}]\n"); printf("\n }\n}]\n");
} }
static void MyCreateObjectErrorHandler(BACNET_ADDRESS *src, static void MyCreateObjectErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
uint8_t service_choice, uint8_t service_choice,
uint8_t *service_request, uint8_t *service_request,
@@ -90,18 +92,19 @@ static void MyCreateObjectErrorHandler(BACNET_ADDRESS *src,
(void)service_choice; (void)service_choice;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
len = create_object_error_ack_service_decode(service_request, len = create_object_error_ack_service_decode(
service_len, &data); service_request, service_len, &data);
if (len > 0) { if (len > 0) {
MyPrintHandler(data.object_type, data.object_instance, MyPrintHandler(
data.error_class, data.error_code, data.object_type, data.object_instance, data.error_class,
data.first_failed_element_number); data.error_code, data.first_failed_element_number);
} }
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyCreateObjectAckHandler(uint8_t *service_request, static void MyCreateObjectAckHandler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -114,11 +117,13 @@ static void MyCreateObjectAckHandler(uint8_t *service_request,
len = create_object_ack_service_decode( len = create_object_ack_service_decode(
service_request, service_len, &data); service_request, service_len, &data);
if (len < 0) { if (len < 0) {
MyPrintHandler(Target_Object_Type, Target_Object_Instance, MyPrintHandler(
Target_Object_Type, Target_Object_Instance,
ERROR_CLASS_SERVICES, ERROR_CODE_REJECT_OTHER, 0); ERROR_CLASS_SERVICES, ERROR_CODE_REJECT_OTHER, 0);
} else { } else {
MyPrintHandler(data.object_type, data.object_instance, MyPrintHandler(
ERROR_CLASS_SERVICES, ERROR_CODE_SUCCESS, 0); data.object_type, data.object_instance, ERROR_CLASS_SERVICES,
ERROR_CODE_SUCCESS, 0);
} }
} else { } else {
if (Verbose) { if (Verbose) {
@@ -133,20 +138,21 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
MyPrintHandler(Target_Object_Type, Target_Object_Instance, MyPrintHandler(
ERROR_CLASS_SERVICES, abort_convert_to_error_code(abort_reason), 0); Target_Object_Type, Target_Object_Instance, ERROR_CLASS_SERVICES,
abort_convert_to_error_code(abort_reason), 0);
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
MyPrintHandler(Target_Object_Type, Target_Object_Instance, MyPrintHandler(
ERROR_CLASS_SERVICES, Target_Object_Type, Target_Object_Instance, ERROR_CLASS_SERVICES,
reject_convert_to_error_code(reject_reason), 0); reject_convert_to_error_code(reject_reason), 0);
Error_Detected = true; Error_Detected = true;
} }
@@ -207,10 +213,11 @@ static void print_help(const char *filename)
"you are creating. For example, if you were writing\n" "you are creating. For example, if you were writing\n"
"Analog Output 2, the object-instance would be 2.\n"); "Analog Output 2, the object-instance would be 2.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"If you want to CreateObject of an Analog Input 1\n" "Example:\n"
"send the following command:\n" "If you want to CreateObject of an Analog Input 1\n"
"%s 123 0 1\n", "send the following command:\n"
"%s 123 0 1\n",
filename); filename);
} }
@@ -275,8 +282,8 @@ int main(int argc, char *argv[])
if (target_args == 0) { if (target_args == 0) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
object_instance, BACNET_MAX_INSTANCE); object_instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -293,8 +300,8 @@ int main(int argc, char *argv[])
} else if (target_args == 2) { } else if (target_args == 2) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"object-instance=%u - not greater than %u\n", stderr, "object-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -328,7 +335,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance, &max_apdu, &Target_Address); Target_Device_Object_Instance, &max_apdu, &Target_Address);
if (found) { if (found) {
if (Verbose) { if (Verbose) {
printf("Found Device %u in address_cache.\n", printf(
"Found Device %u in address_cache.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
} else { } else {
@@ -341,16 +349,18 @@ int main(int argc, char *argv[])
/* device is bound! */ /* device is bound! */
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
if (Verbose) { if (Verbose) {
printf("Sending CreateObject to Device %u.\n", printf(
"Sending CreateObject to Device %u.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
Request_Invoke_ID = Request_Invoke_ID = Send_Create_Object_Request(
Send_Create_Object_Request(Target_Device_Object_Instance, Target_Device_Object_Instance, Target_Object_Type,
Target_Object_Type, Target_Object_Instance); Target_Object_Instance);
} else if (tsm_invoke_id_free(Request_Invoke_ID)) { } else if (tsm_invoke_id_free(Request_Invoke_ID)) {
break; break;
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) { } else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
MyPrintHandler(Target_Object_Type, Target_Object_Instance, MyPrintHandler(
Target_Object_Type, Target_Object_Instance,
ERROR_CLASS_COMMUNICATION, ERROR_CODE_ABORT_TSM_TIMEOUT, 0); ERROR_CLASS_COMMUNICATION, ERROR_CODE_ABORT_TSM_TIMEOUT, 0);
tsm_free_invoke_id(Request_Invoke_ID); tsm_free_invoke_id(Request_Invoke_ID);
Error_Detected = true; Error_Detected = true;
@@ -371,10 +381,11 @@ int main(int argc, char *argv[])
mstimer_reset(&maintenance_timer); mstimer_reset(&maintenance_timer);
tsm_timer_milliseconds(mstimer_interval(&maintenance_timer)); tsm_timer_milliseconds(mstimer_interval(&maintenance_timer));
datalink_maintenance_timer( datalink_maintenance_timer(
mstimer_interval(&maintenance_timer)/1000L); mstimer_interval(&maintenance_timer) / 1000L);
} }
if (mstimer_expired(&apdu_timer)) { if (mstimer_expired(&apdu_timer)) {
MyPrintHandler(Target_Object_Type, Target_Object_Instance, MyPrintHandler(
Target_Object_Type, Target_Object_Instance,
ERROR_CLASS_COMMUNICATION, ERROR_CLASS_COMMUNICATION,
ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME, 0); ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME, 0);
Error_Detected = true; Error_Detected = true;
+10 -6
View File
@@ -46,7 +46,8 @@ static char *Communication_Password = NULL;
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -54,7 +55,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
printf("BACnet Error: %s: %s\n", bactext_error_class_name(error_class), printf(
"BACnet Error: %s: %s\n", bactext_error_class_name(error_class),
bactext_error_code_name(error_code)); bactext_error_code_name(error_code));
Error_Detected = true; Error_Detected = true;
} }
@@ -70,8 +72,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -103,7 +105,8 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
/* handle the ack coming back */ /* handle the ack coming back */
apdu_set_confirmed_simple_ack_handler( apdu_set_confirmed_simple_ack_handler(
@@ -190,7 +193,8 @@ int main(int argc, char *argv[])
Communication_Password = argv[4]; Communication_Password = argv[4];
} }
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
+32 -29
View File
@@ -56,11 +56,11 @@ static bool Error_Detected = false;
/* Used for verbose */ /* Used for verbose */
static bool Verbose = false; static bool Verbose = false;
static void MyPrintHandler( static void
BACNET_ERROR_CLASS error_class, MyPrintHandler(BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CODE error_code)
{ {
printf("[{\n \"%s\": {\n" printf(
"[{\n \"%s\": {\n"
" \"object-type\": \"%s\",\n \"object-instance\": %lu,\n" " \"object-type\": \"%s\",\n \"object-instance\": %lu,\n"
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"\n }\n}]\n", " \"error-class\": \"%s\",\n \"error-code\": \"%s\"\n }\n}]\n",
bactext_confirmed_service_name(SERVICE_CONFIRMED_DELETE_OBJECT), bactext_confirmed_service_name(SERVICE_CONFIRMED_DELETE_OBJECT),
@@ -70,7 +70,8 @@ static void MyPrintHandler(
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
} }
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -82,8 +83,7 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
} }
} }
static void MySimpleAckHandler( static void MySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -97,19 +97,19 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
MyPrintHandler(ERROR_CLASS_SERVICES, MyPrintHandler(
abort_convert_to_error_code(abort_reason)); ERROR_CLASS_SERVICES, abort_convert_to_error_code(abort_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
MyPrintHandler(ERROR_CLASS_SERVICES, MyPrintHandler(
reject_convert_to_error_code(reject_reason)); ERROR_CLASS_SERVICES, reject_convert_to_error_code(reject_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
@@ -138,8 +138,7 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance\n", printf("Usage: %s device-instance object-type object-instance\n", filename);
filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help][--verbose]\n"); printf(" [--version][--help][--verbose]\n");
} }
@@ -168,10 +167,11 @@ static void print_help(const char *filename)
"you are deleting. For example, if you were deleting\n" "you are deleting. For example, if you were deleting\n"
"Analog Output 2, the object-instance would be 2.\n"); "Analog Output 2, the object-instance would be 2.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"If you want to DeleteObject an Analog Input 1\n" "Example:\n"
"send the following command:\n" "If you want to DeleteObject an Analog Input 1\n"
"%s 123 0 1\n", "send the following command:\n"
"%s 123 0 1\n",
filename); filename);
} }
@@ -236,8 +236,8 @@ int main(int argc, char *argv[])
if (target_args == 0) { if (target_args == 0) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
object_instance, BACNET_MAX_INSTANCE); object_instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -254,8 +254,8 @@ int main(int argc, char *argv[])
} else if (target_args == 2) { } else if (target_args == 2) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"object-instance=%u - not greater than %u\n", stderr, "object-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -289,7 +289,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance, &max_apdu, &Target_Address); Target_Device_Object_Instance, &max_apdu, &Target_Address);
if (found) { if (found) {
if (Verbose) { if (Verbose) {
printf("Found Device %u in address_cache.\n", printf(
"Found Device %u in address_cache.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
} else { } else {
@@ -302,7 +303,8 @@ int main(int argc, char *argv[])
/* device is bound! */ /* device is bound! */
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
if (Verbose) { if (Verbose) {
printf("Sending DeleteObject to Device %u.\n", printf(
"Sending DeleteObject to Device %u.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
Request_Invoke_ID = Send_Delete_Object_Request( Request_Invoke_ID = Send_Delete_Object_Request(
@@ -311,8 +313,8 @@ int main(int argc, char *argv[])
} else if (tsm_invoke_id_free(Request_Invoke_ID)) { } else if (tsm_invoke_id_free(Request_Invoke_ID)) {
break; break;
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) { } else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
MyPrintHandler(ERROR_CLASS_COMMUNICATION, MyPrintHandler(
ERROR_CODE_ABORT_TSM_TIMEOUT); ERROR_CLASS_COMMUNICATION, ERROR_CODE_ABORT_TSM_TIMEOUT);
tsm_free_invoke_id(Request_Invoke_ID); tsm_free_invoke_id(Request_Invoke_ID);
Error_Detected = true; Error_Detected = true;
/* abort */ /* abort */
@@ -332,10 +334,11 @@ int main(int argc, char *argv[])
mstimer_reset(&maintenance_timer); mstimer_reset(&maintenance_timer);
tsm_timer_milliseconds(mstimer_interval(&maintenance_timer)); tsm_timer_milliseconds(mstimer_interval(&maintenance_timer));
datalink_maintenance_timer( datalink_maintenance_timer(
mstimer_interval(&maintenance_timer)/1000L); mstimer_interval(&maintenance_timer) / 1000L);
} }
if (mstimer_expired(&apdu_timer)) { if (mstimer_expired(&apdu_timer)) {
MyPrintHandler(ERROR_CLASS_COMMUNICATION, MyPrintHandler(
ERROR_CLASS_COMMUNICATION,
ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME); ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME);
Error_Detected = true; Error_Detected = true;
} }
+15 -11
View File
@@ -67,19 +67,23 @@
* @ingroup BACEPICS * @ingroup BACEPICS
*/ */
typedef enum { typedef enum {
/** Initial state to establish a binding with the target device. */ /** Initial state to establish a binding with the target device. */
INITIAL_BINDING, INITIAL_BINDING,
/** Get selected device information and put out the heading information. */ /** Get selected device information and put out the heading information. */
GET_HEADING_INFO, GET_HEADING_RESPONSE, PRINT_HEADING, GET_HEADING_INFO,
/** Getting ALL properties and values at once with RPM. */ GET_HEADING_RESPONSE,
GET_ALL_REQUEST, GET_ALL_RESPONSE, PRINT_HEADING,
/** Getting ALL properties with array index = 0, just to get the list. */ /** Getting ALL properties and values at once with RPM. */
GET_LIST_OF_ALL_REQUEST, GET_LIST_OF_ALL_RESPONSE, GET_ALL_REQUEST,
/** Processing the properties individually with ReadProperty. */ GET_ALL_RESPONSE,
GET_PROPERTY_REQUEST, GET_PROPERTY_RESPONSE, /** Getting ALL properties with array index = 0, just to get the list. */
/** Done with this Object; move onto the next. */ GET_LIST_OF_ALL_REQUEST,
GET_LIST_OF_ALL_RESPONSE,
/** Processing the properties individually with ReadProperty. */
GET_PROPERTY_REQUEST,
GET_PROPERTY_RESPONSE,
/** Done with this Object; move onto the next. */
NEXT_OBJECT NEXT_OBJECT
} EPICS_STATES; } EPICS_STATES;
#endif /* BACEPICS_H_ */ #endif /* BACEPICS_H_ */
+89 -58
View File
@@ -11,7 +11,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> /* for time */ #include <time.h> /* for time */
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
#include <locale.h> #include <locale.h>
#endif #endif
#include <errno.h> #include <errno.h>
@@ -117,10 +117,12 @@ struct property_value_list_t {
BACNET_APPLICATION_DATA_VALUE *value; BACNET_APPLICATION_DATA_VALUE *value;
}; };
static struct property_value_list_t Property_Value_List[] = { static struct property_value_list_t Property_Value_List[] = {
{ PROP_VENDOR_NAME, NULL }, { PROP_MODEL_NAME, NULL }, { PROP_VENDOR_NAME, NULL },
{ PROP_MODEL_NAME, NULL },
{ PROP_MAX_APDU_LENGTH_ACCEPTED, NULL }, { PROP_MAX_APDU_LENGTH_ACCEPTED, NULL },
{ PROP_PROTOCOL_SERVICES_SUPPORTED, NULL }, { PROP_PROTOCOL_SERVICES_SUPPORTED, NULL },
{ PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL }, { PROP_DESCRIPTION, NULL }, { PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL },
{ PROP_DESCRIPTION, NULL },
{ -1, NULL } { -1, NULL }
}; };
@@ -161,7 +163,8 @@ static bool Optional_Properties = false;
#define PRINT_ERRORS 1 #define PRINT_ERRORS 1
#endif #endif
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -170,7 +173,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
#if PRINT_ERRORS #if PRINT_ERRORS
if (ShowValues) { if (ShowValues) {
fprintf(stderr, "-- BACnet Error: %s: %s\n", fprintf(
stderr, "-- BACnet Error: %s: %s\n",
bactext_error_class_name(error_class), bactext_error_class_name(error_class),
bactext_error_code_name(error_code)); bactext_error_code_name(error_code));
} }
@@ -190,7 +194,8 @@ static void MyAbortHandler(
#if PRINT_ERRORS #if PRINT_ERRORS
/* It is normal for this to fail, so don't print. */ /* It is normal for this to fail, so don't print. */
if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) { if ((myState != GET_ALL_RESPONSE) && !IsLongArray && ShowValues) {
fprintf(stderr, "-- BACnet Abort: %s \n", fprintf(
stderr, "-- BACnet Abort: %s \n",
bactext_abort_reason_name(abort_reason)); bactext_abort_reason_name(abort_reason));
} }
#endif #endif
@@ -205,14 +210,15 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
#if PRINT_ERRORS #if PRINT_ERRORS
if (ShowValues) { if (ShowValues) {
fprintf(stderr, "BACnet Reject: %s\n", fprintf(
stderr, "BACnet Reject: %s\n",
bactext_reject_reason_name(reject_reason)); bactext_reject_reason_name(reject_reason));
} }
#endif #endif
@@ -227,7 +233,8 @@ static void MyRejectHandler(
} }
} }
static void MyReadPropertyAckHandler(uint8_t *service_request, static void MyReadPropertyAckHandler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -243,7 +250,8 @@ static void MyReadPropertyAckHandler(uint8_t *service_request,
service_request, service_len, rp_data); service_request, service_len, rp_data);
} }
if (len > 0) { if (len > 0) {
memmove(&Read_Property_Multiple_Data.service_data, service_data, memmove(
&Read_Property_Multiple_Data.service_data, service_data,
sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA));
Read_Property_Multiple_Data.rpm_data = rp_data; Read_Property_Multiple_Data.rpm_data = rp_data;
Read_Property_Multiple_Data.new_data = true; Read_Property_Multiple_Data.new_data = true;
@@ -256,7 +264,8 @@ static void MyReadPropertyAckHandler(uint8_t *service_request,
} }
} }
static void MyReadPropertyMultipleAckHandler(uint8_t *service_request, static void MyReadPropertyMultipleAckHandler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -272,7 +281,8 @@ static void MyReadPropertyMultipleAckHandler(uint8_t *service_request,
service_request, service_len, rpm_data); service_request, service_len, rpm_data);
} }
if (len > 0) { if (len > 0) {
memmove(&Read_Property_Multiple_Data.service_data, service_data, memmove(
&Read_Property_Multiple_Data.service_data, service_data,
sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA)); sizeof(BACNET_CONFIRMED_SERVICE_ACK_DATA));
Read_Property_Multiple_Data.rpm_data = rpm_data; Read_Property_Multiple_Data.rpm_data = rpm_data;
Read_Property_Multiple_Data.new_data = true; Read_Property_Multiple_Data.new_data = true;
@@ -372,11 +382,12 @@ static bool PrettyPrintPropertyValue(
property = object_value->object_property; property = object_value->object_property;
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) && if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) &&
((property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) || ((property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) ||
(property == PROP_PROTOCOL_SERVICES_SUPPORTED))) { (property == PROP_PROTOCOL_SERVICES_SUPPORTED))) {
len = bitstring_bits_used(&value->type.Bit_String); len = bitstring_bits_used(&value->type.Bit_String);
fprintf(stream, "( \n "); fprintf(stream, "( \n ");
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
fprintf(stream, "%s", fprintf(
stream, "%s",
bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F"); bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F");
if (i < len - 1) { if (i < len - 1) {
fprintf(stream, ","); fprintf(stream, ",");
@@ -395,7 +406,8 @@ static bool PrettyPrintPropertyValue(
stream, " %s,", bactext_object_type_name(j)); stream, " %s,", bactext_object_type_name(j));
} else { } else {
/* PROP_PROTOCOL_SERVICES_SUPPORTED */ /* PROP_PROTOCOL_SERVICES_SUPPORTED */
fprintf(stream, " %s,", fprintf(
stream, " %s,",
protocol_services_supported_text(j)); protocol_services_supported_text(j));
} }
} else { /* not supported */ } else { /* not supported */
@@ -412,7 +424,8 @@ static bool PrettyPrintPropertyValue(
* clearer, international form. */ * clearer, international form. */
strncpy(short_month, bactext_month_name(value->type.Date.month), 3); strncpy(short_month, bactext_month_name(value->type.Date.month), 3);
short_month[3] = 0; short_month[3] = 0;
fprintf(stream, "(%u-%3s-%u, %u)", (unsigned)value->type.Date.day, fprintf(
stream, "(%u-%3s-%u, %u)", (unsigned)value->type.Date.day,
short_month, (unsigned)value->type.Date.year, short_month, (unsigned)value->type.Date.year,
(unsigned)value->type.Date.wday); (unsigned)value->type.Date.wday);
} else if (value != NULL) { } else if (value != NULL) {
@@ -436,7 +449,8 @@ static bool PrettyPrintPropertyValue(
* @param rpm_property [in] Points to structure holding the Property, * @param rpm_property [in] Points to structure holding the Property,
* Value, and Error information. * Value, and Error information.
*/ */
static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type, static void PrintReadPropertyData(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_REFERENCE *rpm_property) BACNET_PROPERTY_REFERENCE *rpm_property)
{ {
@@ -452,7 +466,8 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
value = rpm_property->value; value = rpm_property->value;
if (value == NULL) { if (value == NULL) {
/* Then we print the error information */ /* Then we print the error information */
fprintf(stdout, "? -- BACnet Error: %s: %s\n", fprintf(
stdout, "? -- BACnet Error: %s: %s\n",
bactext_error_class_name((int)rpm_property->error.error_class), bactext_error_class_name((int)rpm_property->error.error_class),
bactext_error_code_name((int)rpm_property->error.error_code)); bactext_error_code_name((int)rpm_property->error.error_code));
return; return;
@@ -516,7 +531,8 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
} }
break; break;
} else { } else {
assert(Walked_List_Index == assert(
Walked_List_Index ==
(uint32_t)rpm_property->propertyArrayIndex); (uint32_t)rpm_property->propertyArrayIndex);
} }
} else { } else {
@@ -553,13 +569,14 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
} }
/* Store the object list so we can interrogate /* Store the object list so we can interrogate
each object. */ each object. */
object_list_element = KEY_ENCODE(value->type.Object_Id.type, object_list_element = KEY_ENCODE(
value->type.Object_Id.type,
value->type.Object_Id.instance); value->type.Object_Id.instance);
/* We don't have anything to put in the data pointer /* We don't have anything to put in the data pointer
* yet, so just leave it null. The key is Key here. */ * yet, so just leave it null. The key is Key here. */
Keylist_Data_Add(Object_List, object_list_element, NULL); Keylist_Data_Add(Object_List, object_list_element, NULL);
} else if (rpm_property->propertyIdentifier == } else if (
PROP_STATE_TEXT) { rpm_property->propertyIdentifier == PROP_STATE_TEXT) {
/* Make sure it fits within 31 chars for original VTS3 /* Make sure it fits within 31 chars for original VTS3
* limitation. If longer, take first 15 dash, and last 15 * limitation. If longer, take first 15 dash, and last 15
* chars. */ * chars. */
@@ -567,14 +584,15 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
int iLast15idx = int iLast15idx =
value->type.Character_String.length - 15; value->type.Character_String.length - 15;
value->type.Character_String.value[15] = '-'; value->type.Character_String.value[15] = '-';
memmove(&value->type.Character_String.value[16], memmove(
&value->type.Character_String.value[16],
&value->type.Character_String.value[iLast15idx], &value->type.Character_String.value[iLast15idx],
15); 15);
value->type.Character_String.value[31] = 0; value->type.Character_String.value[31] = 0;
value->type.Character_String.length = 31; value->type.Character_String.length = 31;
} }
} else if (rpm_property->propertyIdentifier == } else if (
PROP_SUBORDINATE_LIST) { rpm_property->propertyIdentifier == PROP_SUBORDINATE_LIST) {
if (value->tag != if (value->tag !=
BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE) { BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE) {
break; break;
@@ -648,8 +666,8 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
/* Closing brace for this multi-valued array */ /* Closing brace for this multi-valued array */
fprintf(stdout, " }"); fprintf(stdout, " }");
} }
if (property_list_writable_member(object_type, if (property_list_writable_member(
rpm_property->propertyIdentifier)) { object_type, rpm_property->propertyIdentifier)) {
fprintf(stdout, " Writable"); fprintf(stdout, " Writable");
} }
fprintf(stdout, "\n"); fprintf(stdout, "\n");
@@ -709,8 +727,8 @@ static void BuildPropRequest(BACNET_READ_ACCESS_DATA *rpm_object)
* @return The invokeID of the message sent, or 0 if reached the end * @return The invokeID of the message sent, or 0 if reached the end
* of the property list. * of the property list.
*/ */
static uint8_t Read_Properties( static uint8_t
uint32_t device_instance, const BACNET_OBJECT_ID *pMyObject) Read_Properties(uint32_t device_instance, const BACNET_OBJECT_ID *pMyObject)
{ {
uint8_t invoke_id = 0; uint8_t invoke_id = 0;
struct special_property_list_t PropertyListStruct; struct special_property_list_t PropertyListStruct;
@@ -775,8 +793,9 @@ static uint8_t Read_Properties(
break; break;
} }
} }
invoke_id = Send_Read_Property_Request(device_instance, pMyObject->type, invoke_id = Send_Read_Property_Request(
pMyObject->instance, prop, array_index); device_instance, pMyObject->type, pMyObject->instance, prop,
array_index);
} }
return invoke_id; return invoke_id;
@@ -793,8 +812,8 @@ static uint8_t Read_Properties(
* if the RPM got good data, or GET_PROPERTY_REQUEST if we have to * if the RPM got good data, or GET_PROPERTY_REQUEST if we have to
* singly process the list of Properties. * singly process the list of Properties.
*/ */
static EPICS_STATES ProcessRPMData( static EPICS_STATES
BACNET_READ_ACCESS_DATA *rpm_data, EPICS_STATES state) ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data, EPICS_STATES state)
{ {
BACNET_READ_ACCESS_DATA *old_rpm_data; BACNET_READ_ACCESS_DATA *old_rpm_data;
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
@@ -845,8 +864,9 @@ static EPICS_STATES ProcessRPMData(
fprintf(stdout, " "); fprintf(stdout, " ");
Print_Property_Identifier(rpm_property->propertyIdentifier); Print_Property_Identifier(rpm_property->propertyIdentifier);
fprintf(stdout, ": "); fprintf(stdout, ": ");
PrintReadPropertyData(rpm_data->object_type, PrintReadPropertyData(
rpm_data->object_instance, rpm_property); rpm_data->object_type, rpm_data->object_instance,
rpm_property);
} }
old_rpm_property = rpm_property; old_rpm_property = rpm_property;
rpm_property = rpm_property->next; rpm_property = rpm_property->next;
@@ -886,8 +906,9 @@ static EPICS_STATES ProcessRPMData(
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]" printf(
" device-instance\n", "Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
" device-instance\n",
filename); filename);
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
} }
@@ -984,9 +1005,9 @@ static int CheckCommandLineArgs(int argc, char *argv[])
int count; int count;
/* loop counter */ /* loop counter */
unsigned j; unsigned j;
count = count = sscanf(
sscanf(argv[i], "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0], argv[i], "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0],
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
if (count == 6) { /* success */ if (count == 6) { /* success */
Target_Address.mac_len = count; Target_Address.mac_len = count;
for (j = 0; j < 6; j++) { for (j = 0; j < 6; j++) {
@@ -1011,8 +1032,8 @@ static int CheckCommandLineArgs(int argc, char *argv[])
/* decode the Target Device Instance parameter */ /* decode the Target Device Instance parameter */
Target_Device_Object_Instance = strtol(anArg, NULL, 0); Target_Device_Object_Instance = strtol(anArg, NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stdout, fprintf(
"Error: device-instance=%u - not greater than %u\n", stdout, "Error: device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
print_usage(filename); print_usage(filename);
exit(0); exit(0);
@@ -1045,7 +1066,8 @@ static void PrintHeading(void)
value = object_property_value(PROP_VENDOR_NAME); value = object_property_value(PROP_VENDOR_NAME);
if ((value != NULL) && if ((value != NULL) &&
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) { (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
printf("Vendor Name: \"%s\"\n", printf(
"Vendor Name: \"%s\"\n",
characterstring_value(&value->type.Character_String)); characterstring_value(&value->type.Character_String));
} else { } else {
printf("Vendor Name: \"your vendor name here\"\n"); printf("Vendor Name: \"your vendor name here\"\n");
@@ -1055,9 +1077,11 @@ static void PrintHeading(void)
/* Best we can do with Product Name and Model Number is use the same text */ /* Best we can do with Product Name and Model Number is use the same text */
if ((value != NULL) && if ((value != NULL) &&
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) { (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
printf("Product Name: \"%s\"\n", printf(
"Product Name: \"%s\"\n",
characterstring_value(&value->type.Character_String)); characterstring_value(&value->type.Character_String));
printf("Product Model Number: \"%s\"\n", printf(
"Product Model Number: \"%s\"\n",
characterstring_value(&value->type.Character_String)); characterstring_value(&value->type.Character_String));
} else { } else {
printf("Product Name: \"your product name here\"\n"); printf("Product Name: \"your product name here\"\n");
@@ -1067,7 +1091,8 @@ static void PrintHeading(void)
value = object_property_value(PROP_DESCRIPTION); value = object_property_value(PROP_DESCRIPTION);
if ((value != NULL) && if ((value != NULL) &&
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) { (value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
printf("Product Description: \"%s\"\n\n", printf(
"Product Description: \"%s\"\n\n",
characterstring_value(&value->type.Character_String)); characterstring_value(&value->type.Character_String));
} else { } else {
printf("Product Description: " printf("Product Description: "
@@ -1093,8 +1118,9 @@ static void PrintHeading(void)
printf("-- DM-UTC-B\n"); printf("-- DM-UTC-B\n");
#ifdef BAC_ROUTING #ifdef BAC_ROUTING
/* Next line only for the gateway (ie, if not addressing a subNet) */ /* Next line only for the gateway (ie, if not addressing a subNet) */
if (Target_Address.net == 0) if (Target_Address.net == 0) {
printf("-- NM-RC-B\n"); printf("-- NM-RC-B\n");
}
#endif #endif
printf("}\n\n"); printf("}\n\n");
printf("BACnet Standard Application Services Supported:\n"); printf("BACnet Standard Application Services Supported:\n");
@@ -1340,7 +1366,7 @@ int main(int argc, char *argv[])
address_init(); address_init();
Init_Service_Handlers(); Init_Service_Handlers();
dlenv_init(); dlenv_init();
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
/* Internationalized programs must call setlocale() /* Internationalized programs must call setlocale()
* to initiate a specific language operation. * to initiate a specific language operation.
* This can be done by calling setlocale() as follows. * This can be done by calling setlocale() as follows.
@@ -1371,8 +1397,8 @@ int main(int argc, char *argv[])
if (Target_Address.net > 0) { if (Target_Address.net > 0) {
/* We specified a DNET; call Who-Is to find the full /* We specified a DNET; call Who-Is to find the full
* routed path to this Device */ * routed path to this Device */
Send_WhoIs_Remote(&Target_Address, Send_WhoIs_Remote(
Target_Device_Object_Instance, &Target_Address, Target_Device_Object_Instance,
Target_Device_Object_Instance); Target_Device_Object_Instance);
} else { } else {
@@ -1418,7 +1444,8 @@ int main(int argc, char *argv[])
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) { if (elapsed_seconds > timeout_seconds) {
fprintf(stderr, fprintf(
stderr,
"\rError: Unable to bind to %u" "\rError: Unable to bind to %u"
" after waiting %ld seconds.\n", " after waiting %ld seconds.\n",
Target_Device_Object_Instance, Target_Device_Object_Instance,
@@ -1492,7 +1519,7 @@ int main(int argc, char *argv[])
if ((Read_Property_Multiple_Data.new_data) && if ((Read_Property_Multiple_Data.new_data) &&
(Request_Invoke_ID == (Request_Invoke_ID ==
Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.service_data.invoke_id)) {
Read_Property_Multiple_Data.new_data = false; Read_Property_Multiple_Data.new_data = false;
myState = ProcessRPMData( myState = ProcessRPMData(
Read_Property_Multiple_Data.rpm_data, myState); Read_Property_Multiple_Data.rpm_data, myState);
@@ -1516,7 +1543,8 @@ int main(int argc, char *argv[])
/* Was it because the Device can't do RPM? */ /* Was it because the Device can't do RPM? */
Has_RPM = false; Has_RPM = false;
myState = GET_PROPERTY_REQUEST; myState = GET_PROPERTY_REQUEST;
} else if (Last_Error_Code == } else if (
Last_Error_Code ==
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) { ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) {
myState = GET_PROPERTY_REQUEST; myState = GET_PROPERTY_REQUEST;
StartNextObject(rpm_object, &myObject); StartNextObject(rpm_object, &myObject);
@@ -1587,7 +1615,7 @@ int main(int argc, char *argv[])
if ((Read_Property_Multiple_Data.new_data) && if ((Read_Property_Multiple_Data.new_data) &&
(Request_Invoke_ID == (Request_Invoke_ID ==
Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.service_data.invoke_id)) {
Read_Property_Multiple_Data.new_data = false; Read_Property_Multiple_Data.new_data = false;
PrintReadPropertyData( PrintReadPropertyData(
Read_Property_Multiple_Data.rpm_data->object_type, Read_Property_Multiple_Data.rpm_data->object_type,
@@ -1684,10 +1712,12 @@ int main(int argc, char *argv[])
do { do {
Object_List_Index++; Object_List_Index++;
if (Object_List_Index < Keylist_Count(Object_List)) { if (Object_List_Index < Keylist_Count(Object_List)) {
if (Keylist_Index_Key(Object_List, Object_List_Index, &nextKey)) { if (Keylist_Index_Key(
Object_List, Object_List_Index, &nextKey)) {
myObject.type = KEY_DECODE_TYPE(nextKey); myObject.type = KEY_DECODE_TYPE(nextKey);
myObject.instance = KEY_DECODE_ID(nextKey); myObject.instance = KEY_DECODE_ID(nextKey);
/* Don't re-list the Device Object among its objects */ /* Don't re-list the Device Object among its objects
*/
if (myObject.type == OBJECT_DEVICE) { if (myObject.type == OBJECT_DEVICE) {
continue; continue;
} }
@@ -1732,7 +1762,8 @@ int main(int argc, char *argv[])
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
elapsed_seconds += (current_seconds - last_seconds); elapsed_seconds += (current_seconds - last_seconds);
if (elapsed_seconds > timeout_seconds) { if (elapsed_seconds > timeout_seconds) {
fprintf(stderr, "\rError: APDU Timeout! (%lds)\n", fprintf(
stderr, "\rError: APDU Timeout! (%lds)\n",
(long int)elapsed_seconds); (long int)elapsed_seconds);
break; break;
} }
+28 -24
View File
@@ -47,8 +47,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -77,7 +77,8 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s [error-class error-code service-number invoke-id]\n", printf(
"Usage: %s [error-class error-code service-number invoke-id]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -87,32 +88,34 @@ static void print_help(const char *filename)
{ {
printf("Send BACnet Error message to the network.\n"); printf("Send BACnet Error message to the network.\n");
printf("--mac A\n" printf("--mac A\n"
"Optional destination BACnet mac address." "Optional destination BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf(
"--dnet N\n"
"Optional destination BACnet network number N for directed requests.\n" "Optional destination BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"Optional BACnet mac address on the destination BACnet network.\n" "Optional BACnet mac address on the destination BACnet network.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("error-class:\n" printf(
" number from 0 to 65535\n" "error-class:\n"
"error-code:\n" " number from 0 to 65535\n"
" number from 0 to 65535\n" "error-code:\n"
"service-number:\n" " number from 0 to 65535\n"
" number from 0 to 65535 for BACnet Services\n" "service-number:\n"
"invoke-id:\n" " number from 0 to 65535 for BACnet Services\n"
" number from 1 to 255\n" "invoke-id:\n"
"Example:\n" " number from 1 to 255\n"
"%s 3 2 1\n", "Example:\n"
"%s 3 2 1\n",
filename); filename);
} }
@@ -219,8 +222,9 @@ int main(int argc, char *argv[])
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
/* send the request */ /* send the request */
Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID, Send_Error_To_Network(
Target_Service, Target_Error_Class, Target_Error_Code); &Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID, Target_Service,
Target_Error_Class, Target_Error_Code);
return 0; return 0;
} }
+61 -53
View File
@@ -50,14 +50,16 @@ static bool Error_Detected = false;
* @param error_class [in] the error class * @param error_class [in] the error class
* @param error_code [in] the error code * @param error_code [in] the error code
*/ */
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -89,12 +91,13 @@ static void MyAbortHandler(
* @param invoke_id [in] the invokeID from the rejected message * @param invoke_id [in] the invokeID from the rejected message
* @param reject_reason [in] the reason for the rejection * @param reject_reason [in] the reason for the rejection
*/ */
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -105,8 +108,8 @@ static void MyRejectHandler(
* @param src [in] BACNET_ADDRESS of the source of the message * @param src [in] BACNET_ADDRESS of the source of the message
* @param invoke_id [in] the invokeID from the rejected message * @param invoke_id [in] the invokeID from the rejected message
*/ */
static void MyWritePropertySimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -143,12 +146,13 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-id process-id initiating-device-id\n" printf(
" event-object-type event-object-instance\n" "Usage: %s device-id process-id initiating-device-id\n"
" sequence-number notification-class priority message-text\n" " event-object-type event-object-instance\n"
" notify-type ack-required from-state to-state event-type\n" " sequence-number notification-class priority message-text\n"
" [change-of-bitstring reference-bit-string status-flags]\n" " notify-type ack-required from-state to-state event-type\n"
" [change-of-state new-state-tag new-state-value status-flags]\n", " [change-of-bitstring reference-bit-string status-flags]\n"
" [change-of-state new-state-tag new-state-value status-flags]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -157,69 +161,71 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Send BACnet ConfirmedEventNotification message to a device.\n"); printf("Send BACnet ConfirmedEventNotification message to a device.\n");
printf("device-id:\n" printf(
"device-id:\n"
"BACnet Device Object Instance number that you are trying to\n" "BACnet Device Object Instance number that you are trying to\n"
"communicate to. This number will be used to try and bind with\n" "communicate to. This number will be used to try and bind with\n"
"the device using Who-Is and I-Am services. For example, if you were\n" "the device using Who-Is and I-Am services. For example, if you were\n"
"notifying Device Object 123, the device-instance would be 123.\n"); "notifying Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf("process-id:\n" printf("process-id:\n"
"Process Identifier in the receiving device for which the\n" "Process Identifier in the receiving device for which the\n"
"notification is intended.\n"); "notification is intended.\n");
printf("\n"); printf("\n");
printf("initiating-device-id: the BACnet Device Object Instance number\n" printf("initiating-device-id: the BACnet Device Object Instance number\n"
"that initiated the ConfirmedEventNotification service request.\n"); "that initiated the ConfirmedEventNotification service request.\n");
printf("\n"); printf("\n");
printf("event-object-type:\n" printf(
"event-object-type:\n"
"The object type is defined either as the object-type name string\n" "The object type is defined either as the object-type name string\n"
"as defined in the BACnet specification, or as the integer value.\n"); "as defined in the BACnet specification, or as the integer value.\n");
printf("\n"); printf("\n");
printf("event-object-instance:\n" printf("event-object-instance:\n"
"The object instance number of the event object.\n"); "The object instance number of the event object.\n");
printf("\n"); printf("\n");
printf("sequence-number:\n" printf("sequence-number:\n"
"The sequence number of the event.\n"); "The sequence number of the event.\n");
printf("\n"); printf("\n");
printf("notification-class:\n" printf("notification-class:\n"
"The notification-class of the event.\n"); "The notification-class of the event.\n");
printf("\n"); printf("\n");
printf("priority:\n" printf("priority:\n"
"The priority of the event.\n"); "The priority of the event.\n");
printf("\n"); printf("\n");
printf("message-text:\n" printf("message-text:\n"
"The message text of the event.\n"); "The message text of the event.\n");
printf("\n"); printf("\n");
printf("notify-type:\n" printf("notify-type:\n"
"The notify type of the event.\n"); "The notify type of the event.\n");
printf("\n"); printf("\n");
printf("ack-required:\n" printf("ack-required:\n"
"The ack-required of the event (0=FALSE,1=TRUE).\n"); "The ack-required of the event (0=FALSE,1=TRUE).\n");
printf("\n"); printf("\n");
printf("from-state:\n" printf("from-state:\n"
"The from-state of the event.\n"); "The from-state of the event.\n");
printf("\n"); printf("\n");
printf("to-state:\n" printf("to-state:\n"
"The to-state of the event.\n"); "The to-state of the event.\n");
printf("\n"); printf("\n");
printf("event-type\n" printf("event-type\n"
"The event-type of the event.\n"); "The event-type of the event.\n");
printf("\n"); printf("\n");
printf("--mac A\n" printf("--mac A\n"
"Optional BACnet mac address." "Optional BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf("--dnet N\n"
"Optional BACnet network number N for directed requests.\n" "Optional BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"Optional BACnet mac address on the destination BACnet network.\n" "Optional BACnet mac address on the destination BACnet network.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
(void)filename; (void)filename;
} }
@@ -462,8 +468,8 @@ int main(int argc, char *argv[])
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == EVENT_OUT_OF_RANGE) { } else if (event_data.eventType == EVENT_OUT_OF_RANGE) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == } else if (
EVENT_CHANGE_OF_LIFE_SAFETY) { event_data.eventType == EVENT_CHANGE_OF_LIFE_SAFETY) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == EVENT_EXTENDED) { } else if (event_data.eventType == EVENT_EXTENDED) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
@@ -477,26 +483,27 @@ int main(int argc, char *argv[])
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == EVENT_SIGNED_OUT_OF_RANGE) { } else if (event_data.eventType == EVENT_SIGNED_OUT_OF_RANGE) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == } else if (
EVENT_UNSIGNED_OUT_OF_RANGE) { event_data.eventType == EVENT_UNSIGNED_OUT_OF_RANGE) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == } else if (
EVENT_CHANGE_OF_CHARACTERSTRING) { event_data.eventType == EVENT_CHANGE_OF_CHARACTERSTRING) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == } else if (
EVENT_CHANGE_OF_STATUS_FLAGS) { event_data.eventType == EVENT_CHANGE_OF_STATUS_FLAGS) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == } else if (
EVENT_CHANGE_OF_RELIABILITY) { event_data.eventType == EVENT_CHANGE_OF_RELIABILITY) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == EVENT_NONE) { } else if (event_data.eventType == EVENT_NONE) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == } else if (
EVENT_CHANGE_OF_DISCRETE_VALUE) { event_data.eventType == EVENT_CHANGE_OF_DISCRETE_VALUE) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if (event_data.eventType == EVENT_CHANGE_OF_TIMER) { } else if (event_data.eventType == EVENT_CHANGE_OF_TIMER) {
/* FIXME: add event type parameters */ /* FIXME: add event type parameters */
} else if ((event_data.eventType >= EVENT_PROPRIETARY_MIN) && } else if (
(event_data.eventType >= EVENT_PROPRIETARY_MIN) &&
(event_data.eventType <= EVENT_PROPRIETARY_MAX)) { (event_data.eventType <= EVENT_PROPRIETARY_MAX)) {
/* Enumerated values 64-65535 may /* Enumerated values 64-65535 may
be used by others subject to be used by others subject to
@@ -544,7 +551,8 @@ int main(int argc, char *argv[])
dest.len = 0; dest.len = 0;
} }
address_add(Target_Device_Object_Instance, MAX_APDU, &dest); address_add(Target_Device_Object_Instance, MAX_APDU, &dest);
printf("Added Device %u to address cache\n", printf(
"Added Device %u to address cache\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
/* setup my info */ /* setup my info */
+37 -22
View File
@@ -40,50 +40,66 @@
static void Init_Service_Handlers() static void Init_Service_Handlers()
{ {
apdu_set_unconfirmed_handler(
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast); SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, handler_read_range); SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); apdu_set_confirmed_handler(
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc); SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
} }
/* /*
* FIXME: This is a hack to get things linking correctly * FIXME: This is a hack to get things linking correctly
*/ */
extern int cov_subscribe(void) { extern int cov_subscribe(void)
{
return 0; return 0;
} }
extern int Device_Value_List_Supported(void) { extern int Device_Value_List_Supported(void)
{
return 0; return 0;
} }
extern int Encode_RR_payload(void) { extern int Encode_RR_payload(void)
{
return 0; return 0;
} }
extern int Device_Objects_RR_Info(void) { extern int Device_Objects_RR_Info(void)
{
return 0; return 0;
} }
extern int Device_Write_Property(void) { extern int Device_Write_Property(void)
{
return 0; return 0;
} }
extern int Device_Reinitialize(void) { extern int Device_Reinitialize(void)
{
return 0; return 0;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
BACNET_ADDRESS src = { 0 }; BACNET_ADDRESS src = { 0 };
@@ -99,5 +115,4 @@ int main(int argc, char *argv[])
} }
return 0; return 0;
} }
+66 -42
View File
@@ -39,87 +39,111 @@
// Pull in all of this... // Pull in all of this...
#include "../router-mstp/main.c" #include "../router-mstp/main.c"
static void Init_Service_Handlers(void) { static void Init_Service_Handlers(void)
{
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast); apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, handler_read_range); SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device); apdu_set_confirmed_handler(
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc); SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); apdu_set_confirmed_handler(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, handler_device_communication_control); SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, handler_timesync);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service); apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
} }
/* /*
* FIXME: This is a hack to get things linking correctly * FIXME: This is a hack to get things linking correctly
*/ */
extern int cov_subscribe(void) { extern int cov_subscribe(void)
{
return 0; return 0;
} }
extern int Device_Value_List_Supported(void) { extern int Device_Value_List_Supported(void)
{
return 0; return 0;
} }
extern int Encode_RR_payload(void) { extern int Encode_RR_payload(void)
{
return 0; return 0;
} }
extern int Device_Objects_RR_Info(void) { extern int Device_Objects_RR_Info(void)
{
return 0; return 0;
} }
extern int Device_Write_Property(void) { extern int Device_Write_Property(void)
{
return 0; return 0;
} }
extern int Device_Reinitialize(void) { extern int Device_Reinitialize(void)
{
return 0; return 0;
} }
extern bool Device_COV(BACNET_OBJECT_TYPE object_type, uint32_t object_instance) { extern bool Device_COV(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
{
return false; return false;
} }
extern void Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance) { extern void
Device_COV_Clear(BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
{
return; return;
} }
extern bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type, extern bool Device_Encode_Value_List(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list) { BACNET_PROPERTY_VALUE *value_list)
{
return false;
}
extern int Device_Add_List_Element(BACNET_LIST_ELEMENT_DATA * list_element) {
return BACNET_STATUS_ERROR;
}
extern int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA * list_element) {
return BACNET_STATUS_ERROR;
}
extern bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data) {
return false; return false;
} }
int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { extern int Device_Add_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
{
return BACNET_STATUS_ERROR;
}
extern int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
{
return BACNET_STATUS_ERROR;
}
extern bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
{
return false;
}
int LLVMFuzzerTestOneInput(uint8_t *data, size_t size)
{
BACNET_ADDRESS src = { 0 }; BACNET_ADDRESS src = { 0 };
Init_Service_Handlers(); Init_Service_Handlers();
/* process fuzz input*/ /* process fuzz input*/
if (size>0 && size<=0xffff) { if (size > 0 && size <= 0xffff) {
my_routing_npdu_handler(BIP_Net, &src, data, (uint16_t)size); my_routing_npdu_handler(BIP_Net, &src, data, (uint16_t)size);
} }
return 0; return 0;
} }
+2 -2
View File
@@ -18,9 +18,9 @@
/* Device configuration definitions. */ /* Device configuration definitions. */
#define FIRST_DEVICE_NUMBER 260001 #define FIRST_DEVICE_NUMBER 260001
#define VIRTUAL_DNET 2709 /* your choice of number here */ #define VIRTUAL_DNET 2709 /* your choice of number here */
#define DEV_NAME_BASE "Gateway Demo Device" #define DEV_NAME_BASE "Gateway Demo Device"
#define DEV_DESCR_GATEWAY "Gateway Device and Router" #define DEV_DESCR_GATEWAY "Gateway Device and Router"
#define DEV_DESCR_REMOTE "Routed Remote Device" #define DEV_DESCR_REMOTE "Routed Remote Device"
#endif #endif
+9 -8
View File
@@ -188,7 +188,8 @@ static void Init_Service_Handlers(uint32_t first_object_instance)
apdu_set_unconfirmed_handler( apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
} }
@@ -225,16 +226,16 @@ int main(int argc, char *argv[])
if ((first_object_instance == 0) || if ((first_object_instance == 0) ||
(first_object_instance > BACNET_MAX_INSTANCE)) { (first_object_instance > BACNET_MAX_INSTANCE)) {
printf("Error: Invalid Object Instance %s \n", argv[1]); printf("Error: Invalid Object Instance %s \n", argv[1]);
printf( printf("Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE);
"Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE);
exit(1); exit(1);
} }
} }
printf("BACnet Router Demo\n" printf(
"BACnet Stack Version %s\n" "BACnet Router Demo\n"
"BACnet Device ID: %u\n" "BACnet Stack Version %s\n"
"Max APDU: %d\n" "BACnet Device ID: %u\n"
"Max Devices: %d\n", "Max APDU: %d\n"
"Max Devices: %d\n",
BACnet_Version, first_object_instance, MAX_APDU, MAX_NUM_DEVICES); BACnet_Version, first_object_instance, MAX_APDU, MAX_NUM_DEVICES);
Init_Service_Handlers(first_object_instance); Init_Service_Handlers(first_object_instance);
dlenv_init(); dlenv_init();
+25 -17
View File
@@ -54,14 +54,16 @@ static bool Recieved_Ack = false;
static bool More_Events = false; static bool More_Events = false;
static BACNET_OBJECT_ID LastReceivedObjectIdentifier; static BACNET_OBJECT_ID LastReceivedObjectIdentifier;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n", printf(
"BACnet Error: %s: %s\r\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -74,18 +76,20 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\r\n", printf(
"BACnet Abort: %s\r\n",
bactext_abort_reason_name((int)abort_reason)); bactext_abort_reason_name((int)abort_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\r\n", printf(
"BACnet Reject: %s\r\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -101,7 +105,8 @@ static void MyRejectHandler(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
static void My_Get_Event_Ack_Handler(uint8_t *service_request, static void My_Get_Event_Ack_Handler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -115,14 +120,16 @@ static void My_Get_Event_Ack_Handler(uint8_t *service_request,
data[i].next = &data[i + 1]; data[i].next = &data[i + 1];
} }
printf("Recieved Ack. Saved invoke ID was %i, service returned %i\n", printf(
"Recieved Ack. Saved invoke ID was %i, service returned %i\n",
Request_Invoke_ID, service_data->invoke_id); Request_Invoke_ID, service_data->invoke_id);
if (service_data->invoke_id == Request_Invoke_ID) { if (service_data->invoke_id == Request_Invoke_ID) {
len = getevent_ack_decode_service_request( len = getevent_ack_decode_service_request(
service_request, service_len, &data[0], &More_Events); service_request, service_len, &data[0], &More_Events);
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n", printf(
len, More_Events); "Decode of Ack returned length %i. MoreEvents flag was %i \n", len,
More_Events);
if (len > 0) { if (len > 0) {
ge_ack_print_data(&(data[0]), Target_Device_Object_Instance); ge_ack_print_data(&(data[0]), Target_Device_Object_Instance);
if (More_Events) { if (More_Events) {
@@ -162,13 +169,14 @@ static void Init_Service_Handlers(void)
static int print_help(const char *exe_name) static int print_help(const char *exe_name)
{ {
printf("Usage:\n" printf(
"\n" "Usage:\n"
"%s device-instance [--help]\n" "\n"
"\n" "%s device-instance [--help]\n"
" Send BACnet GetEventInformation service retruequest to given " "\n"
"device, and wait\n" " Send BACnet GetEventInformation service retruequest to given "
" for responses.\n\n", "device, and wait\n"
" for responses.\n\n",
exe_name); exe_name);
return 1; return 1;
} }
+31 -27
View File
@@ -50,8 +50,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -80,7 +80,8 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s [device-instance vendor-id max-apdu segmentation]\n", printf(
"Usage: %s [device-instance vendor-id max-apdu segmentation]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -90,47 +91,49 @@ static void print_help(const char *filename)
{ {
printf("Send BACnet I-Am message for a device.\n"); printf("Send BACnet I-Am message for a device.\n");
printf("--mac A\n" printf("--mac A\n"
"Optional BACnet mac address." "Optional BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf("--dnet N\n"
"Optional BACnet network number N for directed requests.\n" "Optional BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"Optional BACnet mac address on the destination BACnet network number.\n" "Optional BACnet mac address on the destination BACnet network "
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "number.\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--repeat\n" printf("--repeat\n"
"Send the message repeatedly until signalled to quit.\n" "Send the message repeatedly until signalled to quit.\n"
"Default is to not repeat, sending only a single message.\n"); "Default is to not repeat, sending only a single message.\n");
printf("\n"); printf("\n");
printf("--retry C\n" printf("--retry C\n"
"Send the message C number of times\n" "Send the message C number of times\n"
"Default is retry 0, only sending one time.\n"); "Default is retry 0, only sending one time.\n");
printf("\n"); printf("\n");
printf("--delay\n" printf("--delay\n"
"Delay, in milliseconds, between repeated messages.\n" "Delay, in milliseconds, between repeated messages.\n"
"Default delay is 100ms.\n"); "Default delay is 100ms.\n");
printf("\n"); printf("\n");
printf("device-instance:\n" printf("device-instance:\n"
"BACnet device-ID 0..4194303\n"); "BACnet device-ID 0..4194303\n");
printf("\n"); printf("\n");
printf("vendor-id:\n" printf("vendor-id:\n"
"Vendor Identifier 0..65535\n"); "Vendor Identifier 0..65535\n");
printf("\n"); printf("\n");
printf("max-apdu:\n" printf("max-apdu:\n"
"Maximum APDU size 50..65535\n"); "Maximum APDU size 50..65535\n");
printf("\n"); printf("\n");
printf("segmentation:\n" printf("segmentation:\n"
"BACnet Segmentation 0=both, 1=transmit, 2=receive, 3=none\n"); "BACnet Segmentation 0=both, 1=transmit, 2=receive, 3=none\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"Example:\n"
"To send an I-Am message of instance=1234 vendor-id=260 max-apdu=480\n" "To send an I-Am message of instance=1234 vendor-id=260 max-apdu=480\n"
"%s 1234 260 480\n", "%s 1234 260 480\n",
filename); filename);
@@ -258,8 +261,9 @@ int main(int argc, char *argv[])
atexit(datalink_cleanup); atexit(datalink_cleanup);
/* send the request */ /* send the request */
do { do {
Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU, Send_I_Am_To_Network(
Target_Segmentation, Target_Vendor_ID); &dest, Target_Device_ID, Target_Max_APDU, Target_Segmentation,
Target_Vendor_ID);
if (repeat_forever || retry_count) { if (repeat_forever || retry_count) {
/* returns 0 bytes on timeout */ /* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
+14 -12
View File
@@ -46,8 +46,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -83,15 +83,16 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Send BACnet I-Am-Router-To-Network message for \n" printf(
"one or more networks.\n" "Send BACnet I-Am-Router-To-Network message for \n"
"\nDNET:\n" "one or more networks.\n"
"BACnet destination network number 0-65534\n" "\nDNET:\n"
"To send a I-Am-Router-To-Network message for DNET 86:\n" "BACnet destination network number 0-65534\n"
"%s 86\n" "To send a I-Am-Router-To-Network message for DNET 86:\n"
"To send a I-Am-Router-To-Network message for multiple DNETs\n" "%s 86\n"
"use the following command:\n" "To send a I-Am-Router-To-Network message for multiple DNETs\n"
"%s 86 42 24 14\n", "use the following command:\n"
"%s 86 42 24 14\n",
filename, filename); filename, filename);
} }
@@ -136,7 +137,8 @@ int main(int argc, char *argv[])
Target_Router_Networks[arg_count] = -1; Target_Router_Networks[arg_count] = -1;
/* invalid DNET? */ /* invalid DNET? */
if (Target_Router_Networks[arg_count - 1] >= 65535) { if (Target_Router_Networks[arg_count - 1] >= 65535) {
fprintf(stderr, "DNET=%u - it must be less than %u\n", fprintf(
stderr, "DNET=%u - it must be less than %u\n",
Target_Router_Networks[arg_count - 1], 65535); Target_Router_Networks[arg_count - 1], 65535);
return 1; return 1;
} }
+20 -14
View File
@@ -59,8 +59,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -69,7 +69,8 @@ static void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void My_Router_Handler(BACNET_ADDRESS *src, static void My_Router_Handler(
BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, /* PDU data */ uint8_t *npdu, /* PDU data */
uint16_t npdu_len) uint16_t npdu_len)
@@ -157,7 +158,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
} }
} }
static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ static void My_NPDU_Handler(
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* length PDU */ { /* length PDU */
@@ -168,7 +170,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data); apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data);
if (npdu_data.network_layer_message) { if (npdu_data.network_layer_message) {
if (apdu_offset <= pdu_len) { if (apdu_offset <= pdu_len) {
My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], My_Router_Handler(
src, &npdu_data, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset)); (uint16_t)(pdu_len - apdu_offset));
} }
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
@@ -183,7 +186,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
if (dest.net) { if (dest.net) {
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net); debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
} else { } else {
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n", debug_printf(
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
npdu_data.protocol_version); npdu_data.protocol_version);
} }
} }
@@ -219,11 +223,11 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf( printf("Send BACnet Initialize-Routing-Table message to a network\n"
"Send BACnet Initialize-Routing-Table message to a network\n" "and wait for responses. Displays their network information.\n");
"and wait for responses. Displays their network information.\n");
printf("\n"); printf("\n");
printf("address:\n" printf(
"address:\n"
"MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\n" "MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\n"
"DNET ID Len Info:\n" "DNET ID Len Info:\n"
"Port-info data:\n" "Port-info data:\n"
@@ -247,8 +251,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
int index = 0; int index = 0;
if (argc > 0) { if (argc > 0) {
count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2], count = sscanf(
&mac[3], &port); argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2], &mac[3],
&port);
if (count == 5) { if (count == 5) {
dst->mac_len = 6; dst->mac_len = 6;
for (index = 0; index < 4; index++) { for (index = 0; index < 4; index++) {
@@ -256,8 +261,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
} }
encode_unsigned16(&dst->mac[4], port); encode_unsigned16(&dst->mac[4], port);
} else { } else {
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], count = sscanf(
&mac[2], &mac[3], &mac[4], &mac[5]); argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->mac_len = count; dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
+88 -77
View File
@@ -36,19 +36,19 @@
#define DLT_BACNET_MS_TP (165) #define DLT_BACNET_MS_TP (165)
/* local min/max macros */ /* local min/max macros */
#ifndef max #ifndef max
#define max(a,b) \ #define max(a, b) \
({ \ ({ \
__typeof__ (a) _a = (a); \ __typeof__(a) _a = (a); \
__typeof__ (b) _b = (b); \ __typeof__(b) _b = (b); \
_a > _b ? _a : _b; \ _a > _b ? _a : _b; \
}) })
#define min(a,b) \ #define min(a, b) \
({ \ ({ \
__typeof__ (a) _a = (a); \ __typeof__(a) _a = (a); \
__typeof__ (b) _b = (b); \ __typeof__(b) _b = (b); \
_a < _b ? _a : _b; \ _a < _b ? _a : _b; \
}) })
#endif #endif
#define MSTP_HEADER_MAX (2 + 1 + 1 + 1 + 2 + 1) #define MSTP_HEADER_MAX (2 + 1 + 1 + 1 + 2 + 1)
@@ -121,8 +121,8 @@ struct mstp_statistics {
static struct mstp_statistics MSTP_Statistics[MAX_MSTP_DEVICES]; static struct mstp_statistics MSTP_Statistics[MAX_MSTP_DEVICES];
static uint32_t Invalid_Frame_Count; static uint32_t Invalid_Frame_Count;
static uint32_t timeval_diff_ms( static uint32_t
const struct timeval *old, const struct timeval *now) timeval_diff_ms(const struct timeval *old, const struct timeval *now)
{ {
uint32_t ms = 0; uint32_t ms = 0;
@@ -133,8 +133,7 @@ static uint32_t timeval_diff_ms(
return ms; return ms;
} }
static void mstp_monitor_i_am( static void mstp_monitor_i_am(uint8_t mac, const uint8_t *pdu, uint16_t pdu_len)
uint8_t mac, const uint8_t *pdu, uint16_t pdu_len)
{ {
BACNET_ADDRESS src = { 0 }; BACNET_ADDRESS src = { 0 };
BACNET_ADDRESS dest = { 0 }; BACNET_ADDRESS dest = { 0 };
@@ -173,8 +172,7 @@ static void mstp_monitor_i_am(
} }
static void packet_statistics( static void packet_statistics(
const struct timeval *tv, const struct timeval *tv, const struct mstp_port_struct_t *mstp_port)
const struct mstp_port_struct_t *mstp_port)
{ {
static struct timeval old_tv = { 0 }; static struct timeval old_tv = { 0 };
static uint8_t old_frame = 255; static uint8_t old_frame = 255;
@@ -211,8 +209,8 @@ static void packet_statistics(
MSTP_Statistics[src].token_reply = delta; MSTP_Statistics[src].token_reply = delta;
} }
} }
} else if ((old_frame == FRAME_TYPE_POLL_FOR_MASTER) && } else if (
(old_src == src)) { (old_frame == FRAME_TYPE_POLL_FOR_MASTER) && (old_src == src)) {
/* Tusage_timeout */ /* Tusage_timeout */
delta = timeval_diff_ms(&old_tv, tv); delta = timeval_diff_ms(&old_tv, tv);
if (delta > MSTP_Statistics[src].tusage_timeout) { if (delta > MSTP_Statistics[src].tusage_timeout) {
@@ -314,7 +312,8 @@ static void packet_statistics_print(void)
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, "==== MS/TP Frame Counts ====\n"); fprintf(stdout, "==== MS/TP Frame Counts ====\n");
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device", fprintf(
stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device",
"Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq", "TestRsp"); "Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq", "TestRsp");
fprintf(stdout, "\n"); fprintf(stdout, "\n");
for (i = 0; i < MAX_MSTP_DEVICES; i++) { for (i = 0; i < MAX_MSTP_DEVICES; i++) {
@@ -324,17 +323,20 @@ static void packet_statistics_print(void)
node_count++; node_count++;
fprintf(stdout, "%-8u", i); fprintf(stdout, "%-8u", i);
if (MSTP_Statistics[i].device_id <= 4194303) { if (MSTP_Statistics[i].device_id <= 4194303) {
fprintf(stdout, "%-8lu", fprintf(
stdout, "%-8lu",
(long unsigned int)MSTP_Statistics[i].device_id); (long unsigned int)MSTP_Statistics[i].device_id);
} else { } else {
fprintf(stdout, "%-8s", "-"); fprintf(stdout, "%-8s", "-");
} }
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu", fprintf(
stdout, "%-8lu%-8lu%-8lu%-8lu",
(long unsigned int)MSTP_Statistics[i].token_count, (long unsigned int)MSTP_Statistics[i].token_count,
(long unsigned int)MSTP_Statistics[i].pfm_count, (long unsigned int)MSTP_Statistics[i].pfm_count,
(long unsigned int)MSTP_Statistics[i].rpfm_count, (long unsigned int)MSTP_Statistics[i].rpfm_count,
(long unsigned int)MSTP_Statistics[i].der_count); (long unsigned int)MSTP_Statistics[i].der_count);
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu", fprintf(
stdout, "%-8lu%-8lu%-8lu%-7lu",
(long unsigned int)MSTP_Statistics[i].reply_postponed_count, (long unsigned int)MSTP_Statistics[i].reply_postponed_count,
(long unsigned int)MSTP_Statistics[i].dner_count, (long unsigned int)MSTP_Statistics[i].dner_count,
(long unsigned int)MSTP_Statistics[i].test_request_count, (long unsigned int)MSTP_Statistics[i].test_request_count,
@@ -346,9 +348,10 @@ static void packet_statistics_print(void)
node_count = 0; node_count = 0;
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n"); fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n");
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", fprintf(
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm", stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "MaxMstr",
"Tder", "Tpostpd"); "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm", "Tder",
"Tpostpd");
fprintf(stdout, "\n"); fprintf(stdout, "\n");
for (i = 0; i < MAX_MSTP_DEVICES; i++) { for (i = 0; i < MAX_MSTP_DEVICES; i++) {
/* check for masters or slaves */ /* check for masters or slaves */
@@ -358,12 +361,14 @@ static void packet_statistics_print(void)
self_or_ooo_count = MSTP_Statistics[i].self_token_count + self_or_ooo_count = MSTP_Statistics[i].self_token_count +
MSTP_Statistics[i].ooo_token_count; MSTP_Statistics[i].ooo_token_count;
fprintf(stdout, "%-8u", i); fprintf(stdout, "%-8u", i);
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu", fprintf(
stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu",
(long unsigned int)MSTP_Statistics[i].max_master, (long unsigned int)MSTP_Statistics[i].max_master,
(long unsigned int)MSTP_Statistics[i].token_retries, (long unsigned int)MSTP_Statistics[i].token_retries,
(long unsigned int)MSTP_Statistics[i].npoll, self_or_ooo_count, (long unsigned int)MSTP_Statistics[i].npoll, self_or_ooo_count,
(long unsigned int)MSTP_Statistics[i].token_reply); (long unsigned int)MSTP_Statistics[i].token_reply);
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu", fprintf(
stdout, "%-8lu%-8lu%-8lu%-7lu",
(long unsigned int)MSTP_Statistics[i].tusage_timeout, (long unsigned int)MSTP_Statistics[i].tusage_timeout,
(long unsigned int)MSTP_Statistics[i].pfm_reply, (long unsigned int)MSTP_Statistics[i].pfm_reply,
(long unsigned int)MSTP_Statistics[i].der_reply, (long unsigned int)MSTP_Statistics[i].der_reply,
@@ -372,7 +377,8 @@ static void packet_statistics_print(void)
} }
} }
fprintf(stdout, "Node Count: %u\n", node_count); fprintf(stdout, "Node Count: %u\n", node_count);
fprintf(stdout, "Invalid Frame Count: %lu\n", fprintf(
stdout, "Invalid Frame Count: %lu\n",
(long unsigned int)Invalid_Frame_Count); (long unsigned int)Invalid_Frame_Count);
fflush(stdout); fflush(stdout);
} }
@@ -410,8 +416,7 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
/* for the MS/TP state machine to use for getting data to send */ /* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */ /* Return: amount of PDU data */
uint16_t MSTP_Get_Send( uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
(void)timeout; (void)timeout;
@@ -426,7 +431,7 @@ uint16_t MSTP_Get_Send(
*/ */
void MSTP_Send_Frame( void MSTP_Send_Frame(
struct mstp_port_struct_t *mstp_port, struct mstp_port_struct_t *mstp_port,
const uint8_t * buffer, const uint8_t *buffer,
uint16_t nbytes) uint16_t nbytes)
{ {
(void)mstp_port; (void)mstp_port;
@@ -434,8 +439,7 @@ void MSTP_Send_Frame(
(void)nbytes; (void)nbytes;
} }
uint16_t MSTP_Get_Reply( uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
(void)timeout; (void)timeout;
@@ -454,8 +458,9 @@ static void named_pipe_create(const char *pipe_name)
/* create the pipe */ /* create the pipe */
while (Pipe_Handle == INVALID_HANDLE_VALUE) { while (Pipe_Handle == INVALID_HANDLE_VALUE) {
/* use CreateFile rather than CreateNamedPipe */ /* use CreateFile rather than CreateNamedPipe */
Pipe_Handle = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, Pipe_Handle = CreateFile(
OPEN_EXISTING, 0, NULL); pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0,
NULL);
if (Pipe_Handle != INVALID_HANDLE_VALUE) { if (Pipe_Handle != INVALID_HANDLE_VALUE) {
break; break;
} }
@@ -477,7 +482,8 @@ static size_t data_write(const void *ptr, size_t size, size_t nitems)
DWORD cbWritten = 0; DWORD cbWritten = 0;
if (Pipe_Handle != INVALID_HANDLE_VALUE) { if (Pipe_Handle != INVALID_HANDLE_VALUE) {
(void)WriteFile(Pipe_Handle, /* handle to pipe */ (void)WriteFile(
Pipe_Handle, /* handle to pipe */
ptr, /* buffer to write from */ ptr, /* buffer to write from */
size * nitems, /* number of bytes to write */ size * nitems, /* number of bytes to write */
&cbWritten, /* number of bytes written */ &cbWritten, /* number of bytes written */
@@ -492,13 +498,13 @@ static size_t data_write(const void *ptr, size_t size, size_t nitems)
return written; return written;
} }
static size_t data_write_header( static size_t data_write_header(const void *ptr, size_t size, size_t nitems)
const void *ptr, size_t size, size_t nitems)
{ {
size_t written = 0; size_t written = 0;
DWORD cbWritten = 0; DWORD cbWritten = 0;
if (Pipe_Handle != INVALID_HANDLE_VALUE) { if (Pipe_Handle != INVALID_HANDLE_VALUE) {
(void)WriteFile(Pipe_Handle, /* handle to pipe */ (void)WriteFile(
Pipe_Handle, /* handle to pipe */
ptr, /* buffer to write from */ ptr, /* buffer to write from */
size * nitems, /* number of bytes to write */ size * nitems, /* number of bytes to write */
&cbWritten, /* number of bytes written */ &cbWritten, /* number of bytes written */
@@ -542,8 +548,7 @@ static size_t data_write(const void *ptr, size_t size, size_t nitems)
return written; return written;
} }
static size_t data_write_header( static size_t data_write_header(const void *ptr, size_t size, size_t nitems)
const void *ptr, size_t size, size_t nitems)
{ {
ssize_t written = 0; ssize_t written = 0;
@@ -573,14 +578,16 @@ static void filename_create_new(void)
} }
File_Handle = NULL; File_Handle = NULL;
datetime_local(&bdate, &btime, NULL, NULL); datetime_local(&bdate, &btime, NULL, NULL);
snprintf(filename, filename_size, "mstp_%04d%02d%02d%02d%02d%02d.cap", snprintf(
filename, filename_size, "mstp_%04d%02d%02d%02d%02d%02d.cap",
(int)bdate.year, (int)bdate.month, (int)bdate.day, (int)btime.hour, (int)bdate.year, (int)bdate.month, (int)bdate.day, (int)btime.hour,
(int)btime.min, (int)btime.sec); (int)btime.min, (int)btime.sec);
File_Handle = fopen(filename, "wb"); File_Handle = fopen(filename, "wb");
if (File_Handle) { if (File_Handle) {
fprintf(stdout, "mstpcap: saving capture to %s\n", filename); fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
} else { } else {
fprintf(stderr, "mstpcap: failed to open %s: %s\n", filename, fprintf(
stderr, "mstpcap: failed to open %s: %s\n", filename,
strerror(errno)); strerror(errno));
} }
} }
@@ -597,12 +604,9 @@ static void write_global_header(void)
uint32_t network = DLT_BACNET_MS_TP; /* data link type - BACNET_MS_TP */ uint32_t network = DLT_BACNET_MS_TP; /* data link type - BACNET_MS_TP */
/* create a new file. */ /* create a new file. */
(void)data_write_header( (void)data_write_header(&magic_number, sizeof(magic_number), 1);
&magic_number, sizeof(magic_number), 1); (void)data_write_header(&version_major, sizeof(version_major), 1);
(void)data_write_header( (void)data_write_header(&version_minor, sizeof(version_minor), 1);
&version_major, sizeof(version_major), 1);
(void)data_write_header(
&version_minor, sizeof(version_minor), 1);
(void)data_write_header(&thiszone, sizeof(thiszone), 1); (void)data_write_header(&thiszone, sizeof(thiszone), 1);
(void)data_write_header(&sigfigs, sizeof(sigfigs), 1); (void)data_write_header(&sigfigs, sizeof(sigfigs), 1);
(void)data_write_header(&snaplen, sizeof(snaplen), 1); (void)data_write_header(&snaplen, sizeof(snaplen), 1);
@@ -610,8 +614,8 @@ static void write_global_header(void)
fflush(File_Handle); fflush(File_Handle);
} }
static void write_received_packet( static void
struct mstp_port_struct_t *mstp_port, size_t header_len) write_received_packet(struct mstp_port_struct_t *mstp_port, size_t header_len)
{ {
uint32_t ts_sec = 0; /* timestamp seconds */ uint32_t ts_sec = 0; /* timestamp seconds */
uint32_t ts_usec = 0; /* timestamp microseconds */ uint32_t ts_usec = 0; /* timestamp microseconds */
@@ -646,8 +650,7 @@ static void write_received_packet(
} }
} else { } else {
if (mstp_port->DataLength) { if (mstp_port->DataLength) {
max_data = max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength);
min(mstp_port->InputBufferSize, mstp_port->DataLength);
incl_len = orig_len = header_len + max_data + data_crc_len; incl_len = orig_len = header_len + max_data + data_crc_len;
} else { } else {
/* header only - or at least some bytes of the header */ /* header only - or at least some bytes of the header */
@@ -744,7 +747,8 @@ static bool test_global_header(const char *filename)
return false; return false;
} }
} else { } else {
fprintf(stderr, "mstpcap[scan]: failed to open %s: %s\n", filename, fprintf(
stderr, "mstpcap[scan]: failed to open %s: %s\n", filename,
strerror(errno)); strerror(errno));
return false; return false;
} }
@@ -819,20 +823,22 @@ static bool read_received_packet(struct mstp_port_struct_t *mstp_port)
if (orig_len > 8) { if (orig_len > 8) {
/* packet includes data */ /* packet includes data */
mstp_port->DataLength = orig_len - 8 - 2; mstp_port->DataLength = orig_len - 8 - 2;
count = fread(
mstp_port->InputBuffer, mstp_port->DataLength, 1, File_Handle);
if (count != 1) {
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = count =
fread(mstp_port->InputBuffer, mstp_port->DataLength, 1, File_Handle); fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, File_Handle);
if (count != 1) { if (count != 1) {
fclose(File_Handle); fclose(File_Handle);
File_Handle = NULL; File_Handle = NULL;
return false; return false;
} }
count = fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, File_Handle); count =
if (count != 1) { fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, File_Handle);
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, File_Handle);
if (count != 1) { if (count != 1) {
fclose(File_Handle); fclose(File_Handle);
File_Handle = NULL; File_Handle = NULL;
@@ -930,14 +936,15 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("%s --scan <filename>\n" printf(
"perform statistic analysis on MS/TP capture file.\n", "%s --scan <filename>\n"
"perform statistic analysis on MS/TP capture file.\n",
filename); filename);
printf("\n"); printf("\n");
printf("Captures MS/TP packets from a serial interface\n" printf("Captures MS/TP packets from a serial interface\n"
"and writes them to a file or a pipe, or scans a file for stats." "and writes them to a file or a pipe, or scans a file for stats."
"Filename is of the form mstp_20090123091200.cap (timestamp).\n" "Filename is of the form mstp_20090123091200.cap (timestamp).\n"
"New files are created after receiving 65535 packets.\n"); "New files are created after receiving 65535 packets.\n");
printf("\n"); printf("\n");
printf("Command line options:\n" printf("Command line options:\n"
"[--extcap-interface port] - serial interface.\n" "[--extcap-interface port] - serial interface.\n"
@@ -957,10 +964,11 @@ static void print_help(const char *filename)
#endif #endif
" Use that name as the interface name in Wireshark.\n"); " Use that name as the interface name in Wireshark.\n");
printf("\n"); printf("\n");
printf("%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n" printf(
"[--capture][--baud baud][--fifo pipe]\n" "%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n"
"[--extcap-interface iface]\n" "[--capture][--baud baud][--fifo pipe]\n"
"Usage from Wireshark ExtCap interface\n", "[--extcap-interface iface]\n"
"Usage from Wireshark ExtCap interface\n",
filename); filename);
} }
@@ -1053,8 +1061,9 @@ int main(int argc, char *argv[])
printf("An interface must be provided.\n"); printf("An interface must be provided.\n");
return 0; return 0;
} }
printf("dlt {number=%u}{name=BACnet MS/TP}" printf(
"{display=BACnet MS/TP}\n", "dlt {number=%u}{name=BACnet MS/TP}"
"{display=BACnet MS/TP}\n",
DLT_BACNET_MS_TP); DLT_BACNET_MS_TP);
Exit_Requested = true; Exit_Requested = true;
} }
@@ -1137,7 +1146,8 @@ int main(int argc, char *argv[])
RS485_Initialize(); RS485_Initialize();
mstimer_init(); mstimer_init();
if (!Wireshark_Capture) { if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n", fprintf(
stdout, "mstpcap: Using %s for capture at %ld bps.\n",
RS485_Interface(), (long)RS485_Get_Baud_Rate()); RS485_Interface(), (long)RS485_Get_Baud_Rate());
} }
#if defined(_WIN32) #if defined(_WIN32)
@@ -1194,7 +1204,8 @@ int main(int argc, char *argv[])
} }
if (!Wireshark_Capture) { if (!Wireshark_Capture) {
if (!(packet_count % 100)) { if (!(packet_count % 100)) {
fprintf(stdout, "\r%u packets, %u invalid frames", fprintf(
stdout, "\r%u packets, %u invalid frames",
(unsigned)packet_count, (unsigned)Invalid_Frame_Count); (unsigned)packet_count, (unsigned)Invalid_Frame_Count);
fflush(stdout); fflush(stdout);
} }
+6 -3
View File
@@ -135,7 +135,8 @@ static void filename_create(char *filename, size_t filesize)
if (filename) { if (filename) {
my_time = time(NULL); my_time = time(NULL);
today = localtime(&my_time); today = localtime(&my_time);
snprintf(filename, filesize, "mstp_%04d%02d%02d%02d%02d%02d.cap", snprintf(
filename, filesize, "mstp_%04d%02d%02d%02d%02d%02d.cap",
1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday, 1900 + today->tm_year, 1 + today->tm_mon, today->tm_mday,
today->tm_hour, today->tm_min, today->tm_sec); today->tm_hour, today->tm_min, today->tm_sec);
} }
@@ -165,7 +166,8 @@ static void write_global_header(const char *filename)
fflush(pFile); fflush(pFile);
fprintf(stdout, "mstpcap: saving capture to %s\n", filename); fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
} else { } else {
fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename, fprintf(
stderr, "mstpcap[header]: failed to open %s: %s\n", filename,
strerror(errno)); strerror(errno));
} }
} }
@@ -189,7 +191,8 @@ static void write_received_packet(uint8_t *buffer, unsigned length)
(void)fwrite(&orig_len, sizeof(orig_len), 1, pFile); (void)fwrite(&orig_len, sizeof(orig_len), 1, pFile);
(void)fwrite(buffer, length, 1, pFile); (void)fwrite(buffer, length, 1, pFile);
} else { } else {
fprintf(stderr, "mstpcrc[packet]: failed to open %s: %s\n", fprintf(
stderr, "mstpcrc[packet]: failed to open %s: %s\n",
Capture_Filename, strerror(errno)); Capture_Filename, strerror(errno));
} }
} }
+42 -31
View File
@@ -63,8 +63,8 @@ static void MyAbortHandler(
* @param invoke_id [in] the invokeID from the rejected message * @param invoke_id [in] the invokeID from the rejected message
* @param reject_reason [in] the reason for the rejection * @param reject_reason [in] the reason for the rejection
*/ */
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -79,7 +79,8 @@ static void MyRejectHandler(
* @param npdu - NPDU data * @param npdu - NPDU data
* @param npdu_len - NPDU data length * @param npdu_len - NPDU data length
*/ */
static void My_Router_Handler(BACNET_ADDRESS *src, static void My_Router_Handler(
BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, uint8_t *npdu,
uint16_t npdu_len) uint16_t npdu_len)
@@ -120,7 +121,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
that are sent with a local unicast address. */ that are sent with a local unicast address. */
if (npdu_len >= 2) { if (npdu_len >= 2) {
len += decode_unsigned16(npdu, &dnet); len += decode_unsigned16(npdu, &dnet);
printf(": network number = %u. SNET=%u\n", (unsigned)dnet, printf(
": network number = %u. SNET=%u\n", (unsigned)dnet,
(unsigned)src->net); (unsigned)src->net);
} else { } else {
printf(": network number = missing! SNET=%u\n", src->net); printf(": network number = missing! SNET=%u\n", src->net);
@@ -142,7 +144,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
} }
} }
static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ static void My_NPDU_Handler(
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* length PDU */ { /* length PDU */
@@ -152,7 +155,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data); apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data);
if (npdu_data.network_layer_message) { if (npdu_data.network_layer_message) {
My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], My_Router_Handler(
src, &npdu_data, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset)); (uint16_t)(pdu_len - apdu_offset));
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
@@ -166,7 +170,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
if (dest.net) { if (dest.net) {
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net); debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
} else { } else {
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n", debug_printf(
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
npdu_data.protocol_version); npdu_data.protocol_version);
} }
} }
@@ -202,8 +207,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
int index = 0; int index = 0;
if (argc > 0) { if (argc > 0) {
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], count = sscanf(
&mac[3], &mac[4], &mac[5]); argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3],
&mac[4], &mac[5]);
dst->mac_len = count; dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -219,8 +225,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
} }
if (dnet) { if (dnet) {
if (argc > 2) { if (argc > 2) {
count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], count = sscanf(
&mac[2], &mac[3], &mac[4], &mac[5]); argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->len = count; dst->len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -257,23 +264,24 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet What-Is-Network-Number message to a network.\r\n" printf(
"\r\n" "Send BACnet What-Is-Network-Number message to a network.\r\n"
"DNET:\r\n" "\r\n"
"BACnet destination network number 0-65535\r\n" "DNET:\r\n"
"To omit the BACnet destination network number, use -1.\r\n" "BACnet destination network number 0-65535\r\n"
"Network Number Status:\r\n" "To omit the BACnet destination network number, use -1.\r\n"
"0=learned\r\n" "Network Number Status:\r\n"
"1=configured\r\n" "0=learned\r\n"
"MAC:\r\n" "1=configured\r\n"
"Optional MAC address of router for unicast message\r\n" "MAC:\r\n"
"Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n" "Optional MAC address of router for unicast message\r\n"
"Use hexidecimal MAC addresses.\r\n" "Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n"
"\r\n" "Use hexidecimal MAC addresses.\r\n"
"To send a What-Is-Network-Number request to DNET 86:\r\n" "\r\n"
"%s 86\r\n" "To send a What-Is-Network-Number request to DNET 86:\r\n"
"To send a What-Is-Network-Number request to all devices:\r\n" "%s 86\r\n"
"%s -1\r\n", "To send a What-Is-Network-Number request to all devices:\r\n"
"%s -1\r\n",
filename_remove_path(argv[0]), filename_remove_path(argv[0])); filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0; return 0;
} }
@@ -281,7 +289,8 @@ int main(int argc, char *argv[])
if (argc > 1) { if (argc > 1) {
Target_Network_Number = strtol(argv[1], NULL, 0); Target_Network_Number = strtol(argv[1], NULL, 0);
if (Target_Network_Number > UINT16_MAX) { if (Target_Network_Number > UINT16_MAX) {
fprintf(stderr, "DNET=%d - it must be 0 to 65535\r\n", fprintf(
stderr, "DNET=%d - it must be 0 to 65535\r\n",
Target_Network_Number); Target_Network_Number);
return 1; return 1;
} }
@@ -289,7 +298,8 @@ int main(int argc, char *argv[])
if (argc > 2) { if (argc > 2) {
Target_Network_Number_Status = strtol(argv[2], NULL, 0); Target_Network_Number_Status = strtol(argv[2], NULL, 0);
if (Target_Network_Number_Status > UINT8_MAX) { if (Target_Network_Number_Status > UINT8_MAX) {
fprintf(stderr, "status=%d - it must be 0 to 255\r\n", fprintf(
stderr, "status=%d - it must be 0 to 255\r\n",
Target_Network_Number_Status); Target_Network_Number_Status);
return 1; return 1;
} }
@@ -309,7 +319,8 @@ int main(int argc, char *argv[])
last_seconds = time(NULL); last_seconds = time(NULL);
timeout_seconds = apdu_timeout() / 1000; timeout_seconds = apdu_timeout() / 1000;
/* send the request */ /* send the request */
Send_Network_Number_Is(&Target_Router_Address, Target_Network_Number, Send_Network_Number_Is(
&Target_Router_Address, Target_Network_Number,
Target_Network_Number_Status); Target_Network_Number_Status);
/* loop forever */ /* loop forever */
for (;;) { for (;;) {
+58 -35
View File
@@ -66,25 +66,28 @@ static void MyAbortHandler(
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
char msg[MAX_ERROR_STRING]; char msg[MAX_ERROR_STRING];
snprintf(msg, sizeof(msg), "BACnet Abort: %s", snprintf(
msg, sizeof(msg), "BACnet Abort: %s",
bactext_abort_reason_name((int)abort_reason)); bactext_abort_reason_name((int)abort_reason));
LogError(msg); LogError(msg);
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
char msg[MAX_ERROR_STRING]; char msg[MAX_ERROR_STRING];
snprintf(msg, sizeof(msg), "BACnet Reject: %s", snprintf(
msg, sizeof(msg), "BACnet Reject: %s",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
LogError(msg); LogError(msg);
} }
} }
static void My_Error_Handler(BACNET_ADDRESS *src, static void My_Error_Handler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -92,7 +95,8 @@ static void My_Error_Handler(BACNET_ADDRESS *src,
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
char msg[MAX_ERROR_STRING]; char msg[MAX_ERROR_STRING];
snprintf(msg, sizeof(msg), "BACnet Error: %s: %s", snprintf(
msg, sizeof(msg), "BACnet Error: %s: %s",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
LogError(msg); LogError(msg);
@@ -138,8 +142,9 @@ void rp_ack_extract_data(BACNET_READ_PROPERTY_DATA *data)
object_value.object_property = data->object_property; object_value.object_property = data->object_property;
object_value.array_index = data->array_index; object_value.array_index = data->array_index;
object_value.value = &value; object_value.value = &value;
bacapp_snprintf_value(pAckString, bacapp_snprintf_value(
MAX_ACK_STRING - (pAckString - ackString), &object_value); pAckString, MAX_ACK_STRING - (pAckString - ackString),
&object_value);
if (len > 0) { if (len > 0) {
if (len < application_data_len) { if (len < application_data_len) {
application_data += len; application_data += len;
@@ -195,8 +200,8 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data)
object_value.array_index = object_value.array_index =
listOfProperties->propertyArrayIndex; listOfProperties->propertyArrayIndex;
object_value.value = value; object_value.value = value;
bacapp_snprintf_value(pAckString, bacapp_snprintf_value(
MAX_ACK_STRING - (pAckString - ackString), pAckString, MAX_ACK_STRING - (pAckString - ackString),
&object_value); &object_value);
if (value->next) { if (value->next) {
strncat(pAckString, ",", 1); strncat(pAckString, ",", 1);
@@ -211,7 +216,8 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data)
} }
} else { } else {
/* AccessError */ /* AccessError */
snprintf(ackString, sizeof(ackString), "BACnet Error: %s: %s", snprintf(
ackString, sizeof(ackString), "BACnet Error: %s: %s",
bactext_error_class_name( bactext_error_class_name(
(int)listOfProperties->error.error_class), (int)listOfProperties->error.error_class),
bactext_error_code_name( bactext_error_code_name(
@@ -231,7 +237,8 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data)
} }
} }
static void AtomicReadFileAckHandler(uint8_t *service_request, static void AtomicReadFileAckHandler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -251,7 +258,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
uint8_t *pFileData; uint8_t *pFileData;
int i; int i;
snprintf(msg, sizeof(msg), "EOF=%d,start=%d,", data.endOfFile, snprintf(
msg, sizeof(msg), "EOF=%d,start=%d,", data.endOfFile,
data.type.stream.fileStartPosition); data.type.stream.fileStartPosition);
__LogAnswer(msg, 0); __LogAnswer(msg, 0);
@@ -279,7 +287,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
static void My_Read_Property_Ack_Handler(uint8_t *service_request, static void My_Read_Property_Ack_Handler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -308,7 +317,8 @@ static void My_Read_Property_Ack_Handler(uint8_t *service_request,
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
static void My_Read_Property_Multiple_Ack_Handler(uint8_t *service_request, static void My_Read_Property_Multiple_Ack_Handler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -447,8 +457,9 @@ static void Wait_For_Answer_Or_Timeout(unsigned timeout_ms, waitAction action)
break; break;
} }
} else if (action == waitBind) { } else if (action == waitBind) {
if (address_bind_request(Target_Device_Object_Instance, if (address_bind_request(
&Target_Max_APDU, &Target_Address)) { Target_Device_Object_Instance, &Target_Max_APDU,
&Target_Address)) {
break; break;
} }
} else { } else {
@@ -507,7 +518,8 @@ int BacnetBindToDevice(int deviceInstanceNumber)
/****************************************************/ /****************************************************/
/* This is the interface to ReadProperty */ /* This is the interface to ReadProperty */
/****************************************************/ /****************************************************/
int BacnetReadProperty(int deviceInstanceNumber, int BacnetReadProperty(
int deviceInstanceNumber,
int objectType, int objectType,
int objectInstanceNumber, int objectInstanceNumber,
int objectProperty, int objectProperty,
@@ -526,8 +538,9 @@ int BacnetReadProperty(int deviceInstanceNumber,
isReadPropertyHandlerRegistered = true; isReadPropertyHandlerRegistered = true;
} }
/* Send the message out */ /* Send the message out */
Request_Invoke_ID = Send_Read_Property_Request(deviceInstanceNumber, Request_Invoke_ID = Send_Read_Property_Request(
objectType, objectInstanceNumber, objectProperty, objectIndex); deviceInstanceNumber, objectType, objectInstanceNumber, objectProperty,
objectIndex);
Wait_For_Answer_Or_Timeout(100, waitAnswer); Wait_For_Answer_Or_Timeout(100, waitAnswer);
int isFailure = Error_Detected; int isFailure = Error_Detected;
@@ -622,7 +635,8 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
if (!isReadPropertyMultipleHandlerRegistered) { if (!isReadPropertyMultipleHandlerRegistered) {
/* handle the data coming back from confirmed requests */ /* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, apdu_set_confirmed_ack_handler(
SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
My_Read_Property_Multiple_Ack_Handler); My_Read_Property_Multiple_Ack_Handler);
/* handle any errors coming back */ /* handle any errors coming back */
@@ -665,7 +679,8 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
/****************************************************/ /****************************************************/
/* This is the interface to WriteProperty */ /* This is the interface to WriteProperty */
/****************************************************/ /****************************************************/
int BacnetWriteProperty(int deviceInstanceNumber, int BacnetWriteProperty(
int deviceInstanceNumber,
int objectType, int objectType,
int objectInstanceNumber, int objectInstanceNumber,
int objectProperty, int objectProperty,
@@ -679,7 +694,8 @@ int BacnetWriteProperty(int deviceInstanceNumber,
if (!isWritePropertyHandlerRegistered) { if (!isWritePropertyHandlerRegistered) {
/* handle the ack coming back */ /* handle the ack coming back */
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, apdu_set_confirmed_simple_ack_handler(
SERVICE_CONFIRMED_WRITE_PROPERTY,
My_Write_Property_SimpleAck_Handler); My_Write_Property_SimpleAck_Handler);
/* handle any errors coming back */ /* handle any errors coming back */
@@ -710,7 +726,8 @@ int BacnetWriteProperty(int deviceInstanceNumber,
property_tag = strtol(tag, NULL, 0); property_tag = strtol(tag, NULL, 0);
if (property_tag >= MAX_BACNET_APPLICATION_TAG) { if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
snprintf(msg, sizeof(msg), "Error: tag=%u - it must be less than %u", snprintf(
msg, sizeof(msg), "Error: tag=%u - it must be less than %u",
property_tag, MAX_BACNET_APPLICATION_TAG); property_tag, MAX_BACNET_APPLICATION_TAG);
LogError(msg); LogError(msg);
break; break;
@@ -724,9 +741,9 @@ int BacnetWriteProperty(int deviceInstanceNumber,
propertyValue.next = NULL; propertyValue.next = NULL;
/* Send out the message */ /* Send out the message */
Request_Invoke_ID = Send_Write_Property_Request(deviceInstanceNumber, Request_Invoke_ID = Send_Write_Property_Request(
objectType, objectInstanceNumber, objectProperty, &propertyValue, deviceInstanceNumber, objectType, objectInstanceNumber,
objectPriority, objectIndex); objectProperty, &propertyValue, objectPriority, objectIndex);
Wait_For_Answer_Or_Timeout(100, waitAnswer); Wait_For_Answer_Or_Timeout(100, waitAnswer);
/* If we get here, then there were no explicit failures. However, there /* If we get here, then there were no explicit failures. However, there
@@ -740,7 +757,8 @@ int BacnetWriteProperty(int deviceInstanceNumber,
return isFailure; return isFailure;
} }
int BacnetAtomicWriteFile(int deviceInstanceNumber, int BacnetAtomicWriteFile(
int deviceInstanceNumber,
int fileInstanceNumber, int fileInstanceNumber,
int blockStartAddr, int blockStartAddr,
int blockNumBytes, int blockNumBytes,
@@ -778,8 +796,9 @@ int BacnetAtomicWriteFile(int deviceInstanceNumber,
/* Send out the message and wait for answer */ /* Send out the message and wait for answer */
if (!Error_Detected) { if (!Error_Detected) {
Request_Invoke_ID = Send_Atomic_Write_File_Stream(deviceInstanceNumber, Request_Invoke_ID = Send_Atomic_Write_File_Stream(
fileInstanceNumber, blockStartAddr, &fileData); deviceInstanceNumber, fileInstanceNumber, blockStartAddr,
&fileData);
Wait_For_Answer_Or_Timeout(100, waitAnswer); Wait_For_Answer_Or_Timeout(100, waitAnswer);
} }
@@ -816,7 +835,8 @@ int BacnetGetMaxApdu()
return requestedOctetCount; return requestedOctetCount;
} }
int BacnetTimeSync(int deviceInstanceNumber, int BacnetTimeSync(
int deviceInstanceNumber,
int year, int year,
int month, int month,
int day, int day,
@@ -871,8 +891,9 @@ int BacnetTimeSync(int deviceInstanceNumber,
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &Target_Address, pdu_len = npdu_encode_pdu(
&my_address, &npdu_data); &Handler_Transmit_Buffer[0], &Target_Address, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = timesync_encode_apdu( len = timesync_encode_apdu(
@@ -884,7 +905,8 @@ int BacnetTimeSync(int deviceInstanceNumber,
&Target_Address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); &Target_Address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
char msg[64]; char msg[64];
snprintf(msg, sizeof(msg), snprintf(
msg, sizeof(msg),
"Failed to Send Time-Synchronization Request (%s)!", "Failed to Send Time-Synchronization Request (%s)!",
strerror(errno)); strerror(errno));
LogError(msg); LogError(msg);
@@ -902,7 +924,8 @@ int BacnetTimeSync(int deviceInstanceNumber,
/****************************************************/ /****************************************************/
/* This is the interface to AtomicReadFile */ /* This is the interface to AtomicReadFile */
/****************************************************/ /****************************************************/
int BacnetAtomicReadFile(int deviceInstanceNumber, int BacnetAtomicReadFile(
int deviceInstanceNumber,
int fileInstanceNumber, int fileInstanceNumber,
int startOffset, int startOffset,
int numBytes) int numBytes)
+187 -88
View File
@@ -41,62 +41,128 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
static object_functions_t *Object_Table; static object_functions_t *Object_Table;
static object_functions_t My_Object_Table[] = { static object_functions_t My_Object_Table[] = {
{ OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */, { OBJECT_DEVICE,
Device_Count, Device_Index_To_Instance, NULL /* Init - don't init Device or it will recourse! */,
Device_Valid_Object_Instance_Number, Device_Object_Name, Device_Count,
Device_Read_Property_Local, Device_Write_Property_Local, Device_Index_To_Instance,
Device_Property_Lists, DeviceGetRRInfo, NULL /* Iterator */, Device_Valid_Object_Instance_Number,
NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */, Device_Object_Name,
NULL /* Intrinsic Reporting */, NULL /* Add_List_Element */, Device_Read_Property_Local,
NULL /* Remove_List_Element */, NULL /* Create */, NULL /* Delete */, Device_Write_Property_Local,
NULL /* Timer */ }, Device_Property_Lists,
DeviceGetRRInfo,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ },
#if (BACNET_PROTOCOL_REVISION >= 17) #if (BACNET_PROTOCOL_REVISION >= 17)
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count, { OBJECT_NETWORK_PORT,
Network_Port_Index_To_Instance, Network_Port_Valid_Instance, Network_Port_Init,
Network_Port_Object_Name, Network_Port_Read_Property, Network_Port_Count,
Network_Port_Write_Property, Network_Port_Property_Lists, Network_Port_Index_To_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, Network_Port_Valid_Instance,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Network_Port_Object_Name,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Network_Port_Read_Property,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ }, Network_Port_Write_Property,
Network_Port_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ },
#endif #endif
{ OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, { OBJECT_BINARY_INPUT,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, Binary_Input_Init,
Binary_Input_Object_Name, Binary_Input_Read_Property, Binary_Input_Count,
Binary_Input_Write_Property, Binary_Input_Property_Lists, Binary_Input_Index_To_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, Binary_Input_Valid_Instance,
Binary_Input_Encode_Value_List, Binary_Input_Change_Of_Value, Binary_Input_Object_Name,
Binary_Input_Change_Of_Value_Clear, NULL /* Intrinsic Reporting */, Binary_Input_Read_Property,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Binary_Input_Write_Property,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ }, Binary_Input_Property_Lists,
{ OBJECT_BINARY_LIGHTING_OUTPUT, Binary_Lighting_Output_Init, NULL /* ReadRangeInfo */,
Binary_Lighting_Output_Count, Binary_Lighting_Output_Index_To_Instance, NULL /* Iterator */,
Binary_Lighting_Output_Valid_Instance, Binary_Input_Encode_Value_List,
Binary_Lighting_Output_Object_Name, Binary_Input_Change_Of_Value,
Binary_Lighting_Output_Read_Property, Binary_Input_Change_Of_Value_Clear,
Binary_Lighting_Output_Write_Property, NULL /* Intrinsic Reporting */,
Binary_Lighting_Output_Property_Lists, NULL /* ReadRangeInfo */, NULL /* Add_List_Element */,
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, NULL /* Remove_List_Element */,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* Create */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* Delete */,
Binary_Lighting_Output_Create, Binary_Lighting_Output_Delete, NULL /* Timer */ },
Binary_Lighting_Output_Timer }, { OBJECT_BINARY_LIGHTING_OUTPUT,
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, Binary_Lighting_Output_Init,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, Binary_Lighting_Output_Count,
Binary_Output_Object_Name, Binary_Output_Read_Property, Binary_Lighting_Output_Index_To_Instance,
Binary_Output_Write_Property, Binary_Output_Property_Lists, Binary_Lighting_Output_Valid_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, Binary_Lighting_Output_Object_Name,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Binary_Lighting_Output_Read_Property,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Binary_Lighting_Output_Write_Property,
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */ }, Binary_Lighting_Output_Property_Lists,
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, NULL /* ReadRangeInfo */,
NULL /* Index_To_Instance */, NULL /* Valid_Instance */, NULL /* Iterator */,
NULL /* Object_Name */, NULL /* Read_Property */, NULL /* Value_Lists */,
NULL /* Write_Property */, NULL /* Property_Lists */, NULL /* COV */,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV Clear */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* Add_List_Element */,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ } NULL /* Remove_List_Element */,
Binary_Lighting_Output_Create,
Binary_Lighting_Output_Delete,
Binary_Lighting_Output_Timer },
{ OBJECT_BINARY_OUTPUT,
Binary_Output_Init,
Binary_Output_Count,
Binary_Output_Index_To_Instance,
Binary_Output_Valid_Instance,
Binary_Output_Object_Name,
Binary_Output_Read_Property,
Binary_Output_Write_Property,
Binary_Output_Property_Lists,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
Binary_Output_Create,
Binary_Output_Delete,
NULL /* Timer */ },
{ MAX_BACNET_OBJECT_TYPE,
NULL /* Init */,
NULL /* Count */,
NULL /* Index_To_Instance */,
NULL /* Valid_Instance */,
NULL /* Object_Name */,
NULL /* Read_Property */,
NULL /* Write_Property */,
NULL /* Property_Lists */,
NULL /* ReadRangeInfo */,
NULL /* Iterator */,
NULL /* Value_Lists */,
NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ }
}; };
/** Glue function to let the Device object, when called by a handler, /** Glue function to let the Device object, when called by a handler,
@@ -107,8 +173,8 @@ static object_functions_t My_Object_Table[] = {
* @return Pointer to the group of object helper functions that implement this * @return Pointer to the group of object helper functions that implement this
* type of Object. * type of Object.
*/ */
static struct object_functions *Device_Objects_Find_Functions( static struct object_functions *
BACNET_OBJECT_TYPE Object_Type) Device_Objects_Find_Functions(BACNET_OBJECT_TYPE Object_Type)
{ {
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
@@ -154,7 +220,8 @@ rr_info_function Device_Objects_RR_Info(BACNET_OBJECT_TYPE object_type)
* list, separately, the Required, Optional, and Proprietary object * list, separately, the Required, Optional, and Proprietary object
* properties with their counts. * properties with their counts.
*/ */
void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type, void Device_Objects_Property_List(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
struct special_property_list_t *pPropertyList) struct special_property_list_t *pPropertyList)
{ {
@@ -172,8 +239,9 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
pObject = Device_Objects_Find_Functions(object_type); pObject = Device_Objects_Find_Functions(object_type);
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) { if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
pObject->Object_RPM_List(&pPropertyList->Required.pList, pObject->Object_RPM_List(
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList); &pPropertyList->Required.pList, &pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
} }
/* Fetch the counts if available otherwise zero them */ /* Fetch the counts if available otherwise zero them */
@@ -193,25 +261,47 @@ void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
} }
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER, static const int Device_Properties_Required[] = {
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME, PROP_OBJECT_IDENTIFIER,
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION, PROP_OBJECT_NAME,
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION, PROP_OBJECT_TYPE,
PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_SYSTEM_STATUS,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST, PROP_VENDOR_NAME,
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED, PROP_VENDOR_IDENTIFIER,
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING, PROP_MODEL_NAME,
PROP_DATABASE_REVISION, -1 }; PROP_FIRMWARE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION,
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_REVISION,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_OBJECT_LIST,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_DEVICE_ADDRESS_BINDING,
PROP_DATABASE_REVISION,
-1
};
static const int Device_Properties_Optional[] = { static const int Device_Properties_Optional[] = {
#if defined(BACDL_MSTP) #if defined(BACDL_MSTP)
PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
#endif #endif
PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE, PROP_DESCRIPTION,
PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS, PROP_LOCAL_TIME,
PROP_UTC_OFFSET,
PROP_LOCAL_DATE,
PROP_DAYLIGHT_SAVINGS_STATUS,
PROP_LOCATION,
PROP_ACTIVE_COV_SUBSCRIPTIONS,
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_TIME_SYNCHRONIZATION_INTERVAL, PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET, PROP_TIME_SYNCHRONIZATION_INTERVAL,
PROP_ALIGN_INTERVALS,
PROP_INTERVAL_OFFSET,
#endif #endif
-1 -1
}; };
@@ -785,7 +875,8 @@ int Device_Object_List_Element_Encode(
* Object. * Object.
* @return True on success or else False if not found. * @return True on success or else False if not found.
*/ */
bool Device_Valid_Object_Name(const BACNET_CHARACTER_STRING *object_name1, bool Device_Valid_Object_Name(
const BACNET_CHARACTER_STRING *object_name1,
BACNET_OBJECT_TYPE *object_type, BACNET_OBJECT_TYPE *object_type,
uint32_t *object_instance) uint32_t *object_instance)
{ {
@@ -804,7 +895,7 @@ bool Device_Valid_Object_Name(const BACNET_CHARACTER_STRING *object_name1,
pObject = Device_Objects_Find_Functions(type); pObject = Device_Objects_Find_Functions(type);
if ((pObject != NULL) && (pObject->Object_Name != NULL) && if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
(pObject->Object_Name(instance, &object_name2) && (pObject->Object_Name(instance, &object_name2) &&
characterstring_same(object_name1, &object_name2))) { characterstring_same(object_name1, &object_name2))) {
found = true; found = true;
if (object_type) { if (object_type) {
*object_type = type; *object_type = type;
@@ -845,7 +936,8 @@ bool Device_Valid_Object_Id(
* @param object_name [out] The Object Name found for this child Object. * @param object_name [out] The Object Name found for this child Object.
* @return True on success or else False if not found. * @return True on success or else False if not found.
*/ */
bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type, bool Device_Object_Name_Copy(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
@@ -1063,7 +1155,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
bitstring_init(&bit_string); bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */ /* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t)i, bitstring_set_bit(
&bit_string, (uint8_t)i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
} }
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
@@ -1090,9 +1183,9 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
break; break;
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
count = Device_Object_List_Count(); count = Device_Object_List_Count();
apdu_len = bacnet_array_encode(rpdata->object_instance, apdu_len = bacnet_array_encode(
rpdata->array_index, Device_Object_List_Element_Encode, count, rpdata->object_instance, rpdata->array_index,
apdu, apdu_max); Device_Object_List_Element_Encode, count, apdu, apdu_max);
if (apdu_len == BACNET_STATUS_ABORT) { if (apdu_len == BACNET_STATUS_ABORT) {
rpdata->error_code = rpdata->error_code =
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -1215,8 +1308,9 @@ static int Read_Property_Common(
} else if (rpdata->object_property == PROP_PROPERTY_LIST) { } else if (rpdata->object_property == PROP_PROPERTY_LIST) {
Device_Objects_Property_List( Device_Objects_Property_List(
rpdata->object_type, rpdata->object_instance, &property_list); rpdata->object_type, rpdata->object_instance, &property_list);
apdu_len = property_list_encode(rpdata, property_list.Required.pList, apdu_len = property_list_encode(
property_list.Optional.pList, property_list.Proprietary.pList); rpdata, property_list.Required.pList, property_list.Optional.pList,
property_list.Proprietary.pList);
#endif #endif
} else if (pObject->Object_Read_Property) { } else if (pObject->Object_Read_Property) {
apdu_len = pObject->Object_Read_Property(rpdata); apdu_len = pObject->Object_Read_Property(rpdata);
@@ -1354,8 +1448,9 @@ bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
wp_data, &value, characterstring_capacity(&My_Object_Name)); wp_data, &value, characterstring_capacity(&My_Object_Name));
if (status) { if (status) {
/* All the object names in a device must be unique */ /* All the object names in a device must be unique */
if (Device_Valid_Object_Name(&value.type.Character_String, if (Device_Valid_Object_Name(
&object_type, &object_instance)) { &value.type.Character_String, &object_type,
&object_instance)) {
if ((object_type == wp_data->object_type) && if ((object_type == wp_data->object_type) &&
(object_instance == wp_data->object_instance)) { (object_instance == wp_data->object_instance)) {
/* writing same name to same object */ /* writing same name to same object */
@@ -1719,7 +1814,8 @@ int Device_Remove_List_Element(BACNET_LIST_ELEMENT_DATA *list_element)
* @param [out] The value list * @param [out] The value list
* @return True if the object instance supports this feature and value changed. * @return True if the object instance supports this feature and value changed.
*/ */
bool Device_Encode_Value_List(BACNET_OBJECT_TYPE object_type, bool Device_Encode_Value_List(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list) BACNET_PROPERTY_VALUE *value_list)
{ {
@@ -1804,7 +1900,8 @@ bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
object for some other reason.*/ object for some other reason.*/
data->error_class = ERROR_CLASS_OBJECT; data->error_class = ERROR_CLASS_OBJECT;
data->error_code = ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED; data->error_code = ERROR_CODE_DYNAMIC_CREATION_NOT_SUPPORTED;
} else if (pObject->Object_Valid_Instance && } else if (
pObject->Object_Valid_Instance &&
pObject->Object_Valid_Instance(data->object_instance)) { pObject->Object_Valid_Instance(data->object_instance)) {
/* The object being created already exists */ /* The object being created already exists */
data->error_class = ERROR_CLASS_OBJECT; data->error_class = ERROR_CLASS_OBJECT;
@@ -1862,7 +1959,8 @@ bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
object for some reason.*/ object for some reason.*/
data->error_class = ERROR_CLASS_OBJECT; data->error_class = ERROR_CLASS_OBJECT;
data->error_code = ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED; data->error_code = ERROR_CODE_OBJECT_DELETION_NOT_PERMITTED;
} else if (pObject->Object_Valid_Instance && } else if (
pObject->Object_Valid_Instance &&
pObject->Object_Valid_Instance(data->object_instance)) { pObject->Object_Valid_Instance(data->object_instance)) {
/* The object being deleted must already exist */ /* The object being deleted must already exist */
status = pObject->Object_Delete(data->object_instance); status = pObject->Object_Delete(data->object_instance);
@@ -1934,7 +2032,8 @@ void Device_Init(object_functions_t *object_table)
} }
} }
bool DeviceGetRRInfo(BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */ bool DeviceGetRRInfo(
BACNET_READ_RANGE_DATA *pRequest, /* Info on the request */
RR_PROP_INFO *pInfo) RR_PROP_INFO *pInfo)
{ /* Where to put the response */ { /* Where to put the response */
bool status = false; /* return value */ bool status = false; /* return value */
+17 -13
View File
@@ -85,7 +85,8 @@ static void piface_write_output(int index, BACNET_BINARY_LIGHTING_PV value)
* @param old_value - value prior to write * @param old_value - value prior to write
* @param value - value of the write * @param value - value of the write
*/ */
static void Binary_Lighting_Output_Write_Value_Handler(uint32_t object_instance, static void Binary_Lighting_Output_Write_Value_Handler(
uint32_t object_instance,
BACNET_BINARY_LIGHTING_PV old_value, BACNET_BINARY_LIGHTING_PV old_value,
BACNET_BINARY_LIGHTING_PV value) BACNET_BINARY_LIGHTING_PV value)
{ {
@@ -93,7 +94,8 @@ static void Binary_Lighting_Output_Write_Value_Handler(uint32_t object_instance,
index = Binary_Lighting_Output_Instance_To_Index(object_instance); index = Binary_Lighting_Output_Instance_To_Index(object_instance);
if (index < PIFACE_OUTPUTS_MAX) { if (index < PIFACE_OUTPUTS_MAX) {
printf("BLO-WRITE: OUTPUT[%u]=%d present=%d feedback=%d target=%d\n", printf(
"BLO-WRITE: OUTPUT[%u]=%d present=%d feedback=%d target=%d\n",
index, (int)value, index, (int)value,
(int)Binary_Lighting_Output_Present_Value(object_instance), (int)Binary_Lighting_Output_Present_Value(object_instance),
(int)old_value, (int)old_value,
@@ -115,12 +117,10 @@ static void Binary_Lighting_Output_Blink_Warn_Handler(uint32_t object_instance)
if (index < PIFACE_OUTPUTS_MAX) { if (index < PIFACE_OUTPUTS_MAX) {
/* blink is just toggle on/off every one second */ /* blink is just toggle on/off every one second */
if (PiFace_Output_State[index]) { if (PiFace_Output_State[index]) {
printf("BLO-BLINK: OUTPUT[%u]=%d\n", index, printf("BLO-BLINK: OUTPUT[%u]=%d\n", index, BINARY_LIGHTING_PV_OFF);
BINARY_LIGHTING_PV_OFF);
piface_write_output(index, BINARY_LIGHTING_PV_OFF); piface_write_output(index, BINARY_LIGHTING_PV_OFF);
} else { } else {
printf( printf("BLO-BLINK: OUTPUT[%u]=%d\n", index, BINARY_LIGHTING_PV_ON);
"BLO-BLINK: OUTPUT[%u]=%d\n", index, BINARY_LIGHTING_PV_ON);
piface_write_output(index, BINARY_LIGHTING_PV_ON); piface_write_output(index, BINARY_LIGHTING_PV_ON);
} }
} }
@@ -166,7 +166,8 @@ static void Init_Service_Handlers(void)
apdu_set_unconfirmed_handler( apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
/* configure the cyclic timers */ /* configure the cyclic timers */
mstimer_set(&BACnet_Task_Timer, 1000UL); mstimer_set(&BACnet_Task_Timer, 1000UL);
@@ -262,13 +263,15 @@ static void piface_task(void)
present_value = Binary_Output_Present_Value(object_instance); present_value = Binary_Output_Present_Value(object_instance);
if (present_value == BINARY_INACTIVE) { if (present_value == BINARY_INACTIVE) {
if (PiFace_Output_State[i]) { if (PiFace_Output_State[i]) {
printf("BO-WRITE: OUTPUT[%u]=%d\n", i, printf(
"BO-WRITE: OUTPUT[%u]=%d\n", i,
BINARY_LIGHTING_PV_OFF); BINARY_LIGHTING_PV_OFF);
piface_write_output(i, BINARY_LIGHTING_PV_OFF); piface_write_output(i, BINARY_LIGHTING_PV_OFF);
} }
} else { } else {
if (!PiFace_Output_State[i]) { if (!PiFace_Output_State[i]) {
printf("BO-WRITE: OUTPUT[%u]=%d\n", i, printf(
"BO-WRITE: OUTPUT[%u]=%d\n", i,
BINARY_LIGHTING_PV_OFF); BINARY_LIGHTING_PV_OFF);
piface_write_output(i, BINARY_LIGHTING_PV_ON); piface_write_output(i, BINARY_LIGHTING_PV_ON);
} }
@@ -302,10 +305,11 @@ int main(int argc, char *argv[])
if (argc > 1) { if (argc > 1) {
Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0)); Device_Set_Object_Instance_Number(strtol(argv[1], NULL, 0));
} }
printf("BACnet Raspberry Pi PiFace Digital Demo\n" printf(
"BACnet Stack Version %s\n" "BACnet Raspberry Pi PiFace Digital Demo\n"
"BACnet Device ID: %u\n" "BACnet Stack Version %s\n"
"Max APDU: %d\n", "BACnet Device ID: %u\n"
"Max APDU: %d\n",
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU); BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
/* load any static address bindings to show up /* load any static address bindings to show up
in our device bindings list */ in our device bindings list */
+15 -10
View File
@@ -122,7 +122,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
data->serviceParametersLen = 0; data->serviceParametersLen = 0;
return; return;
} }
iLen += decode_real(&data->serviceParameters[iLen], iLen += decode_real(
&data->serviceParameters[iLen],
&MyData[(int8_t)cBlockNumber].fMyReal); &MyData[(int8_t)cBlockNumber].fMyReal);
tag_len = decode_tag_number_and_value( tag_len = decode_tag_number_and_value(
@@ -135,7 +136,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
decode_character_string( decode_character_string(
&data->serviceParameters[iLen], len_value_type, &bsTemp); &data->serviceParameters[iLen], len_value_type, &bsTemp);
/* Only copy as much as we can accept */ /* Only copy as much as we can accept */
strncpy((char *)MyData[(int8_t)cBlockNumber].sMyString, strncpy(
(char *)MyData[(int8_t)cBlockNumber].sMyString,
characterstring_value(&bsTemp), MY_MAX_STR); characterstring_value(&bsTemp), MY_MAX_STR);
/* Make sure it is nul terminated */ /* Make sure it is nul terminated */
MyData[(int8_t)cBlockNumber].sMyString[MY_MAX_STR] = '\0'; MyData[(int8_t)cBlockNumber].sMyString[MY_MAX_STR] = '\0';
@@ -160,7 +162,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
* *
*/ */
void handler_conf_private_trans(uint8_t *service_request, void handler_conf_private_trans(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
@@ -194,9 +197,9 @@ void handler_conf_private_trans(uint8_t *service_request,
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n"); fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
#endif #endif
@@ -206,8 +209,9 @@ void handler_conf_private_trans(uint8_t *service_request,
len = ptransfer_decode_service_request(service_request, service_len, &data); len = ptransfer_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */ /* bad decoding - send an abort */
if (len < 0) { if (len < 0) {
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, ABORT_REASON_OTHER, true); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_OTHER, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -247,8 +251,9 @@ void handler_conf_private_trans(uint8_t *service_request,
} }
if (error) { if (error) {
len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = ptransfer_error_encode_apdu(
service_data->invoke_id, error_class, error_code, &data); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
error_class, error_code, &data);
} }
CPT_ABORT: CPT_ABORT:
pdu_len += len; pdu_len += len;
+14 -14
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Steve Karg * @author Steve Karg
* @date October 2019 * @date October 2019
* @brief Header file for a basic ConfirmedPrivateTransfer service handler * @brief Header file for a basic ConfirmedPrivateTransfer service handler
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_H #ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_H
#define HANDLER_CONFIRMED_PRIVATE_TRANSFER_H #define HANDLER_CONFIRMED_PRIVATE_TRANSFER_H
@@ -24,11 +24,11 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void handler_conf_private_trans( void handler_conf_private_trans(
uint8_t * service_request, uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA * service_data); BACNET_CONFIRMED_SERVICE_DATA *service_data);
#ifdef __cplusplus #ifdef __cplusplus
} }
+10 -5
View File
@@ -36,8 +36,9 @@ static void DecodeBlock(char cBlockNum, uint8_t *pData)
iLen = 0; iLen = 0;
if (cBlockNum >= MY_MAX_BLOCK) if (cBlockNum >= MY_MAX_BLOCK) {
return; return;
}
tag_len = tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type); decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
@@ -136,12 +137,14 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
cBlockNumber = (char)ulTemp; cBlockNumber = (char)ulTemp;
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]); DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
} else { /* Read error */ } else { /* Read error */
printf("Private Transfer read operation returned error code: %lu\n", printf(
"Private Transfer read operation returned error code: %lu\n",
(unsigned long)uiErrorCode); (unsigned long)uiErrorCode);
return; return;
} }
} else { /* Write I/O block - should just be an OK type message */ } else { /* Write I/O block - should just be an OK type message */
printf("Private Transfer write operation returned error code: %lu\n", printf(
"Private Transfer write operation returned error code: %lu\n",
(unsigned long)uiErrorCode); (unsigned long)uiErrorCode);
} }
} }
@@ -152,7 +155,8 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
* and decide what to do next... * and decide what to do next...
*/ */
void handler_conf_private_trans_ack(uint8_t *service_request, void handler_conf_private_trans_ack(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -176,7 +180,8 @@ void handler_conf_private_trans_ack(uint8_t *service_request,
printf("Received Confirmed Private Transfer Ack!\n"); printf("Received Confirmed Private Transfer Ack!\n");
#endif #endif
len = ptransfer_decode_service_request(service_request, service_len, len = ptransfer_decode_service_request(
service_request, service_len,
&data); /* Same decode for ack as for service request! */ &data); /* Same decode for ack as for service request! */
if (len < 0) { if (len < 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
+14 -14
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Steve Karg * @author Steve Karg
* @date October 2019 * @date October 2019
* @brief Header file for a basic ConfirmedPrivateTransfer-Ack service handler * @brief Header file for a basic ConfirmedPrivateTransfer-Ack service handler
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H #ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H
#define HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H #define HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H
@@ -25,11 +25,11 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void handler_conf_private_trans_ack( void handler_conf_private_trans_ack(
uint8_t * service_request, uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data); BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data);
#ifdef __cplusplus #ifdef __cplusplus
} }
+18 -12
View File
@@ -68,7 +68,8 @@ static int Target_Mode = 0;
static BACNET_ADDRESS Target_Address; static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -76,14 +77,15 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
printf("BACnet Error: %s: %s\r\n", printf(
bactext_error_class_name((int)error_class), "BACnet Error: %s: %s\r\n", bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
/* Error_Detected = true; */ /* Error_Detected = true; */
} }
/* complex error reply function */ /* complex error reply function */
static void MyPrivateTransferErrorHandler(BACNET_ADDRESS *src, static void MyPrivateTransferErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
uint8_t service_choice, uint8_t service_choice,
uint8_t *service_request, uint8_t *service_request,
@@ -108,13 +110,14 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
printf("BACnet Reject: %s\r\n", printf(
"BACnet Reject: %s\r\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -184,8 +187,9 @@ int main(int argc, char *argv[])
if (((argc != 2) && (argc != 3)) || if (((argc != 2) && (argc != 3)) ||
((argc >= 2) && (strcmp(argv[1], "--help") == 0))) { ((argc >= 2) && (strcmp(argv[1], "--help") == 0))) {
printf("%s\n", argv[0]); printf("%s\n", argv[0]);
printf("Usage: %s server local-device-instance\r\n or\r\n" printf(
" %s remote-device-instance\r\n", "Usage: %s server local-device-instance\r\n or\r\n"
" %s remote-device-instance\r\n",
filename_remove_path(argv[0]), filename_remove_path(argv[0])); filename_remove_path(argv[0]), filename_remove_path(argv[0]));
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf( printf(
@@ -220,7 +224,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0); Target_Device_Object_Instance = strtol(argv[1 + Target_Mode], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\r\n", fprintf(
stderr, "device-instance=%u - not greater than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -349,8 +354,9 @@ int main(int argc, char *argv[])
case 3: case 3:
case 5: case 5:
case 7: case 7:
printf("Requesting block %d with invalid " printf(
"Vendor ID\n", "Requesting block %d with invalid "
"Vendor ID\n",
iCount); iCount);
invoke_id = Send_Private_Transfer_Request( invoke_id = Send_Private_Transfer_Request(
Target_Device_Object_Instance, Target_Device_Object_Instance,
+11 -6
View File
@@ -25,7 +25,8 @@
#include "bacnet/datalink/datalink.h" #include "bacnet/datalink/datalink.h"
#include "bacnet/basic/services.h" #include "bacnet/basic/services.h"
uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint8_t Send_Private_Transfer_Request(
uint32_t device_id,
uint16_t vendor_id, uint16_t vendor_id,
uint32_t service_number, uint32_t service_number,
unsigned int block_number, unsigned int block_number,
@@ -81,21 +82,25 @@ uint8_t Send_Private_Transfer_Request(uint32_t device_id,
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
bytes_sent = datalink_send_pdu( bytes_sent = datalink_send_pdu(
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0) {
fprintf(stderr, fprintf(
stderr,
"Failed to Send Private Transfer Request (%s)!\n", "Failed to Send Private Transfer Request (%s)!\n",
strerror(errno)); strerror(errno));
}
#endif #endif
} else { } else {
tsm_free_invoke_id(invoke_id); tsm_free_invoke_id(invoke_id);
invoke_id = 0; invoke_id = 0;
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(
stderr,
"Failed to Send Private Transfer Request " "Failed to Send Private Transfer Request "
"(exceeds destination maximum APDU)!\n"); "(exceeds destination maximum APDU)!\n");
#endif #endif
+15 -12
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Steve Karg * @author Steve Karg
* @date October 2019 * @date October 2019
* @brief Header file for a basic WritePropertyMultiple service send * @brief Header file for a basic WritePropertyMultiple service send
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef SEND_WRITE_PROPERTY_MULTIPLE_H #ifndef SEND_WRITE_PROPERTY_MULTIPLE_H
#define SEND_WRITE_PROPERTY_MULTIPLE_H #define SEND_WRITE_PROPERTY_MULTIPLE_H
@@ -25,9 +25,12 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id, uint8_t Send_Private_Transfer_Request(
uint32_t service_number, uint32_t device_id,
char block_number, DATABLOCK *block); uint16_t vendor_id,
uint32_t service_number,
char block_number,
DATABLOCK *block);
#ifdef __cplusplus #ifdef __cplusplus
} }
+2 -2
View File
@@ -52,8 +52,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
+13 -12
View File
@@ -52,8 +52,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -98,16 +98,17 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send a Read-Foreign-Device-Table message to a BBMD.\r\n" printf(
"\r\n" "Send a Read-Foreign-Device-Table message to a BBMD.\r\n"
"IP:\r\n" "\r\n"
"IP address of the BBMD in dotted decimal notation\r\n" "IP:\r\n"
"[port]\r\n" "IP address of the BBMD in dotted decimal notation\r\n"
"optional BACnet/IP port number (default=47808=0xBAC0)\r\n" "[port]\r\n"
"\r\n" "optional BACnet/IP port number (default=47808=0xBAC0)\r\n"
"To send a Read-Foreign-Device-Table message to a BBMD\r\n" "\r\n"
"at 192.168.0.1 using port 47808:\r\n" "To send a Read-Foreign-Device-Table message to a BBMD\r\n"
"%s 192.168.0.1 47808\r\n", "at 192.168.0.1 using port 47808:\r\n"
"%s 192.168.0.1 47808\r\n",
filename_remove_path(argv[0])); filename_remove_path(argv[0]));
return 0; return 0;
} }
+32 -21
View File
@@ -50,14 +50,16 @@ static bool End_Of_File_Detected = false;
static bool Error_Detected = false; static bool Error_Detected = false;
static uint8_t Request_Invoke_ID = 0; static uint8_t Request_Invoke_ID = 0;
static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS *src, static void Atomic_Read_File_Error_Handler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -76,18 +78,20 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void AtomicReadFileAckHandler(uint8_t *service_request, static void AtomicReadFileAckHandler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -128,7 +132,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
octets_written = octets_written =
fwrite(octet_buffer, 1, octet_count, pFile); fwrite(octet_buffer, 1, octet_count, pFile);
if (octets_written != octet_count) { if (octets_written != octet_count) {
fprintf(stderr, fprintf(
stderr,
"Unable to write data to file \"%s\".\n", "Unable to write data to file \"%s\".\n",
Local_File_Name); Local_File_Name);
} else { } else {
@@ -140,7 +145,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
} }
fflush(pFile); fflush(pFile);
} else { } else {
fprintf(stderr, "Unable to seek to %d!\n", fprintf(
stderr, "Unable to seek to %d!\n",
data.type.stream.fileStartPosition); data.type.stream.fileStartPosition);
} }
} }
@@ -154,7 +160,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
fprintf(stderr, "Decode error! %d bytes decoded.\n", len); fprintf(stderr, "Decode error! %d bytes decoded.\n", len);
} }
} else { } else {
fprintf(stderr, "Address & Invoke ID mismatch! Invoke ID=%d\n", fprintf(
stderr, "Address & Invoke ID mismatch! Invoke ID=%d\n",
Request_Invoke_ID); Request_Invoke_ID);
} }
} }
@@ -213,24 +220,26 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf( printf("Read a file from a BACnet device and save it locally.\n");
"Read a file from a BACnet device and save it locally.\n");
printf("\n"); printf("\n");
printf("device-instance:\n" printf(
"device-instance:\n"
"BACnet Device Object Instance number that you are trying to\n" "BACnet Device Object Instance number that you are trying to\n"
"communicate to. This number will be used to try and bind with\n" "communicate to. This number will be used to try and bind with\n"
"the device using Who-Is and I-Am services. For example, if you were\n" "the device using Who-Is and I-Am services. For example, if you were\n"
"reading from Device Object 123, the device-instance would be 123.\n"); "reading from Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf("file-instance:\n" printf(
"file-instance:\n"
"This is the file object instance number that you are reading from.\n" "This is the file object instance number that you are reading from.\n"
"For example, if you were reading from File 2, \n" "For example, if you were reading from File 2, \n"
"the file-instance would be 2.\n"); "the file-instance would be 2.\n");
printf("\n"); printf("\n");
printf("local-name:\n" printf("local-name:\n"
"The name of the file that will be stored locally.\n"); "The name of the file that will be stored locally.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"Example:\n"
"If you want read File 2 from Device 123 and save it to temp.txt,\n" "If you want read File 2 from Device 123 and save it to temp.txt,\n"
"use the following command:\n" "use the following command:\n"
"%s 123 2 temp.txt\n", "%s 123 2 temp.txt\n",
@@ -280,12 +289,14 @@ int main(int argc, char *argv[])
Target_File_Object_Instance = strtol(argv[2], NULL, 0); Target_File_Object_Instance = strtol(argv[2], NULL, 0);
Local_File_Name = argv[3]; Local_File_Name = argv[3];
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_File_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_File_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "file-instance=%u - not greater than %u\n", fprintf(
stderr, "file-instance=%u - not greater than %u\n",
Target_File_Object_Instance, BACNET_MAX_INSTANCE); Target_File_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -356,10 +367,10 @@ int main(int argc, char *argv[])
/* the ACK will increment the start position if OK */ /* the ACK will increment the start position if OK */
/* we'll read the file in chunks /* we'll read the file in chunks
less than max_apdu to keep unsegmented */ less than max_apdu to keep unsegmented */
invoke_id = invoke_id = Send_Atomic_Read_File_Stream(
Send_Atomic_Read_File_Stream(Target_Device_Object_Instance, Target_Device_Object_Instance, Target_File_Object_Instance,
Target_File_Object_Instance, Target_File_Start_Position, Target_File_Start_Position,
Target_File_Requested_Octet_Count); Target_File_Requested_Octet_Count);
Request_Invoke_ID = invoke_id; Request_Invoke_ID = invoke_id;
} else if (tsm_invoke_id_failed(invoke_id)) { } else if (tsm_invoke_id_failed(invoke_id)) {
fprintf(stderr, "\rError: TSM Timeout!\n"); fprintf(stderr, "\rError: TSM Timeout!\n");
+38 -38
View File
@@ -13,7 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <time.h> /* for time */ #include <time.h> /* for time */
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
#include <locale.h> #include <locale.h>
#endif #endif
#define PRINT_ENABLED 1 #define PRINT_ENABLED 1
@@ -56,14 +56,16 @@ static uint8_t Request_Invoke_ID = 0;
static BACNET_ADDRESS Target_Address; static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -82,12 +84,13 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -104,7 +107,8 @@ static void MyRejectHandler(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
static void My_Read_Property_Ack_Handler(uint8_t *service_request, static void My_Read_Property_Ack_Handler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -149,8 +153,9 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance " printf(
"property [index]\n", "Usage: %s device-instance object-type object-instance "
"property [index]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -166,14 +171,12 @@ static void print_help(const char *filename)
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf( printf("--dnet N\n"
"--dnet N\n"
"Optional BACnet network number N for directed requests.\n" "Optional BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf( printf("--dadr A\n"
"--dadr A\n"
"Optional BACnet mac address on the destination BACnet network " "Optional BACnet mac address on the destination BACnet network "
"number.\n" "number.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
@@ -187,8 +190,7 @@ static void print_help(const char *filename)
"I-Am services. For example, if you were reading\n" "I-Am services. For example, if you were reading\n"
"Device Object 123, the device-instance would be 123.\n"); "Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf( printf("object-type:\n"
"object-type:\n"
"The object type is object that you are reading. It\n" "The object type is object that you are reading. It\n"
"can be defined either as the object-type name string\n" "can be defined either as the object-type name string\n"
"as defined in the BACnet specification, or as the\n" "as defined in the BACnet specification, or as the\n"
@@ -196,14 +198,12 @@ static void print_help(const char *filename)
"in bacenum.h. For example if you were reading Analog\n" "in bacenum.h. For example if you were reading Analog\n"
"Output 2, the object-type would be analog-output or 1.\n"); "Output 2, the object-type would be analog-output or 1.\n");
printf("\n"); printf("\n");
printf( printf("object-instance:\n"
"object-instance:\n"
"This is the object instance number of the object that\n" "This is the object instance number of the object that\n"
"you are reading. For example, if you were reading\n" "you are reading. For example, if you were reading\n"
"Analog Output 2, the object-instance would be 2.\n"); "Analog Output 2, the object-instance would be 2.\n");
printf("\n"); printf("\n");
printf( printf("property:\n"
"property:\n"
"The property of the object that you are reading. It\n" "The property of the object that you are reading. It\n"
"can be defined either as the property name string as\n" "can be defined either as the property name string as\n"
"defined in the BACnet specification, or as an integer\n" "defined in the BACnet specification, or as an integer\n"
@@ -211,27 +211,26 @@ static void print_help(const char *filename)
"bacenum.h. For example, if you were reading the Present\n" "bacenum.h. For example, if you were reading the Present\n"
"Value property, use present-value or 85 as the property.\n"); "Value property, use present-value or 85 as the property.\n");
printf("\n"); printf("\n");
printf( printf("index:\n"
"index:\n"
"This integer parameter is the index number of an array.\n" "This integer parameter is the index number of an array.\n"
"If the property is an array, individual elements can\n" "If the property is an array, individual elements can\n"
"be read. If this parameter is missing and the property\n" "be read. If this parameter is missing and the property\n"
"is an array, the entire array will be read.\n"); "is an array, the entire array will be read.\n");
printf("\n"); printf("\n");
printf( printf(
"Example:\n" "Example:\n"
"If you want read the Present-Value of Analog Output 101\n" "If you want read the Present-Value of Analog Output 101\n"
"in Device 123, you could send either of the following\n" "in Device 123, you could send either of the following\n"
"commands:\n" "commands:\n"
"%s 123 analog-output 101 present-value\n" "%s 123 analog-output 101 present-value\n"
"%s 123 1 101 85\n", "%s 123 1 101 85\n",
filename, filename); filename, filename);
printf( printf(
"If you want read the Priority-Array of Analog Output 101\n" "If you want read the Priority-Array of Analog Output 101\n"
"in Device 123, you could send either of the following\n" "in Device 123, you could send either of the following\n"
"commands:\n" "commands:\n"
"%s 123 analog-output 101 priority-array\n" "%s 123 analog-output 101 priority-array\n"
"%s 123 1 101 87\n", "%s 123 1 101 87\n",
filename, filename); filename, filename);
} }
@@ -329,7 +328,8 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -370,7 +370,7 @@ int main(int argc, char *argv[])
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers(); Init_Service_Handlers();
dlenv_init(); dlenv_init();
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
/* Internationalized programs must call setlocale() /* Internationalized programs must call setlocale()
* to initiate a specific language operation. * to initiate a specific language operation.
* This can be done by calling setlocale() as follows. * This can be done by calling setlocale() as follows.
@@ -413,10 +413,10 @@ int main(int argc, char *argv[])
} }
if (found) { if (found) {
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
Request_Invoke_ID = Request_Invoke_ID = Send_Read_Property_Request(
Send_Read_Property_Request(Target_Device_Object_Instance, Target_Device_Object_Instance, Target_Object_Type,
Target_Object_Type, Target_Object_Instance, Target_Object_Instance, Target_Object_Property,
Target_Object_Property, Target_Object_Index); Target_Object_Index);
} else if (tsm_invoke_id_free(Request_Invoke_ID)) { } else if (tsm_invoke_id_free(Request_Invoke_ID)) {
break; break;
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) { } else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
+64 -45
View File
@@ -13,7 +13,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <time.h> /* for time */ #include <time.h> /* for time */
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
#include <locale.h> #include <locale.h>
#endif #endif
#define PRINT_ENABLED 1 #define PRINT_ENABLED 1
@@ -43,7 +43,6 @@
#error "App requires server-only features disabled! Set BACNET_SVC_SERVER=0" #error "App requires server-only features disabled! Set BACNET_SVC_SERVER=0"
#endif #endif
/* buffer used for receive */ /* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -56,14 +55,16 @@ static BACNET_ADDRESS Target_Address;
/* needed for return value of main application */ /* needed for return value of main application */
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -82,13 +83,14 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -105,7 +107,8 @@ static void MyRejectHandler(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
static void My_Read_Property_Multiple_Ack_Handler(uint8_t *service_request, static void My_Read_Property_Multiple_Ack_Handler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
@@ -168,7 +171,8 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the data coming back from confirmed requests */ /* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, apdu_set_confirmed_ack_handler(
SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
My_Read_Property_Multiple_Ack_Handler); My_Read_Property_Multiple_Ack_Handler);
/* handle any errors coming back */ /* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
@@ -236,8 +240,9 @@ static void target_address_add(
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance " printf(
"property[index][,property[index]] [object-type ...]\n", "Usage: %s device-instance object-type object-instance "
"property[index][,property[index]] [object-type ...]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -298,29 +303,39 @@ static void print_help(const char *filename)
"be read. If this parameter is missing and the property\n" "be read. If this parameter is missing and the property\n"
"is an array, the entire array will be read.\n"); "is an array, the entire array will be read.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"If you want read the PRESENT_VALUE property and various\n" "Example:\n"
"array elements of the PRIORITY_ARRAY in Device 123\n" "If you want read the PRESENT_VALUE property and various\n"
"Analog Output object 99, use one of the following commands:\n" "array elements of the PRIORITY_ARRAY in Device 123\n"
"%s 123 analog-output 99 85,87[0],87\n" "Analog Output object 99, use one of the following commands:\n"
"%s 123 1 99 85,87[0],87\n", filename, filename); "%s 123 analog-output 99 85,87[0],87\n"
printf("If you want read the PRESENT_VALUE property in objects\n" "%s 123 1 99 85,87[0],87\n",
"Analog Input 77 and Analog Input 78 in Device 123\n" filename, filename);
"use one of the following commands:\n" printf(
"%s 123 analog-input 77 85 analog-input 78 85\n" "If you want read the PRESENT_VALUE property in objects\n"
"%s 123 0 77 85 0 78 85\n", filename, filename); "Analog Input 77 and Analog Input 78 in Device 123\n"
printf("If you want read the ALL property in\n" "use one of the following commands:\n"
"Device object 123, you would use one of the following commands:\n" "%s 123 analog-input 77 85 analog-input 78 85\n"
"%s 123 device 123 8\n" "%s 123 0 77 85 0 78 85\n",
"%s 123 8 123 8\n", filename, filename); filename, filename);
printf("If you want read the OPTIONAL property in\n" printf(
"Device object 123, you would use one of the following commands:\n" "If you want read the ALL property in\n"
"%s 123 device 123 80\n" "Device object 123, you would use one of the following commands:\n"
"%s 123 8 123 80\n", filename, filename); "%s 123 device 123 8\n"
printf("If you want read the REQUIRED property in\n" "%s 123 8 123 8\n",
"Device object 123, you would one of use the following commands:\n" filename, filename);
"%s 123 device 123 105\n" printf(
"%s 123 8 123 105\n", filename, filename); "If you want read the OPTIONAL property in\n"
"Device object 123, you would use one of the following commands:\n"
"%s 123 device 123 80\n"
"%s 123 8 123 80\n",
filename, filename);
printf(
"If you want read the REQUIRED property in\n"
"Device object 123, you would one of use the following commands:\n"
"%s 123 device 123 105\n"
"%s 123 8 123 105\n",
filename, filename);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@@ -391,8 +406,8 @@ int main(int argc, char *argv[])
if (target_args == 0) { if (target_args == 0) {
Target_Device_Object_Instance = strtol(argv[argi], NULL, 0); Target_Device_Object_Instance = strtol(argv[argi], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -413,13 +428,15 @@ int main(int argc, char *argv[])
status = status =
bactext_object_type_strtol(argv[argi], &object_type); bactext_object_type_strtol(argv[argi], &object_type);
if (status == false) { if (status == false) {
fprintf(stderr, "Error: object-type=%s invalid\n", fprintf(
stderr, "Error: object-type=%s invalid\n",
argv[argi]); argv[argi]);
return 1; return 1;
} }
rpm_object->object_type = object_type; rpm_object->object_type = object_type;
if (rpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) { if (rpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, fprintf(
stderr,
"object-type=%u - it must be less than %u\n", "object-type=%u - it must be less than %u\n",
rpm_object->object_type, MAX_BACNET_OBJECT_TYPE); rpm_object->object_type, MAX_BACNET_OBJECT_TYPE);
return 1; return 1;
@@ -428,10 +445,10 @@ int main(int argc, char *argv[])
} else if (tag_value_arg == 1) { } else if (tag_value_arg == 1) {
rpm_object->object_instance = strtol(argv[argi], NULL, 0); rpm_object->object_instance = strtol(argv[argi], NULL, 0);
if (rpm_object->object_instance > BACNET_MAX_INSTANCE) { if (rpm_object->object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
stderr,
"object-instance=%u - not greater than %u\n", "object-instance=%u - not greater than %u\n",
rpm_object->object_instance, rpm_object->object_instance, BACNET_MAX_INSTANCE);
BACNET_MAX_INSTANCE);
return 1; return 1;
} }
tag_value_arg++; tag_value_arg++;
@@ -441,13 +458,15 @@ int main(int argc, char *argv[])
property_token = strtok(argv[argi], ","); property_token = strtok(argv[argi], ",");
/* add all the properties and optional index to our list */ /* add all the properties and optional index to our list */
while (rpm_property) { while (rpm_property) {
scan_count = sscanf(property_token, "%u[%u]", scan_count = sscanf(
&property_id, &property_array_index); property_token, "%u[%u]", &property_id,
&property_array_index);
if (scan_count > 0) { if (scan_count > 0) {
rpm_property->propertyIdentifier = property_id; rpm_property->propertyIdentifier = property_id;
if (rpm_property->propertyIdentifier > if (rpm_property->propertyIdentifier >
MAX_BACNET_PROPERTY_ID) { MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, fprintf(
stderr,
"property=%u - it must be less than %u\n", "property=%u - it must be less than %u\n",
rpm_property->propertyIdentifier, rpm_property->propertyIdentifier,
MAX_BACNET_PROPERTY_ID + 1); MAX_BACNET_PROPERTY_ID + 1);
@@ -489,7 +508,7 @@ int main(int argc, char *argv[])
} }
Init_Service_Handlers(); Init_Service_Handlers();
dlenv_init(); dlenv_init();
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
/* Internationalized programs must call setlocale() /* Internationalized programs must call setlocale()
* to initiate a specific language operation. * to initiate a specific language operation.
* This can be done by calling setlocale() as follows. * This can be done by calling setlocale() as follows.
+43 -37
View File
@@ -14,7 +14,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <time.h> /* for time */ #include <time.h> /* for time */
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
#include <locale.h> #include <locale.h>
#endif #endif
/* BACnet Stack defines - first */ /* BACnet Stack defines - first */
@@ -60,14 +60,16 @@ static bool Error_Detected = false;
/* specific request data */ /* specific request data */
static BACNET_READ_RANGE_DATA RR_Request; static BACNET_READ_RANGE_DATA RR_Request;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\r\n", printf(
"BACnet Error: %s: %s\r\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -86,12 +88,13 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -123,7 +126,8 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance property\n", printf(
"Usage: %s device-instance object-type object-instance property\n",
filename); filename);
printf(" range-type <index|<date time>> count\n"); printf(" range-type <index|<date time>> count\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -132,48 +136,48 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Read a range of properties from an array or list property\n" printf("Read a range of properties from an array or list property\n"
"in an object in a BACnet device and print the values.\n"); "in an object in a BACnet device and print the values.\n");
printf("\n"); printf("\n");
printf("device-instance:\n" printf("device-instance:\n"
"BACnet Device Object Instance number that you are\n" "BACnet Device Object Instance number that you are\n"
"trying to communicate to. This number will be used\n" "trying to communicate to. This number will be used\n"
"to try and bind with the device using Who-Is and\n" "to try and bind with the device using Who-Is and\n"
"I-Am services. For example, if you were reading\n" "I-Am services. For example, if you were reading\n"
"Device Object 123, the device-instance would be 123.\n"); "Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf("object-type:\n" printf("object-type:\n"
"The object type is the integer value of the enumeration\n" "The object type is the integer value of the enumeration\n"
"BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n"
"that you are reading. For example if you were\n" "that you are reading. For example if you were\n"
"reading Trend Log 2, the object-type would be 20.\n"); "reading Trend Log 2, the object-type would be 20.\n");
printf("\n"); printf("\n");
printf("object-instance:\n" printf("object-instance:\n"
"This is the object instance number of the object that\n" "This is the object instance number of the object that\n"
"you are reading. For example, if you were reading\n" "you are reading. For example, if you were reading\n"
"Trend Log 2, the object-instance would be 2.\n"); "Trend Log 2, the object-instance would be 2.\n");
printf("\n"); printf("\n");
printf("property:\n" printf("property:\n"
"The property is an integer value of the enumeration\n" "The property is an integer value of the enumeration\n"
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n" "BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
"you are reading. For example, if you were reading the\n" "you are reading. For example, if you were reading the\n"
"Log_Buffer property, use 131 as the property.\n"); "Log_Buffer property, use 131 as the property.\n");
printf("\n"); printf("\n");
printf("range-type:\n" printf("range-type:\n"
"1=By Position\n" "1=By Position\n"
"2=By Sequence\n" "2=By Sequence\n"
"3=By Time\n" "3=By Time\n"
"4=All\n"); "4=All\n");
printf("\n"); printf("\n");
printf("index or date/time:\n" printf("index or date/time:\n"
"This integer parameter is the starting index, or date & time.\n"); "This integer parameter is the starting index, or date & time.\n");
printf("\n"); printf("\n");
printf("count:\n" printf("count:\n"
"This integer parameter is the number of elements to read.\n"); "This integer parameter is the number of elements to read.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf("Example:\n"
"If you want read the Log_Buffer of Trend Log 2\n" "If you want read the Log_Buffer of Trend Log 2\n"
"in Device 123, from starting position 1 and read 10 entries,\n" "in Device 123, from starting position 1 and read 10 entries,\n"
"you could send the following commands:\n"); "you could send the following commands:\n");
printf("%s 123 trend-log 2 log-buffer 1 1 10\n", filename); printf("%s 123 trend-log 2 log-buffer 1 1 10\n", filename);
printf("%s 123 trend-log 2 log-buffer 2 1 10\n", filename); printf("%s 123 trend-log 2 log-buffer 2 1 10\n", filename);
printf("%s 123 trend-log 2 log-buffer 3 1/1/2014 00:00:01 10\n", filename); printf("%s 123 trend-log 2 log-buffer 3 1/1/2014 00:00:01 10\n", filename);
@@ -238,7 +242,8 @@ int main(int argc, char *argv[])
Target_Object_Range_Type = strtol(argv[5], NULL, 0); Target_Object_Range_Type = strtol(argv[5], NULL, 0);
/* some bounds checking */ /* some bounds checking */
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\r\n", fprintf(
stderr, "device-instance=%u - not greater than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -270,8 +275,9 @@ int main(int argc, char *argv[])
RR_Request.RequestType = RR_BY_TIME; RR_Request.RequestType = RR_BY_TIME;
count = sscanf(argv[6], "%4d/%3d/%3d:%3d", &year, &month, &day, &wday); count = sscanf(argv[6], "%4d/%3d/%3d:%3d", &year, &month, &day, &wday);
if (count == 3) { if (count == 3) {
datetime_set_date(&RR_Request.Range.RefTime.date, (uint16_t)year, datetime_set_date(
(uint8_t)month, (uint8_t)day); &RR_Request.Range.RefTime.date, (uint16_t)year, (uint8_t)month,
(uint8_t)day);
} else if (count == 4) { } else if (count == 4) {
RR_Request.Range.RefTime.date.year = (uint16_t)year; RR_Request.Range.RefTime.date.year = (uint16_t)year;
RR_Request.Range.RefTime.date.month = (uint8_t)month; RR_Request.Range.RefTime.date.month = (uint8_t)month;
@@ -320,7 +326,7 @@ int main(int argc, char *argv[])
address_init(); address_init();
Init_Service_Handlers(); Init_Service_Handlers();
dlenv_init(); dlenv_init();
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__) #if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
/* Internationalized programs must call setlocale() /* Internationalized programs must call setlocale()
* to initiate a specific language operation. * to initiate a specific language operation.
* This can be done by calling setlocale() as follows. * This can be done by calling setlocale() as follows.
+27 -22
View File
@@ -44,7 +44,8 @@ static char *Reinitialize_Password = NULL;
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -52,7 +53,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
printf("BACnet Error: %s: %s\r\n", bactext_error_class_name(error_class), printf(
"BACnet Error: %s: %s\r\n", bactext_error_class_name(error_class),
bactext_error_code_name(error_code)); bactext_error_code_name(error_code));
Error_Detected = true; Error_Detected = true;
} }
@@ -68,8 +70,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -78,8 +80,8 @@ static void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyReinitializeDeviceSimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyReinitializeDeviceSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -101,7 +103,8 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the ack coming back */ /* handle the ack coming back */
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, apdu_set_confirmed_simple_ack_handler(
SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
MyReinitializeDeviceSimpleAckHandler); MyReinitializeDeviceSimpleAckHandler);
/* handle any errors coming back */ /* handle any errors coming back */
apdu_set_error_handler( apdu_set_error_handler(
@@ -125,20 +128,21 @@ int main(int argc, char *argv[])
if (argc < 3) { if (argc < 3) {
/* note: priority 16 and 0 should produce the same end results... */ /* note: priority 16 and 0 should produce the same end results... */
printf("Usage: %s device-instance state [password]\r\n" printf(
"Send BACnet ReinitializeDevice service to device.\r\n" "Usage: %s device-instance state [password]\r\n"
"\r\n" "Send BACnet ReinitializeDevice service to device.\r\n"
"The device-instance can be 0 to %d.\r\n" "\r\n"
"Possible state values:\r\n" "The device-instance can be 0 to %d.\r\n"
" 0=coldstart\r\n" "Possible state values:\r\n"
" 1=warmstart\r\n" " 0=coldstart\r\n"
" 2=startbackup\r\n" " 1=warmstart\r\n"
" 3=endbackup\r\n" " 2=startbackup\r\n"
" 4=startrestore\r\n" " 3=endbackup\r\n"
" 5=endrestore\r\n" " 4=startrestore\r\n"
" 6=abortrestore\r\n" " 5=endrestore\r\n"
"The optional password is a character string of 1 to 20 " " 6=abortrestore\r\n"
"characters.\r\n", "The optional password is a character string of 1 to 20 "
"characters.\r\n",
filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1); filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1);
return 0; return 0;
} }
@@ -151,7 +155,8 @@ int main(int argc, char *argv[])
} }
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\r\n", fprintf(
stderr, "device-instance=%u - not greater than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
+39 -27
View File
@@ -57,7 +57,8 @@ static bool Error_Detected = false;
/* Used for verbose */ /* Used for verbose */
static bool Verbose = false; static bool Verbose = false;
static void MyRemoveListElementErrorHandler(BACNET_ADDRESS *src, static void MyRemoveListElementErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
uint8_t service_choice, uint8_t service_choice,
uint8_t *service_request, uint8_t *service_request,
@@ -72,7 +73,8 @@ static void MyRemoveListElementErrorHandler(BACNET_ADDRESS *src,
len = list_element_error_ack_decode( len = list_element_error_ack_decode(
service_request, service_len, &list_element); service_request, service_len, &list_element);
if (len > 0) { if (len > 0) {
printf("BACnet Error: %s: %s [first-failed=%u]\n", printf(
"BACnet Error: %s: %s [first-failed=%u]\n",
bactext_error_class_name((int)list_element.error_class), bactext_error_class_name((int)list_element.error_class),
bactext_error_code_name((int)list_element.error_code), bactext_error_code_name((int)list_element.error_code),
(unsigned)list_element.first_failed_element_number); (unsigned)list_element.first_failed_element_number);
@@ -81,8 +83,8 @@ static void MyRemoveListElementErrorHandler(BACNET_ADDRESS *src,
} }
} }
static void MyRemoveListElementSimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyRemoveListElementSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -102,13 +104,14 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -130,7 +133,8 @@ static void Init_Service_Handlers(void)
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the ack or error coming back from confirmed request */ /* handle the ack or error coming back from confirmed request */
apdu_set_confirmed_simple_ack_handler( apdu_set_confirmed_simple_ack_handler(
SERVICE_CONFIRMED_ADD_LIST_ELEMENT, MyRemoveListElementSimpleAckHandler); SERVICE_CONFIRMED_ADD_LIST_ELEMENT,
MyRemoveListElementSimpleAckHandler);
apdu_set_complex_error_handler( apdu_set_complex_error_handler(
SERVICE_CONFIRMED_ADD_LIST_ELEMENT, MyRemoveListElementErrorHandler); SERVICE_CONFIRMED_ADD_LIST_ELEMENT, MyRemoveListElementErrorHandler);
apdu_set_abort_handler(MyAbortHandler); apdu_set_abort_handler(MyAbortHandler);
@@ -139,8 +143,9 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance " printf(
"property array-index tag value\n", "Usage: %s device-instance object-type object-instance "
"property array-index tag value\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help][--verbose]\n"); printf(" [--version][--help][--verbose]\n");
@@ -211,10 +216,11 @@ static void print_help(const char *filename)
"the Any property type in the schedule object and the Present Value\n" "the Any property type in the schedule object and the Present Value\n"
"accepting REAL, BOOLEAN, NULL, etc.\n"); "accepting REAL, BOOLEAN, NULL, etc.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"If you want to RemoveListElement to the Recipient-List property in\n" "Example:\n"
"Notification Class 1 of Device 123, send the following command:\n" "If you want to RemoveListElement to the Recipient-List property in\n"
"%s 123 15 1 102 -1 4 100\n", "Notification Class 1 of Device 123, send the following command:\n"
"%s 123 15 1 102 -1 4 100\n",
filename); filename);
} }
@@ -287,8 +293,8 @@ int main(int argc, char *argv[])
if (target_args == 0) { if (target_args == 0) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
object_instance, BACNET_MAX_INSTANCE); object_instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -305,8 +311,8 @@ int main(int argc, char *argv[])
} else if (target_args == 2) { } else if (target_args == 2) {
object_instance = strtoul(argv[argi], NULL, 0); object_instance = strtoul(argv[argi], NULL, 0);
if (object_instance > BACNET_MAX_INSTANCE) { if (object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, fprintf(
"device-instance=%u - not greater than %u\n", stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -330,7 +336,8 @@ int main(int argc, char *argv[])
property_array_index = strtol(argv[argi], NULL, 0); property_array_index = strtol(argv[argi], NULL, 0);
Target_Object_Array_Index = property_array_index; Target_Object_Array_Index = property_array_index;
if (Verbose) { if (Verbose) {
printf("Array_Index=%i=%s\n", property_array_index, printf(
"Array_Index=%i=%s\n", property_array_index,
argv[argi]); argv[argi]);
} }
target_args++; target_args++;
@@ -357,14 +364,16 @@ int main(int argc, char *argv[])
} else if (tag_value_arg == 1) { } else if (tag_value_arg == 1) {
value_string = argv[argi]; value_string = argv[argi];
if (Verbose) { if (Verbose) {
printf("tag=%ld value=%s\n", property_tag, value_string); printf(
"tag=%ld value=%s\n", property_tag, value_string);
} }
if (property_tag < 0) { if (property_tag < 0) {
/* find the application tag for internal properties */ /* find the application tag for internal properties */
property_tag = bacapp_known_property_tag( property_tag = bacapp_known_property_tag(
Target_Object_Type, Target_Object_Property); Target_Object_Type, Target_Object_Property);
} else if (property_tag >= MAX_BACNET_APPLICATION_TAG) { } else if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, fprintf(
stderr,
"Error: tag=%ld - it must be less than %u\n", "Error: tag=%ld - it must be less than %u\n",
property_tag, MAX_BACNET_APPLICATION_TAG); property_tag, MAX_BACNET_APPLICATION_TAG);
return 1; return 1;
@@ -374,13 +383,15 @@ int main(int argc, char *argv[])
status = bacapp_parse_application_data( status = bacapp_parse_application_data(
property_tag, value_string, application_value); property_tag, value_string, application_value);
if (!status) { if (!status) {
fprintf(stderr, fprintf(
stderr,
"Error: unable to parse the tag value\n"); "Error: unable to parse the tag value\n");
return 1; return 1;
} }
} else { } else {
/* FIXME: show the expected entry format for the tag */ /* FIXME: show the expected entry format for the tag */
fprintf(stderr, fprintf(
stderr,
"Error: unable to parse the known property" "Error: unable to parse the known property"
" \"%s\"\r\n", " \"%s\"\r\n",
value_string); value_string);
@@ -400,8 +411,7 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if (tag_value_arg != 0) { if (tag_value_arg != 0) {
fprintf( fprintf(stderr, "Error: invalid tag+value pair (%i).\n", tag_value_arg);
stderr, "Error: invalid tag+value pair (%i).\n", tag_value_arg);
return 1; return 1;
} }
/* setup my info */ /* setup my info */
@@ -422,7 +432,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance, &max_apdu, &Target_Address); Target_Device_Object_Instance, &max_apdu, &Target_Address);
if (found) { if (found) {
if (Verbose) { if (Verbose) {
printf("Found Device %u in address_cache.\n", printf(
"Found Device %u in address_cache.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
} else { } else {
@@ -435,7 +446,8 @@ int main(int argc, char *argv[])
/* device is bound! */ /* device is bound! */
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
if (Verbose) { if (Verbose) {
printf("Sending RemoveListElement to Device %u.\n", printf(
"Sending RemoveListElement to Device %u.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
Request_Invoke_ID = Send_Remove_List_Element_Request( Request_Invoke_ID = Send_Remove_List_Element_Request(
+42 -29
View File
@@ -303,7 +303,8 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
* *
* @return number of bytes sent * @return number of bytes sent
*/ */
static int datalink_send_pdu(uint16_t snet, static int datalink_send_pdu(
uint16_t snet,
BACNET_ADDRESS *dest, BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu, uint8_t *pdu,
@@ -347,7 +348,8 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
DNET *dnet = NULL; DNET *dnet = NULL;
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, npdu_encode_npdu_network(
&npdu_data, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK,
data_expecting_reply, MESSAGE_PRIORITY_NORMAL); data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
/* We don't need src information, since a message can't originate from /* We don't need src information, since a message can't originate from
our downstream BACnet network. */ our downstream BACnet network. */
@@ -398,8 +400,8 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
* Optionally may designate a particular router destination, * Optionally may designate a particular router destination,
* especially when ACKing receipt of this message type. * especially when ACKing receipt of this message type.
*/ */
static void send_initialize_routing_table_ack( static void
uint8_t snet, const BACNET_ADDRESS *dst) send_initialize_routing_table_ack(uint8_t snet, const BACNET_ADDRESS *dst)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
bool data_expecting_reply = false; bool data_expecting_reply = false;
@@ -415,8 +417,9 @@ static void send_initialize_routing_table_ack(
} else { } else {
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
} }
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK, npdu_encode_npdu_network(
data_expecting_reply, MESSAGE_PRIORITY_NORMAL); &npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK, data_expecting_reply,
MESSAGE_PRIORITY_NORMAL);
/* We don't need src information, since a message can't originate from /* We don't need src information, since a message can't originate from
our downstream BACnet network. */ our downstream BACnet network. */
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
@@ -475,9 +478,9 @@ static void send_reject_message_to_network(
} else { } else {
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
} }
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, data_expecting_reply, &npdu_data, NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK,
MESSAGE_PRIORITY_NORMAL); data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
/* We don't need src information, since a message can't originate from /* We don't need src information, since a message can't originate from
our downstream BACnet network. */ our downstream BACnet network. */
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
@@ -506,9 +509,9 @@ static void send_who_is_router_to_network(uint16_t snet, uint16_t dnet)
int len = 0; int len = 0;
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, data_expecting_reply, &npdu_data, NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
MESSAGE_PRIORITY_NORMAL); data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
if (dnet) { if (dnet) {
len = encode_unsigned16(&Tx_Buffer[pdu_len], dnet); len = encode_unsigned16(&Tx_Buffer[pdu_len], dnet);
@@ -574,7 +577,8 @@ static void send_who_is_router_to_network(uint16_t snet, uint16_t dnet)
* bytes that have already been decoded. * bytes that have already been decoded.
* @param npdu_len [in] The length of the remaining NPDU message in npdu[]. * @param npdu_len [in] The length of the remaining NPDU message in npdu[].
*/ */
static void who_is_router_to_network_handler(uint16_t snet, static void who_is_router_to_network_handler(
uint16_t snet,
const BACNET_ADDRESS *src, const BACNET_ADDRESS *src,
const BACNET_NPDU_DATA *npdu_data, const BACNET_NPDU_DATA *npdu_data,
const uint8_t *npdu, const uint8_t *npdu,
@@ -627,7 +631,8 @@ static void who_is_router_to_network_handler(uint16_t snet,
* bytes that have already been decoded. * bytes that have already been decoded.
* @param npdu_len [in] The length of the remaining NPDU message in npdu[]. * @param npdu_len [in] The length of the remaining NPDU message in npdu[].
*/ */
static void network_control_handler(uint16_t snet, static void network_control_handler(
uint16_t snet,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, uint8_t *npdu,
@@ -803,7 +808,8 @@ static void routed_src_address(
* @param apdu [in] The apdu portion of the request, to be processed. * @param apdu [in] The apdu portion of the request, to be processed.
* @param apdu_len [in] The total (remaining) length of the apdu. * @param apdu_len [in] The total (remaining) length of the apdu.
*/ */
static void routed_apdu_handler(uint16_t snet, static void routed_apdu_handler(
uint16_t snet,
BACNET_NPDU_DATA *npdu, BACNET_NPDU_DATA *npdu,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_ADDRESS *dest, BACNET_ADDRESS *dest,
@@ -842,7 +848,8 @@ static void routed_apdu_handler(uint16_t snet,
port = Router_Table_Head; port = Router_Table_Head;
while (port != NULL) { while (port != NULL) {
if (port->net != snet) { if (port->net != snet) {
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
port->net, &local_dest, npdu, &Tx_Buffer[0],
npdu_len + apdu_len); npdu_len + apdu_len);
} }
port = port->next; port = port->next;
@@ -869,7 +876,8 @@ static void routed_apdu_handler(uint16_t snet,
npdu_len = npdu_len =
npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu); npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu);
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
port->net, &local_dest, npdu, &Tx_Buffer[0],
npdu_len + apdu_len); npdu_len + apdu_len);
} else { } else {
debug_printf( debug_printf(
@@ -886,7 +894,8 @@ static void routed_apdu_handler(uint16_t snet,
npdu_len = npdu_len =
npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu); npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu);
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
datalink_send_pdu(port->net, &remote_dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
port->net, &remote_dest, npdu, &Tx_Buffer[0],
npdu_len + apdu_len); npdu_len + apdu_len);
} }
} else if (dest->net) { } else if (dest->net) {
@@ -902,8 +911,8 @@ static void routed_apdu_handler(uint16_t snet,
port = Router_Table_Head; port = Router_Table_Head;
while (port != NULL) { while (port != NULL) {
if (port->net != snet) { if (port->net != snet) {
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
npdu_len + apdu_len); port->net, dest, npdu, &Tx_Buffer[0], npdu_len + apdu_len);
} }
port = port->next; port = port->next;
} }
@@ -947,8 +956,9 @@ static void my_routing_npdu_handler(
fprintf(stderr, "NPDU: Decoding failed; Discarded!\n"); fprintf(stderr, "NPDU: Decoding failed; Discarded!\n");
} else if (npdu_data.network_layer_message) { } else if (npdu_data.network_layer_message) {
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) { if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
network_control_handler(snet, src, &npdu_data, network_control_handler(
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); snet, src, &npdu_data, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset));
} else { } else {
/* The DNET is set, but we don't support downstream routers, /* The DNET is set, but we don't support downstream routers,
* so we just silently drop this network layer message, * so we just silently drop this network layer message,
@@ -962,17 +972,19 @@ static void my_routing_npdu_handler(
routing information cause they are not for us */ routing information cause they are not for us */
if ((dest.net == BACNET_BROADCAST_NETWORK) && if ((dest.net == BACNET_BROADCAST_NETWORK) &&
((pdu[apdu_offset] & 0xF0) == ((pdu[apdu_offset] & 0xF0) ==
PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
/* hack for 5.4.5.1 - IDLE */ /* hack for 5.4.5.1 - IDLE */
/* ConfirmedBroadcastReceived */ /* ConfirmedBroadcastReceived */
/* then enter IDLE - ignore the PDU */ /* then enter IDLE - ignore the PDU */
} else { } else {
routed_apdu_handler(snet, &npdu_data, src, &dest, routed_apdu_handler(
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); snet, &npdu_data, src, &dest, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset));
/* add a Device object and application layer */ /* add a Device object and application layer */
if ((dest.net == 0) || if ((dest.net == 0) ||
(dest.net == BACNET_BROADCAST_NETWORK)) { (dest.net == BACNET_BROADCAST_NETWORK)) {
apdu_handler(src, &pdu[apdu_offset], apdu_handler(
src, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset)); (uint16_t)(pdu_len - apdu_offset));
} }
} }
@@ -984,7 +996,7 @@ static void my_routing_npdu_handler(
} else { } else {
fprintf( fprintf(
stderr, "NPDU: unsupported protocol version %u. Discarded!\n", stderr, "NPDU: unsupported protocol version %u. Discarded!\n",
protocol_version); protocol_version);
} }
return; return;
@@ -1026,8 +1038,9 @@ static void datalink_init(void)
pEnv = getenv("BACNET_BIP6_BROADCAST"); pEnv = getenv("BACNET_BIP6_BROADCAST");
if (pEnv) { if (pEnv) {
BACNET_IP6_ADDRESS addr; BACNET_IP6_ADDRESS addr;
bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, bvlc6_address_set(
0, BIP6_MULTICAST_GROUP_ID); &addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
bip6_set_broadcast_addr(&addr); bip6_set_broadcast_addr(&addr);
} }
if (!bip6_init(getenv("BACNET_BIP6_IFACE"))) { if (!bip6_init(getenv("BACNET_BIP6_IFACE"))) {
+38 -27
View File
@@ -324,7 +324,8 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
* *
* @return number of bytes sent * @return number of bytes sent
*/ */
static int datalink_send_pdu(uint16_t snet, static int datalink_send_pdu(
uint16_t snet,
BACNET_ADDRESS *dest, BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu, uint8_t *pdu,
@@ -368,7 +369,8 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
DNET *dnet = NULL; DNET *dnet = NULL;
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, npdu_encode_npdu_network(
&npdu_data, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK,
data_expecting_reply, MESSAGE_PRIORITY_NORMAL); data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
/* We don't need src information, since a message can't originate from /* We don't need src information, since a message can't originate from
our downstream BACnet network. */ our downstream BACnet network. */
@@ -419,8 +421,8 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
* Optionally may designate a particular router destination, * Optionally may designate a particular router destination,
* especially when ACKing receipt of this message type. * especially when ACKing receipt of this message type.
*/ */
static void send_initialize_routing_table_ack( static void
uint8_t snet, const BACNET_ADDRESS *dst) send_initialize_routing_table_ack(uint8_t snet, const BACNET_ADDRESS *dst)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
bool data_expecting_reply = false; bool data_expecting_reply = false;
@@ -436,8 +438,9 @@ static void send_initialize_routing_table_ack(
} else { } else {
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
} }
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK, npdu_encode_npdu_network(
data_expecting_reply, MESSAGE_PRIORITY_NORMAL); &npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK, data_expecting_reply,
MESSAGE_PRIORITY_NORMAL);
/* We don't need src information, since a message can't originate from /* We don't need src information, since a message can't originate from
our downstream BACnet network. */ our downstream BACnet network. */
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
@@ -496,9 +499,9 @@ static void send_reject_message_to_network(
} else { } else {
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
} }
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, data_expecting_reply, &npdu_data, NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK,
MESSAGE_PRIORITY_NORMAL); data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
/* We don't need src information, since a message can't originate from /* We don't need src information, since a message can't originate from
our downstream BACnet network. */ our downstream BACnet network. */
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
@@ -527,9 +530,9 @@ static void send_who_is_router_to_network(uint16_t snet, uint16_t dnet)
int len = 0; int len = 0;
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, data_expecting_reply, &npdu_data, NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
MESSAGE_PRIORITY_NORMAL); data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data); pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
if (dnet) { if (dnet) {
len = encode_unsigned16(&Tx_Buffer[pdu_len], dnet); len = encode_unsigned16(&Tx_Buffer[pdu_len], dnet);
@@ -595,7 +598,8 @@ static void send_who_is_router_to_network(uint16_t snet, uint16_t dnet)
* bytes that have already been decoded. * bytes that have already been decoded.
* @param npdu_len [in] The length of the remaining NPDU message in npdu[]. * @param npdu_len [in] The length of the remaining NPDU message in npdu[].
*/ */
static void who_is_router_to_network_handler(uint16_t snet, static void who_is_router_to_network_handler(
uint16_t snet,
const BACNET_ADDRESS *src, const BACNET_ADDRESS *src,
const BACNET_NPDU_DATA *npdu_data, const BACNET_NPDU_DATA *npdu_data,
const uint8_t *npdu, const uint8_t *npdu,
@@ -648,7 +652,8 @@ static void who_is_router_to_network_handler(uint16_t snet,
* bytes that have already been decoded. * bytes that have already been decoded.
* @param npdu_len [in] The length of the remaining NPDU message in npdu[]. * @param npdu_len [in] The length of the remaining NPDU message in npdu[].
*/ */
static void network_control_handler(uint16_t snet, static void network_control_handler(
uint16_t snet,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, uint8_t *npdu,
@@ -826,7 +831,8 @@ static void routed_src_address(
* @param apdu [in] The apdu portion of the request, to be processed. * @param apdu [in] The apdu portion of the request, to be processed.
* @param apdu_len [in] The total (remaining) length of the apdu. * @param apdu_len [in] The total (remaining) length of the apdu.
*/ */
static void routed_apdu_handler(uint16_t snet, static void routed_apdu_handler(
uint16_t snet,
BACNET_NPDU_DATA *npdu, BACNET_NPDU_DATA *npdu,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_ADDRESS *dest, BACNET_ADDRESS *dest,
@@ -865,7 +871,8 @@ static void routed_apdu_handler(uint16_t snet,
port = Router_Table_Head; port = Router_Table_Head;
while (port != NULL) { while (port != NULL) {
if (port->net != snet) { if (port->net != snet) {
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
port->net, &local_dest, npdu, &Tx_Buffer[0],
npdu_len + apdu_len); npdu_len + apdu_len);
} }
port = port->next; port = port->next;
@@ -892,7 +899,8 @@ static void routed_apdu_handler(uint16_t snet,
npdu_len = npdu_len =
npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu); npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu);
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
datalink_send_pdu(port->net, &local_dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
port->net, &local_dest, npdu, &Tx_Buffer[0],
npdu_len + apdu_len); npdu_len + apdu_len);
} else { } else {
log_printf( log_printf(
@@ -909,7 +917,8 @@ static void routed_apdu_handler(uint16_t snet,
npdu_len = npdu_len =
npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu); npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu);
memmove(&Tx_Buffer[npdu_len], apdu, apdu_len); memmove(&Tx_Buffer[npdu_len], apdu, apdu_len);
datalink_send_pdu(port->net, &remote_dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
port->net, &remote_dest, npdu, &Tx_Buffer[0],
npdu_len + apdu_len); npdu_len + apdu_len);
} }
} else if (dest->net) { } else if (dest->net) {
@@ -925,8 +934,8 @@ static void routed_apdu_handler(uint16_t snet,
port = Router_Table_Head; port = Router_Table_Head;
while (port != NULL) { while (port != NULL) {
if (port->net != snet) { if (port->net != snet) {
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0], datalink_send_pdu(
npdu_len + apdu_len); port->net, dest, npdu, &Tx_Buffer[0], npdu_len + apdu_len);
} }
port = port->next; port = port->next;
} }
@@ -966,8 +975,9 @@ static void my_routing_npdu_handler(
fprintf(stderr, "NPDU: Decoding failed; Discarded!\n"); fprintf(stderr, "NPDU: Decoding failed; Discarded!\n");
} else if (npdu_data.network_layer_message) { } else if (npdu_data.network_layer_message) {
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) { if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
network_control_handler(snet, src, &npdu_data, network_control_handler(
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); snet, src, &npdu_data, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset));
} else { } else {
/* The DNET is set, but we don't support downstream routers, /* The DNET is set, but we don't support downstream routers,
* so we just silently drop this network layer message, * so we just silently drop this network layer message,
@@ -981,17 +991,19 @@ static void my_routing_npdu_handler(
routing information cause they are not for us */ routing information cause they are not for us */
if ((dest.net == BACNET_BROADCAST_NETWORK) && if ((dest.net == BACNET_BROADCAST_NETWORK) &&
((pdu[apdu_offset] & 0xF0) == ((pdu[apdu_offset] & 0xF0) ==
PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
/* hack for 5.4.5.1 - IDLE */ /* hack for 5.4.5.1 - IDLE */
/* ConfirmedBroadcastReceived */ /* ConfirmedBroadcastReceived */
/* then enter IDLE - ignore the PDU */ /* then enter IDLE - ignore the PDU */
} else { } else {
routed_apdu_handler(snet, &npdu_data, src, &dest, routed_apdu_handler(
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset)); snet, &npdu_data, src, &dest, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset));
/* add a Device object and application layer */ /* add a Device object and application layer */
if ((dest.net == 0) || if ((dest.net == 0) ||
(dest.net == BACNET_BROADCAST_NETWORK)) { (dest.net == BACNET_BROADCAST_NETWORK)) {
apdu_handler(src, &pdu[apdu_offset], apdu_handler(
src, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset)); (uint16_t)(pdu_len - apdu_offset));
} }
} }
@@ -1151,7 +1163,6 @@ static void control_c_hooks(void)
} }
#endif #endif
#ifndef FUZZING #ifndef FUZZING
/** /**
* Main function of simple router demo. * Main function of simple router demo.
+23 -14
View File
@@ -17,9 +17,9 @@
#ifdef TEST_PACKET #ifdef TEST_PACKET
uint8_t test_packet[] = { 0x81, 0x0a, 0x00, 0x16, /* BVLC header */ uint8_t test_packet[] = { 0x81, 0x0a, 0x00, 0x16, /* BVLC header */
0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */ 0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x19, 0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00,
0x55 }; /* APDU */ 0x00, 0x02, 0x19, 0x55 }; /* APDU */
#endif #endif
void *dl_ip_thread(void *pArgs) void *dl_ip_thread(void *pArgs)
@@ -146,14 +146,16 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
/* setup socket options */ /* setup socket options */
socket_opt = 1; socket_opt = 1;
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt, status = setsockopt(
ip_data->socket, SOL_SOCKET, SO_REUSEADDR, &socket_opt,
sizeof(socket_opt)); sizeof(socket_opt));
if (status < 0) { if (status < 0) {
close(ip_data->socket); close(ip_data->socket);
return false; return false;
} }
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt, status = setsockopt(
ip_data->socket, SOL_SOCKET, SO_BROADCAST, &socket_opt,
sizeof(socket_opt)); sizeof(socket_opt));
if (status < 0) { if (status < 0) {
close(ip_data->socket); close(ip_data->socket);
@@ -162,8 +164,9 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
/* Bind to device so we don't get routing loops between our /* Bind to device so we don't get routing loops between our
different ports. */ different ports. */
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BINDTODEVICE, status = setsockopt(
port->iface, strlen(port->iface)); ip_data->socket, SOL_SOCKET, SO_BINDTODEVICE, port->iface,
strlen(port->iface));
if (status < 0) { if (status < 0) {
close(ip_data->socket); close(ip_data->socket);
return false; return false;
@@ -176,7 +179,8 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = ip_data->port; sin.sin_port = ip_data->port;
status = bind(ip_data->socket, (const struct sockaddr *)&sin, status = bind(
ip_data->socket, (const struct sockaddr *)&sin,
sizeof(struct sockaddr)); sizeof(struct sockaddr));
if (status < 0) { if (status < 0) {
close(ip_data->socket); close(ip_data->socket);
@@ -192,7 +196,8 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr)); PRINT(INFO, "IP Address: %s\n", inet_ntoa(ip_data->local_addr));
PRINT( PRINT(
INFO, "IP Broadcast Address: %s\n", inet_ntoa(ip_data->broadcast_addr)); INFO, "IP Broadcast Address: %s\n", inet_ntoa(ip_data->broadcast_addr));
PRINT(INFO, "UDP Port: 0x%04X [%hu]\n", (port->params.bip_params.port), PRINT(
INFO, "UDP Port: 0x%04X [%hu]\n", (port->params.bip_params.port),
(port->params.bip_params.port)); (port->params.bip_params.port));
return true; return true;
@@ -235,7 +240,8 @@ int dl_ip_send(
buff_len += pdu_len; buff_len += pdu_len;
/* send the packet */ /* send the packet */
bytes_sent = sendto(data->socket, (char *)data->buff, buff_len, 0, bytes_sent = sendto(
data->socket, (char *)data->buff, buff_len, 0,
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); (struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
PRINT(DEBUG, "send to %s\n", inet_ntoa(bip_dest.sin_addr)); PRINT(DEBUG, "send to %s\n", inet_ntoa(bip_dest.sin_addr));
@@ -279,8 +285,9 @@ int dl_ip_recv(
int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout); int ret = select(data->socket + 1, &read_fds, NULL, NULL, &select_timeout);
/* see if there is a packet for us */ /* see if there is a packet for us */
if (ret > 0) { if (ret > 0) {
received_bytes = recvfrom(data->socket, (char *)&data->buff[0], received_bytes = recvfrom(
data->max_buff, 0, (struct sockaddr *)&sin, &sin_len); data->socket, (char *)&data->buff[0], data->max_buff, 0,
(struct sockaddr *)&sin, &sin_len);
} else { } else {
return 0; return 0;
} }
@@ -319,7 +326,8 @@ int dl_ip_recv(
(*msg_data)->pdu_len = buff_len; (*msg_data)->pdu_len = buff_len;
(*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len); (*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len);
/* fill up data message structure */ /* fill up data message structure */
memmove(&(*msg_data)->pdu[0], &data->buff[4], memmove(
&(*msg_data)->pdu[0], &data->buff[4],
(*msg_data)->pdu_len); (*msg_data)->pdu_len);
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS)); memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
} }
@@ -352,7 +360,8 @@ int dl_ip_recv(
(*msg_data)->pdu_len = buff_len; (*msg_data)->pdu_len = buff_len;
(*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len); (*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len);
/* fill up data message structure */ /* fill up data message structure */
memmove(&(*msg_data)->pdu[0], &data->buff[4 + 6], memmove(
&(*msg_data)->pdu[0], &data->buff[4 + 6],
(*msg_data)->pdu_len); (*msg_data)->pdu_len);
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS)); memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
} else { } else {
+21 -26
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv * @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
* @date 2012 * @date 2012
* @brief Datalink IP module * @brief Datalink IP module
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef UDPMODULE_H #ifndef UDPMODULE_H
#define UDPMODULE_H #define UDPMODULE_H
@@ -17,9 +17,9 @@
#include "portthread.h" #include "portthread.h"
#include "bacnet/datalink/bip.h" #include "bacnet/datalink/bip.h"
#define MAX_BIP_APDU 1476 #define MAX_BIP_APDU 1476
#define MAX_BIP_PDU (MAX_NPDU + MAX_BIP_APDU) #define MAX_BIP_PDU (MAX_NPDU + MAX_BIP_APDU)
#define MAX_BIP_MPDU (BIP_HEADER_MAX + MAX_BIP_PDU) #define MAX_BIP_MPDU (BIP_HEADER_MAX + MAX_BIP_PDU)
/* Yes, we know this is longer than an Ethernet Frame, /* Yes, we know this is longer than an Ethernet Frame,
a UDP payload and an IPv6 packet. a UDP payload and an IPv6 packet.
Grandfathered in from BACnet Ethernet days, Grandfathered in from BACnet Ethernet days,
@@ -35,27 +35,22 @@ typedef struct ip_data {
uint16_t max_buff; uint16_t max_buff;
} IP_DATA; } IP_DATA;
void *dl_ip_thread(void *pArgs);
void *dl_ip_thread( bool dl_ip_init(ROUTER_PORT *port, IP_DATA *data);
void *pArgs);
bool dl_ip_init(
ROUTER_PORT * port,
IP_DATA * data);
int dl_ip_send( int dl_ip_send(
IP_DATA * data, IP_DATA *data,
const BACNET_ADDRESS * dest, const BACNET_ADDRESS *dest,
const uint8_t * pdu, const uint8_t *pdu,
unsigned pdu_len); unsigned pdu_len);
int dl_ip_recv( int dl_ip_recv(
IP_DATA * data, IP_DATA *data,
MSG_DATA ** msg, /* on recieve fill up message */ MSG_DATA **msg, /* on recieve fill up message */
BACNET_ADDRESS * src, BACNET_ADDRESS *src,
unsigned timeout); unsigned timeout);
void dl_ip_cleanup( void dl_ip_cleanup(IP_DATA *data);
IP_DATA * data);
#endif /* end of UDPMODULE_H */ #endif /* end of UDPMODULE_H */
+20 -12
View File
@@ -140,8 +140,8 @@ int main(int argc, char *argv[])
if (is_network_msg(bacmsg)) { if (is_network_msg(bacmsg)) {
msg_data->ref_count = 1; msg_data->ref_count = 1;
send_to_msgbox(msg_src, &msg_storage); send_to_msgbox(msg_src, &msg_storage);
} else if (msg_data->dest.net != } else if (
BACNET_BROADCAST_NETWORK) { msg_data->dest.net != BACNET_BROADCAST_NETWORK) {
msg_data->ref_count = 1; msg_data->ref_count = 1;
port = port =
find_dnet(msg_data->dest.net, &msg_data->dest); find_dnet(msg_data->dest.net, &msg_data->dest);
@@ -212,7 +212,8 @@ bool read_config(const char *filepath)
/* open configuration file */ /* open configuration file */
if (!config_read_file(&cfg, filepath)) { if (!config_read_file(&cfg, filepath)) {
PRINT(ERROR, "Config file error: %d - %s\n", config_error_line(&cfg), PRINT(
ERROR, "Config file error: %d - %s\n", config_error_line(&cfg),
config_error_text(&cfg)); config_error_text(&cfg));
config_destroy(&cfg); config_destroy(&cfg);
return false; return false;
@@ -261,13 +262,15 @@ bool read_config(const char *filepath)
fd = socket(AF_INET, SOCK_DGRAM, 0); fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd) { if (fd) {
struct ifreq ifr; struct ifreq ifr;
strncpy(ifr.ifr_name, current->iface, strncpy(
ifr.ifr_name, current->iface,
sizeof(ifr.ifr_name) - 1); sizeof(ifr.ifr_name) - 1);
result = ioctl(fd, SIOCGIFADDR, &ifr); result = ioctl(fd, SIOCGIFADDR, &ifr);
if (result != -1) { if (result != -1) {
close(fd); close(fd);
} else { } else {
PRINT(ERROR, PRINT(
ERROR,
"Error: Invalid interface for BIP device\n"); "Error: Invalid interface for BIP device\n");
return false; return false;
} }
@@ -304,7 +307,8 @@ bool read_config(const char *filepath)
if (fd != -1) { if (fd != -1) {
close(fd); close(fd);
} else { } else {
PRINT(ERROR, PRINT(
ERROR,
"Error: Invalid interface for MSTP device\n"); "Error: Invalid interface for MSTP device\n");
return false; return false;
} }
@@ -465,13 +469,15 @@ bool parse_cmd(int argc, char *argv[])
fd = socket(AF_INET, SOCK_DGRAM, 0); fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd) { if (fd) {
struct ifreq ifr; struct ifreq ifr;
strncpy(ifr.ifr_name, current->iface, strncpy(
ifr.ifr_name, current->iface,
sizeof(ifr.ifr_name) - 1); sizeof(ifr.ifr_name) - 1);
result = ioctl(fd, SIOCGIFADDR, &ifr); result = ioctl(fd, SIOCGIFADDR, &ifr);
if (result != -1) { if (result != -1) {
close(fd); close(fd);
} else { } else {
PRINT(ERROR, PRINT(
ERROR,
"Error: Invalid interface for BIP device \n"); "Error: Invalid interface for BIP device \n");
return false; return false;
} }
@@ -520,7 +526,8 @@ bool parse_cmd(int argc, char *argv[])
if (fd != -1) { if (fd != -1) {
close(fd); close(fd);
} else { } else {
PRINT(ERROR, PRINT(
ERROR,
"Error: Invalid interface for MSTP device\n"); "Error: Invalid interface for MSTP device\n");
return false; return false;
} }
@@ -755,8 +762,8 @@ uint16_t process_msg(BACMSG *msg, MSG_DATA *data, uint8_t **buff)
memmove(data, msg->data, sizeof(MSG_DATA)); memmove(data, msg->data, sizeof(MSG_DATA));
apdu_offset = bacnet_npdu_decode(data->pdu, data->pdu_len, &data->dest, apdu_offset = bacnet_npdu_decode(
&addr, &npdu_data); data->pdu, data->pdu_len, &data->dest, &addr, &npdu_data);
apdu_len = data->pdu_len - apdu_offset; apdu_len = data->pdu_len - apdu_offset;
srcport = find_snet(msg->origin); srcport = find_snet(msg->origin);
@@ -787,7 +794,8 @@ uint16_t process_msg(BACMSG *msg, MSG_DATA *data, uint8_t **buff)
*buff = (uint8_t *)malloc(buff_len); *buff = (uint8_t *)malloc(buff_len);
memmove(*buff, npdu, npdu_len); /* copy newly formed NPDU */ memmove(*buff, npdu, npdu_len); /* copy newly formed NPDU */
memmove(*buff + npdu_len, &data->pdu[apdu_offset], memmove(
*buff + npdu_len, &data->pdu[apdu_offset],
apdu_len); /* copy APDU */ apdu_len); /* copy APDU */
} else { } else {
+16 -31
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv * @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
* @date 2012 * @date 2012
* @brief Message queue module * @brief Message queue module
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef MSGQUEUE_H #ifndef MSGQUEUE_H
#define MSGQUEUE_H #define MSGQUEUE_H
@@ -27,16 +27,9 @@ extern pthread_mutex_t msg_lock;
typedef int MSGBOX_ID; typedef int MSGBOX_ID;
typedef enum { typedef enum { DATA = 1, SERVICE } MSGTYPE;
DATA = 1,
SERVICE
} MSGTYPE;
typedef enum { typedef enum { SHUTDOWN, CHG_IP, CHG_MAC } MSGSUBTYPE;
SHUTDOWN,
CHG_IP,
CHG_MAC
} MSGSUBTYPE;
typedef struct _message { typedef struct _message {
MSGTYPE type; MSGTYPE type;
@@ -58,25 +51,17 @@ typedef struct _msg_data {
MSGBOX_ID create_msgbox(void); MSGBOX_ID create_msgbox(void);
/* returns sent byte count */ /* returns sent byte count */
bool send_to_msgbox( bool send_to_msgbox(MSGBOX_ID dest, BACMSG *msg);
MSGBOX_ID dest,
BACMSG * msg);
/* returns received message */ /* returns received message */
BACMSG *recv_from_msgbox( BACMSG *recv_from_msgbox(MSGBOX_ID src, BACMSG *msg, int flags);
MSGBOX_ID src,
BACMSG * msg,
int flags);
void del_msgbox( void del_msgbox(MSGBOX_ID msgboxid);
MSGBOX_ID msgboxid);
/* free message data structure */ /* free message data structure */
void free_data( void free_data(MSG_DATA *data);
MSG_DATA * data);
/* check message reference counter and delete data if needed */ /* check message reference counter and delete data if needed */
void check_data( void check_data(MSG_DATA *data);
MSG_DATA * data);
#endif /* end of MSGQUEUE_H */ #endif /* end of MSGQUEUE_H */
+7 -4
View File
@@ -105,8 +105,9 @@ void *dl_mstp_thread(void *pArgs)
msg_data->dest.mac_len = 1; msg_data->dest.mac_len = 1;
} }
dlmstp_send_pdu(&mstp_port, &(msg_data->dest), dlmstp_send_pdu(
msg_data->pdu, msg_data->pdu_len); &mstp_port, &(msg_data->dest), msg_data->pdu,
msg_data->pdu_len);
check_data(msg_data); check_data(msg_data);
@@ -129,13 +130,15 @@ void *dl_mstp_thread(void *pArgs)
if (pdu_len > 0) { if (pdu_len > 0) {
msg_data = (MSG_DATA *)malloc(sizeof(MSG_DATA)); msg_data = (MSG_DATA *)malloc(sizeof(MSG_DATA));
memmove(&(msg_data->src), memmove(
&(msg_data->src),
(const void *)&(shared_port_data.Receive_Packet.address), (const void *)&(shared_port_data.Receive_Packet.address),
sizeof(shared_port_data.Receive_Packet.address)); sizeof(shared_port_data.Receive_Packet.address));
msg_data->src.adr[0] = msg_data->src.mac[0]; msg_data->src.adr[0] = msg_data->src.mac[0];
msg_data->src.len = 1; msg_data->src.len = 1;
msg_data->pdu = (uint8_t *)malloc(pdu_len); msg_data->pdu = (uint8_t *)malloc(pdu_len);
memmove(msg_data->pdu, memmove(
msg_data->pdu,
(const void *)&(shared_port_data.Receive_Packet.pdu), (const void *)&(shared_port_data.Receive_Packet.pdu),
pdu_len); pdu_len);
msg_data->pdu_len = pdu_len; msg_data->pdu_len = pdu_len;
+10 -11
View File
@@ -1,19 +1,18 @@
/** /**
* @file * @file
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv * @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
* @date 2012 * @date 2012
* @brief Datalink for MS/TP module * @brief Datalink for MS/TP module
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef MSTPMODULE_H #ifndef MSTPMODULE_H
#define MSTPMODULE_H #define MSTPMODULE_H
#include "portthread.h" #include "portthread.h"
void *dl_mstp_thread( void *dl_mstp_thread(void *pArgs);
void *pArgs);
#endif /* end of MSTPMODULE_H */ #endif /* end of MSTPMODULE_H */
+20 -12
View File
@@ -14,8 +14,8 @@
#include "network_layer.h" #include "network_layer.h"
#include "bacnet/bacint.h" #include "bacnet/bacint.h"
uint16_t process_network_message( uint16_t
const BACMSG *msg, MSG_DATA *data, uint8_t **buff) process_network_message(const BACMSG *msg, MSG_DATA *data, uint8_t **buff)
{ {
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
ROUTER_PORT *srcport; ROUTER_PORT *srcport;
@@ -28,8 +28,8 @@ uint16_t process_network_message(
memmove(data, msg->data, sizeof(MSG_DATA)); memmove(data, msg->data, sizeof(MSG_DATA));
apdu_offset = bacnet_npdu_decode(data->pdu, data->pdu_len, &data->dest, apdu_offset = bacnet_npdu_decode(
NULL, &npdu_data); data->pdu, data->pdu_len, &data->dest, NULL, &npdu_data);
apdu_len = data->pdu_len - apdu_offset; apdu_len = data->pdu_len - apdu_offset;
srcport = find_snet(msg->origin); srcport = find_snet(msg->origin);
@@ -71,9 +71,11 @@ uint16_t process_network_message(
int net_count = apdu_len / 2; int net_count = apdu_len / 2;
int i; int i;
for (i = 0; i < net_count; i++) { for (i = 0; i < net_count; i++) {
decode_unsigned16(&data->pdu[apdu_offset + 2 * i], decode_unsigned16(
&data->pdu[apdu_offset + 2 * i],
&net); /* decode received NET values */ &net); /* decode received NET values */
add_dnet(&srcport->route_info, net, add_dnet(
&srcport->route_info, net,
data->src); /* and update routing table */ data->src); /* and update routing table */
} }
break; break;
@@ -110,9 +112,11 @@ uint16_t process_network_message(
int net_count = data->pdu[apdu_offset]; int net_count = data->pdu[apdu_offset];
while (net_count--) { while (net_count--) {
int i = 1; int i = 1;
decode_unsigned16(&data->pdu[apdu_offset + i], decode_unsigned16(
&data->pdu[apdu_offset + i],
&net); /* decode received NET values */ &net); /* decode received NET values */
add_dnet(&srcport->route_info, net, add_dnet(
&srcport->route_info, net,
data->src); /* and update routing table */ data->src); /* and update routing table */
if (data->pdu[apdu_offset + i + 3] > if (data->pdu[apdu_offset + i + 3] >
0) { /* find next NET value */ 0) { /* find next NET value */
@@ -135,9 +139,11 @@ uint16_t process_network_message(
int net_count = data->pdu[apdu_offset]; int net_count = data->pdu[apdu_offset];
while (net_count--) { while (net_count--) {
int i = 1; int i = 1;
decode_unsigned16(&data->pdu[apdu_offset + i], decode_unsigned16(
&data->pdu[apdu_offset + i],
&net); /* decode received NET values */ &net); /* decode received NET values */
add_dnet(&srcport->route_info, net, add_dnet(
&srcport->route_info, net,
data->src); /* and update routing table */ data->src); /* and update routing table */
if (data->pdu[apdu_offset + i + 3] > if (data->pdu[apdu_offset + i + 3] >
0) { /* find next NET value */ 0) { /* find next NET value */
@@ -299,7 +305,8 @@ uint16_t create_network_message(
return buff_len; return buff_len;
} }
void send_network_message(BACNET_NETWORK_MESSAGE_TYPE network_message_type, void send_network_message(
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
MSG_DATA *data, MSG_DATA *data,
uint8_t **buff, uint8_t **buff,
void *val) void *val)
@@ -334,7 +341,8 @@ void send_network_message(BACNET_NETWORK_MESSAGE_TYPE network_message_type,
} }
} }
void init_npdu(BACNET_NPDU_DATA *npdu_data, void init_npdu(
BACNET_NPDU_DATA *npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_NETWORK_MESSAGE_TYPE network_message_type,
bool data_expecting_reply) bool data_expecting_reply)
{ {
+16 -18
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv * @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
* @date 2012 * @date 2012
* @brief Network layer for BACnet routing * @brief Network layer for BACnet routing
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef NETWORK_LAYER_H #ifndef NETWORK_LAYER_H
#define NETWORK_LAYER_H #define NETWORK_LAYER_H
@@ -24,25 +24,23 @@
#include "bacport.h" #include "bacport.h"
#include "portthread.h" #include "portthread.h"
uint16_t process_network_message( uint16_t
const BACMSG * msg, process_network_message(const BACMSG *msg, MSG_DATA *data, uint8_t **buff);
MSG_DATA * data,
uint8_t ** buff);
uint16_t create_network_message( uint16_t create_network_message(
BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_NETWORK_MESSAGE_TYPE network_message_type,
MSG_DATA * data, MSG_DATA *data,
uint8_t ** buff, uint8_t **buff,
void *val); void *val);
void send_network_message( void send_network_message(
BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_NETWORK_MESSAGE_TYPE network_message_type,
MSG_DATA * data, MSG_DATA *data,
uint8_t ** buff, uint8_t **buff,
void *val); void *val);
void init_npdu( void init_npdu(
BACNET_NPDU_DATA * npdu_data, BACNET_NPDU_DATA *npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_NETWORK_MESSAGE_TYPE network_message_type,
bool data_expecting_reply); bool data_expecting_reply);
+22 -41
View File
@@ -1,13 +1,13 @@
/** /**
* @file * @file
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv * @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
* @date 2012 * @date 2012
* @brief Network port storage and handling * @brief Network port storage and handling
* *
* @section LICENSE * @section LICENSE
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#ifndef PORTTHREAD_H #ifndef PORTTHREAD_H
#define PORTTHREAD_H #define PORTTHREAD_H
@@ -27,33 +27,21 @@
#define DEBUG_LEVEL 3 #define DEBUG_LEVEL 3
#ifdef DEBUG_LEVEL #ifdef DEBUG_LEVEL
#define PRINT(debug_level, ...) if(debug_level <= DEBUG_LEVEL) fprintf(stderr, __VA_ARGS__) #define PRINT(debug_level, ...) \
if (debug_level <= DEBUG_LEVEL) \
fprintf(stderr, __VA_ARGS__)
#else #else
#define PRINT(...) #define PRINT(...)
#endif #endif
typedef enum { typedef enum { BIP = 1, MSTP = 2 } DL_TYPE;
BIP = 1,
MSTP = 2
} DL_TYPE;
typedef enum { typedef enum { INIT, INIT_FAILED, RUNNING, FINISHED } PORT_STATE;
INIT,
INIT_FAILED,
RUNNING,
FINISHED
} PORT_STATE;
/* router port thread function */ /* router port thread function */
typedef void *( typedef void *(*PORT_FUNC)(void *);
*PORT_FUNC) (
void *);
typedef enum { typedef enum { PARITY_NONE, PARITY_EVEN, PARITY_ODD } PARITY;
PARITY_NONE,
PARITY_EVEN,
PARITY_ODD
} PARITY;
/* port specific parameters */ /* port specific parameters */
typedef union _port_params { typedef union _port_params {
@@ -90,8 +78,8 @@ typedef struct _routing_table_entry {
typedef struct _port { typedef struct _port {
DL_TYPE type; DL_TYPE type;
PORT_STATE state; PORT_STATE state;
MSGBOX_ID main_id; /* same for every router port */ MSGBOX_ID main_id; /* same for every router port */
MSGBOX_ID port_id; /* different for every router port */ MSGBOX_ID port_id; /* different for every router port */
char *iface; char *iface;
PORT_FUNC func; PORT_FUNC func;
RT_ENTRY route_info; RT_ENTRY route_info;
@@ -103,21 +91,14 @@ extern ROUTER_PORT *head;
extern int port_count; extern int port_count;
/* get recieving router port */ /* get recieving router port */
ROUTER_PORT *find_snet( ROUTER_PORT *find_snet(MSGBOX_ID id);
MSGBOX_ID id);
/* get sending router port */ /* get sending router port */
ROUTER_PORT *find_dnet( ROUTER_PORT *find_dnet(uint16_t net, BACNET_ADDRESS *addr);
uint16_t net,
BACNET_ADDRESS * addr);
/* add reacheble network for specified router port */ /* add reacheble network for specified router port */
void add_dnet( void add_dnet(RT_ENTRY *route_info, uint16_t net, BACNET_ADDRESS addr);
RT_ENTRY * route_info,
uint16_t net,
BACNET_ADDRESS addr);
void cleanup_dnets( void cleanup_dnets(DNET *dnets);
DNET * dnets);
#endif /* end of PORTTHREAD_H */ #endif /* end of PORTTHREAD_H */
+57 -40
View File
@@ -59,14 +59,16 @@ BACNET_SUBSCRIBE_COV_DATA *COV_Subscribe_Data = NULL;
static bool Simple_Ack_Detected = false; static bool Simple_Ack_Detected = false;
static bool Cancel_Requested = false; static bool Cancel_Requested = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -79,18 +81,19 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\n", printf(
bactext_abort_reason_name((int)abort_reason)); "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -102,7 +105,8 @@ static void My_Unconfirmed_COV_Notification_Handler(
handler_ucov_notification(service_request, service_len, src); handler_ucov_notification(service_request, service_len, src);
} }
static void My_Confirmed_COV_Notification_Handler(uint8_t *service_request, static void My_Confirmed_COV_Notification_Handler(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
@@ -110,8 +114,8 @@ static void My_Confirmed_COV_Notification_Handler(uint8_t *service_request,
handler_ccov_notification(service_request, service_len, src, service_data); handler_ccov_notification(service_request, service_len, src, service_data);
} }
static void MyWritePropertySimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -135,9 +139,11 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the data coming back from COV subscriptions */ /* handle the data coming back from COV subscriptions */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_COV_NOTIFICATION, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_COV_NOTIFICATION,
My_Confirmed_COV_Notification_Handler); My_Confirmed_COV_Notification_Handler);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION,
My_Unconfirmed_COV_Notification_Handler); My_Unconfirmed_COV_Notification_Handler);
/* handle the Simple ack coming back from SubscribeCOV */ /* handle the Simple ack coming back from SubscribeCOV */
apdu_set_confirmed_simple_ack_handler( apdu_set_confirmed_simple_ack_handler(
@@ -163,55 +169,62 @@ static void cleanup(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-id object-type object-instance " printf(
"process-id <[un]confirmed lifetime|cancel>\n", "Usage: %s device-id object-type object-instance "
"process-id <[un]confirmed lifetime|cancel>\n",
filename); filename);
} }
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Subscribe to a BACnet object for Change-of-Value notifications\n" printf("Subscribe to a BACnet object for Change-of-Value notifications\n"
"in a BACnet device and print the Change-of-Value notifications.\n"); "in a BACnet device and print the Change-of-Value notifications.\n");
printf("\n"); printf("\n");
printf("device-id:\n" printf("device-id:\n"
"The subscriber BACnet Device Object Instance number.\n"); "The subscriber BACnet Device Object Instance number.\n");
printf("\n"); printf("\n");
printf("object-type:\n" printf("object-type:\n"
"The object type is object that you are reading. It\n" "The object type is object that you are reading. It\n"
"can be defined either as the object-type name string\n" "can be defined either as the object-type name string\n"
"as defined in the BACnet specification, or as the\n" "as defined in the BACnet specification, or as the\n"
"integer value of the enumeration BACNET_OBJECT_TYPE\n" "integer value of the enumeration BACNET_OBJECT_TYPE\n"
"in bacenum.h. For example if you were reading Analog\n" "in bacenum.h. For example if you were reading Analog\n"
"Output 2, the object-type would be analog-output or 1.\n"); "Output 2, the object-type would be analog-output or 1.\n");
printf("\n"); printf("\n");
printf("object-instance:\n" printf("object-instance:\n"
"The monitored object instance number.\n"); "The monitored object instance number.\n");
printf("\n"); printf("\n");
printf("process-id:\n" printf("process-id:\n"
"Process Identifier for this COV subscription.\n"); "Process Identifier for this COV subscription.\n");
printf("\n"); printf("\n");
printf("confirmed:\n" printf("confirmed:\n"
"Optional flag to subscribe using Confirmed notifications.\n" "Optional flag to subscribe using Confirmed notifications.\n"
"Use the word \'confirmed\' or \'unconfirmed\'.\n"); "Use the word \'confirmed\' or \'unconfirmed\'.\n");
printf("\n"); printf("\n");
printf("lifetime:\n" printf("lifetime:\n"
"Optional subscription lifetime is conveyed in seconds.\n"); "Optional subscription lifetime is conveyed in seconds.\n");
printf("\n"); printf("\n");
printf("cancel:\n" printf("cancel:\n"
"Use the word \'cancel\' instead of confirm and lifetime.\n" "Use the word \'cancel\' instead of confirm and lifetime.\n"
"This shall indicate a cancellation request.\n"); "This shall indicate a cancellation request.\n");
printf("\n"); printf("\n");
printf("Examples:\n"); printf("Examples:\n");
printf("If you want subscribe to Device 123 Analog Input 9 object\n" printf(
"If you want subscribe to Device 123 Analog Input 9 object\n"
"using confirmed COV notifications for 5 minutes,\n" "using confirmed COV notifications for 5 minutes,\n"
"you could send the following command:\n" "you could send the following command:\n"
"%s 123 0 9 1 confirmed 600\n", filename); "%s 123 0 9 1 confirmed 600\n",
printf("To send the same COV subscription request for unconfirmed\n" filename);
printf(
"To send the same COV subscription request for unconfirmed\n"
"notifications, send the following command:\n" "notifications, send the following command:\n"
"%s 123 0 9 1 unconfirmed 600\n", filename); "%s 123 0 9 1 unconfirmed 600\n",
printf("To cancel the same COV subscription request,\n" filename);
printf(
"To cancel the same COV subscription request,\n"
"send the following command:\n" "send the following command:\n"
"%s 123 0 9 1 cancel\n", filename); "%s 123 0 9 1 cancel\n",
filename);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@@ -255,7 +268,8 @@ int main(int argc, char *argv[])
/* decode the command line parameters */ /* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0); Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -271,7 +285,8 @@ int main(int argc, char *argv[])
cov_data->monitoredObjectIdentifier.type = (uint16_t)uint; cov_data->monitoredObjectIdentifier.type = (uint16_t)uint;
if (cov_data->monitoredObjectIdentifier.type >= if (cov_data->monitoredObjectIdentifier.type >=
MAX_BACNET_OBJECT_TYPE) { MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\n", fprintf(
stderr, "object-type=%u - it must be less than %u\n",
cov_data->monitoredObjectIdentifier.type, cov_data->monitoredObjectIdentifier.type,
MAX_BACNET_OBJECT_TYPE); MAX_BACNET_OBJECT_TYPE);
return 1; return 1;
@@ -281,7 +296,8 @@ int main(int argc, char *argv[])
strtol(argv[argi], NULL, 0); strtol(argv[argi], NULL, 0);
if (cov_data->monitoredObjectIdentifier.instance > if (cov_data->monitoredObjectIdentifier.instance >
BACNET_MAX_INSTANCE) { BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - not greater than %u\n", fprintf(
stderr, "object-instance=%u - not greater than %u\n",
cov_data->monitoredObjectIdentifier.instance, cov_data->monitoredObjectIdentifier.instance,
BACNET_MAX_INSTANCE); BACNET_MAX_INSTANCE);
return 1; return 1;
@@ -376,8 +392,9 @@ int main(int argc, char *argv[])
/* increase the timeout to the longest lifetime */ /* increase the timeout to the longest lifetime */
timeout_seconds = cov_data->lifetime; timeout_seconds = cov_data->lifetime;
} }
printf("Sent SubscribeCOV request. " printf(
" Waiting up to %u seconds....\n", "Sent SubscribeCOV request. "
" Waiting up to %u seconds....\n",
(unsigned)(timeout_seconds - elapsed_seconds)); (unsigned)(timeout_seconds - elapsed_seconds));
} else if (tsm_invoke_id_free(Request_Invoke_ID)) { } else if (tsm_invoke_id_free(Request_Invoke_ID)) {
if (cov_data->next) { if (cov_data->next) {
+31 -23
View File
@@ -68,17 +68,18 @@ static void print_help(const char *filename)
"you are reading. For example, if you were reading\n" "you are reading. For example, if you were reading\n"
"Analog Output 2, the object-instance would be 2.\n"); "Analog Output 2, the object-instance would be 2.\n");
PRINTF("\n"); PRINTF("\n");
PRINTF("Example:\n" PRINTF(
"If you want read the Present-Value of Analog Output 101\n" "Example:\n"
"in Device 123, you could send either of the following\n" "If you want read the Present-Value of Analog Output 101\n"
"commands:\n" "in Device 123, you could send either of the following\n"
"%s 123 analog-output 101\n" "commands:\n"
"%s 123 1 101\n" "%s 123 analog-output 101\n"
"If you want read the Present-Value of Binary Input 1\n" "%s 123 1 101\n"
"in Device 123, you could send either of the following\n" "If you want read the Present-Value of Binary Input 1\n"
"commands:\n" "in Device 123, you could send either of the following\n"
"%s 123 binary-input 1\n" "commands:\n"
"%s 123 3 1\n", "%s 123 binary-input 1\n"
"%s 123 3 1\n",
filename, filename, filename, filename); filename, filename, filename, filename);
} }
@@ -125,8 +126,9 @@ int main(int argc, char *argv[])
if (++argi < argc) { if (++argi < argc) {
device_id = strtol(argv[argi], NULL, 0); device_id = strtol(argv[argi], NULL, 0);
if (device_id > BACNET_MAX_INSTANCE) { if (device_id > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device=%u - not greater than %u\n", fprintf(
device_id, BACNET_MAX_INSTANCE); stderr, "device=%u - not greater than %u\n", device_id,
BACNET_MAX_INSTANCE);
return 1; return 1;
} }
} }
@@ -161,22 +163,25 @@ int main(int argc, char *argv[])
} }
Device_Set_Object_Instance_Number(device_id); Device_Set_Object_Instance_Number(device_id);
if (target_device_object_instance > BACNET_MAX_INSTANCE) { if (target_device_object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
target_device_object_instance, BACNET_MAX_INSTANCE); target_device_object_instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
PRINTF("BACnet Server-Client Demo\n" PRINTF(
"BACnet Stack Version %s\n" "BACnet Server-Client Demo\n"
"BACnet Device ID: %u\n" "BACnet Stack Version %s\n"
"Max APDU: %d\n", "BACnet Device ID: %u\n"
"Max APDU: %d\n",
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU); BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
fflush(stdout); fflush(stdout);
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
bacnet_task_init(); bacnet_task_init();
bacnet_data_poll_seconds_set(print_seconds); bacnet_data_poll_seconds_set(print_seconds);
if (!bacnet_data_object_add(target_device_object_instance, if (!bacnet_data_object_add(
target_object_type, target_object_instance)) { target_device_object_instance, target_object_type,
target_object_instance)) {
return 1; return 1;
} }
mstimer_set(&print_value_timer, print_seconds * 1000); mstimer_set(&print_value_timer, print_seconds * 1000);
@@ -192,7 +197,8 @@ int main(int argc, char *argv[])
if (bacnet_data_analog_present_value( if (bacnet_data_analog_present_value(
target_device_object_instance, target_object_type, target_device_object_instance, target_object_type,
target_object_instance, &float_value)) { target_object_instance, &float_value)) {
PRINTF("Device %u %s-%u=%f\n", PRINTF(
"Device %u %s-%u=%f\n",
(unsigned)target_device_object_instance, (unsigned)target_device_object_instance,
bactext_object_type_name(target_object_type), bactext_object_type_name(target_object_type),
(unsigned)target_object_instance, float_value); (unsigned)target_object_instance, float_value);
@@ -204,7 +210,8 @@ int main(int argc, char *argv[])
if (bacnet_data_binary_present_value( if (bacnet_data_binary_present_value(
target_device_object_instance, target_object_type, target_device_object_instance, target_object_type,
target_object_instance, &bool_value)) { target_object_instance, &bool_value)) {
PRINTF("Device %u %s-%u=%s\n", PRINTF(
"Device %u %s-%u=%s\n",
(unsigned)target_device_object_instance, (unsigned)target_device_object_instance,
bactext_object_type_name(target_object_type), bactext_object_type_name(target_object_type),
(unsigned)target_object_instance, (unsigned)target_object_instance,
@@ -217,7 +224,8 @@ int main(int argc, char *argv[])
if (bacnet_data_multistate_present_value( if (bacnet_data_multistate_present_value(
target_device_object_instance, target_object_type, target_device_object_instance, target_object_type,
target_object_instance, &unsigned_value)) { target_object_instance, &unsigned_value)) {
PRINTF("Device %u %s-%u=%u\n", PRINTF(
"Device %u %s-%u=%u\n",
(unsigned)target_device_object_instance, (unsigned)target_device_object_instance,
bactext_object_type_name(target_object_type), bactext_object_type_name(target_object_type),
(unsigned)target_object_instance, (unsigned)target_object_instance,
+20 -15
View File
@@ -80,8 +80,9 @@ static void print_discovered_devices(void)
milliseconds = bacnet_discover_device_elapsed_milliseconds(device_id); milliseconds = bacnet_discover_device_elapsed_milliseconds(device_id);
heap_ram = bacnet_discover_device_memory(device_id); heap_ram = bacnet_discover_device_memory(device_id);
/* convert to KB next highest value */ /* convert to KB next highest value */
bacnet_discover_property_name(device_id, OBJECT_DEVICE, device_id, bacnet_discover_property_name(
PROP_MODEL_NAME, model_name, sizeof(model_name), ""); device_id, OBJECT_DEVICE, device_id, PROP_MODEL_NAME, model_name,
sizeof(model_name), "");
printf( printf(
"device[%u] %7u \"%s\" object_list[%d] in %lums using %lu bytes\n", "device[%u] %7u \"%s\" object_list[%d] in %lums using %lu bytes\n",
device_index, device_id, model_name, object_count, milliseconds, device_index, device_id, model_name, object_count, milliseconds,
@@ -94,10 +95,11 @@ static void print_discovered_devices(void)
device_id, object_index, &object_id)) { device_id, object_index, &object_id)) {
property_count = bacnet_discover_object_property_count( property_count = bacnet_discover_object_property_count(
device_id, object_id.type, object_id.instance); device_id, object_id.type, object_id.instance);
bacnet_discover_property_name(device_id, object_id.type, bacnet_discover_property_name(
object_id.instance, PROP_OBJECT_NAME, object_name, device_id, object_id.type, object_id.instance,
sizeof(object_name), ""); PROP_OBJECT_NAME, object_name, sizeof(object_name), "");
printf(" object_list[%d] %s %u \"%s\" has %u properties\n", printf(
" object_list[%d] %s %u \"%s\" has %u properties\n",
object_index, bactext_object_type_name(object_id.type), object_index, bactext_object_type_name(object_id.type),
object_id.instance, object_name, property_count); object_id.instance, object_name, property_count);
} }
@@ -160,7 +162,8 @@ static void bacnet_server_init(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple); SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
mstimer_set(&BACnet_Task_Timer, 1000); mstimer_set(&BACnet_Task_Timer, 1000);
mstimer_set(&BACnet_TSM_Timer, 50); mstimer_set(&BACnet_TSM_Timer, 50);
@@ -254,17 +257,19 @@ int main(int argc, char *argv[])
} }
} }
if (device_id > BACNET_MAX_INSTANCE) { if (device_id > BACNET_MAX_INSTANCE) {
debug_perror("device-instance=%u - not greater than %u\n", debug_perror(
device_id, BACNET_MAX_INSTANCE); "device-instance=%u - not greater than %u\n", device_id,
BACNET_MAX_INSTANCE);
return 1; return 1;
} }
Device_Set_Object_Instance_Number(device_id); Device_Set_Object_Instance_Number(device_id);
debug_aprintf("BACnet Server-Discovery Demo\n" debug_aprintf(
"BACnet Stack Version %s\n" "BACnet Server-Discovery Demo\n"
"BACnet Device ID: %u\n" "BACnet Stack Version %s\n"
"DNET: %u every %lu seconds\n" "BACnet Device ID: %u\n"
"Print Devices: every %lu seconds (0=none)\n" "DNET: %u every %lu seconds\n"
"Max APDU: %d\n", "Print Devices: every %lu seconds (0=none)\n"
"Max APDU: %d\n",
BACnet_Version, Device_Object_Instance_Number(), dnet, discover_seconds, BACnet_Version, Device_Object_Instance_Number(), dnet, discover_seconds,
print_seconds, MAX_APDU); print_seconds, MAX_APDU);
dlenv_init(); dlenv_init();
+35 -28
View File
@@ -106,16 +106,15 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
#define LIGHTING_OBJECT_RELAY OBJECT_BINARY_OUTPUT #define LIGHTING_OBJECT_RELAY OBJECT_BINARY_OUTPUT
#endif #endif
static BACNET_SUBORDINATE_DATA Lighting_Subordinate[] = static BACNET_SUBORDINATE_DATA Lighting_Subordinate[] = {
{ { 0, LIGHTING_OBJECT_WATTS, 1, "watt-hours", 0, 0, NULL },
{0, LIGHTING_OBJECT_WATTS, 1, "watt-hours", 0, 0, NULL}, { 0, LIGHTING_OBJECT_ADR, 1, "demand-response", 0, 0, NULL },
{0, LIGHTING_OBJECT_ADR, 1, "demand-response", 0, 0, NULL}, { 0, LIGHTING_OBJECT_SCENE, 1, "scene", 0, 0, NULL },
{0, LIGHTING_OBJECT_SCENE, 1, "scene", 0, 0, NULL}, { 0, LIGHTING_OBJECT_LIGHT, 1, "light", 0, 0, NULL },
{0, LIGHTING_OBJECT_LIGHT, 1, "light", 0, 0, NULL}, { 0, LIGHTING_OBJECT_RELAY, 1, "relay", 0, 0, NULL },
{0, LIGHTING_OBJECT_RELAY, 1, "relay", 0, 0, NULL},
#if (BACNET_PROTOCOL_REVISION >= 24) #if (BACNET_PROTOCOL_REVISION >= 24)
{0, OBJECT_COLOR, 1, "color", 0, 0, NULL}, { 0, OBJECT_COLOR, 1, "color", 0, 0, NULL },
{0, OBJECT_COLOR_TEMPERATURE, 1, "color-temperature", 0, 0, NULL}, { 0, OBJECT_COLOR_TEMPERATURE, 1, "color-temperature", 0, 0, NULL },
#endif #endif
}; };
@@ -132,8 +131,8 @@ static void Structured_View_Update(void)
device_id = Device_Object_Instance_Number(); device_id = Device_Object_Instance_Number();
for (i = 0; i < ARRAY_SIZE(Lighting_Subordinate); i++) { for (i = 0; i < ARRAY_SIZE(Lighting_Subordinate); i++) {
/* link the lists */ /* link the lists */
if (i < (ARRAY_SIZE(Lighting_Subordinate)-1)) { if (i < (ARRAY_SIZE(Lighting_Subordinate) - 1)) {
Lighting_Subordinate[i].next = &Lighting_Subordinate[i+1]; Lighting_Subordinate[i].next = &Lighting_Subordinate[i + 1];
} }
/* update the device instance to internal */ /* update the device instance to internal */
Lighting_Subordinate[i].Device_Instance = device_id; Lighting_Subordinate[i].Device_Instance = device_id;
@@ -168,7 +167,8 @@ static void Init_Service_Handlers(void)
for (i = 0; i <= BACNET_OBJECT_TYPE_LAST; i++) { for (i = 0; i <= BACNET_OBJECT_TYPE_LAST; i++) {
object_data.object_type = i; object_data.object_type = i;
if (Device_Create_Object(&object_data)) { if (Device_Create_Object(&object_data)) {
printf("Created object %s-%u\n", bactext_object_type_name(i), printf(
"Created object %s-%u\n", bactext_object_type_name(i),
(unsigned)object_data.object_instance); (unsigned)object_data.object_instance);
} }
} }
@@ -224,10 +224,12 @@ static void Init_Service_Handlers(void)
apdu_set_unconfirmed_handler( apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
/* handle the data coming back from private requests */ /* handle the data coming back from private requests */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
handler_unconfirmed_private_transfer); handler_unconfirmed_private_transfer);
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
@@ -247,10 +249,10 @@ static void Init_Service_Handlers(void)
/* configure the cyclic timers */ /* configure the cyclic timers */
mstimer_set(&BACnet_Task_Timer, 1000UL); mstimer_set(&BACnet_Task_Timer, 1000UL);
mstimer_set(&BACnet_TSM_Timer, 50UL); mstimer_set(&BACnet_TSM_Timer, 50UL);
mstimer_set(&BACnet_Address_Timer, 60UL*1000UL); mstimer_set(&BACnet_Address_Timer, 60UL * 1000UL);
mstimer_set(&BACnet_Object_Timer, 100UL); mstimer_set(&BACnet_Object_Timer, 100UL);
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
mstimer_set(&BACnet_Notification_Timer, NC_RESCAN_RECIPIENTS_SECS*1000UL); mstimer_set(&BACnet_Notification_Timer, NC_RESCAN_RECIPIENTS_SECS * 1000UL);
#endif #endif
} }
@@ -269,11 +271,13 @@ static void print_help(const char *filename)
"device-name:\n" "device-name:\n"
"The Device object-name is the text name for the device.\n" "The Device object-name is the text name for the device.\n"
"\nExample:\n"); "\nExample:\n");
printf("To simulate Device 123, use the following command:\n" printf(
"%s 123\n", "To simulate Device 123, use the following command:\n"
"%s 123\n",
filename); filename);
printf("To simulate Device 123 named Fred, use following command:\n" printf(
"%s 123 Fred\n", "To simulate Device 123 named Fred, use following command:\n"
"%s 123 Fred\n",
filename); filename);
} }
@@ -325,8 +329,9 @@ int main(int argc, char *argv[])
} }
#if defined(BAC_UCI) #if defined(BAC_UCI)
ctx = ucix_init("bacnet_dev"); ctx = ucix_init("bacnet_dev");
if (!ctx) if (!ctx) {
fprintf(stderr, "Failed to load config file bacnet_dev\n"); fprintf(stderr, "Failed to load config file bacnet_dev\n");
}
uciId = ucix_get_option_int(ctx, "bacnet_dev", "0", "Id", 0); uciId = ucix_get_option_int(ctx, "bacnet_dev", "0", "Id", 0);
if (uciId != 0) { if (uciId != 0) {
Device_Set_Object_Instance_Number(uciId); Device_Set_Object_Instance_Number(uciId);
@@ -342,10 +347,11 @@ int main(int argc, char *argv[])
ucix_cleanup(ctx); ucix_cleanup(ctx);
#endif /* defined(BAC_UCI) */ #endif /* defined(BAC_UCI) */
printf("BACnet Server Demo\n" printf(
"BACnet Stack Version %s\n" "BACnet Server Demo\n"
"BACnet Device ID: %u\n" "BACnet Stack Version %s\n"
"Max APDU: %d\n", "BACnet Device ID: %u\n"
"Max APDU: %d\n",
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU); BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
/* load any static address bindings to show up /* load any static address bindings to show up
in our device bindings list */ in our device bindings list */
@@ -357,8 +363,9 @@ int main(int argc, char *argv[])
#if defined(BAC_UCI) #if defined(BAC_UCI)
const char *uciname; const char *uciname;
ctx = ucix_init("bacnet_dev"); ctx = ucix_init("bacnet_dev");
if (!ctx) if (!ctx) {
fprintf(stderr, "Failed to load config file bacnet_dev\n"); fprintf(stderr, "Failed to load config file bacnet_dev\n");
}
uciname = ucix_get_option(ctx, "bacnet_dev", "0", "Name"); uciname = ucix_get_option(ctx, "bacnet_dev", "0", "Name");
if (uciname != 0) { if (uciname != 0) {
Device_Object_Name_ANSI_Init(uciname); Device_Object_Name_ANSI_Init(uciname);
@@ -390,7 +397,7 @@ int main(int argc, char *argv[])
if (mstimer_expired(&BACnet_Task_Timer)) { if (mstimer_expired(&BACnet_Task_Timer)) {
mstimer_reset(&BACnet_Task_Timer); mstimer_reset(&BACnet_Task_Timer);
elapsed_milliseconds = mstimer_interval(&BACnet_Task_Timer); elapsed_milliseconds = mstimer_interval(&BACnet_Task_Timer);
elapsed_seconds = elapsed_milliseconds/1000; elapsed_seconds = elapsed_milliseconds / 1000;
/* 1 second tasks */ /* 1 second tasks */
dcc_timer_seconds(elapsed_seconds); dcc_timer_seconds(elapsed_seconds);
datalink_maintenance_timer(elapsed_seconds); datalink_maintenance_timer(elapsed_seconds);
@@ -413,7 +420,7 @@ int main(int argc, char *argv[])
if (mstimer_expired(&BACnet_Address_Timer)) { if (mstimer_expired(&BACnet_Address_Timer)) {
mstimer_reset(&BACnet_Address_Timer); mstimer_reset(&BACnet_Address_Timer);
elapsed_milliseconds = mstimer_interval(&BACnet_Address_Timer); elapsed_milliseconds = mstimer_interval(&BACnet_Address_Timer);
elapsed_seconds = elapsed_milliseconds/1000; elapsed_seconds = elapsed_milliseconds / 1000;
address_cache_timer(elapsed_seconds); address_cache_timer(elapsed_seconds);
} }
handler_cov_task(); handler_cov_task();
+28 -25
View File
@@ -50,8 +50,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -94,35 +94,36 @@ static void print_help(const char *filename)
printf("Send BACnet TimeSynchronization request.\n"); printf("Send BACnet TimeSynchronization request.\n");
printf("\n"); printf("\n");
printf("--date year/month/day[:weekday]\n" printf("--date year/month/day[:weekday]\n"
"Date formatted 2021/12/31 or 2021/12/31:1\n" "Date formatted 2021/12/31 or 2021/12/31:1\n"
"where day is 1..31,\n" "where day is 1..31,\n"
"where month is 1=January..12=December,\n" "where month is 1=January..12=December,\n"
"where weekday is 1=Monday..7=Sunday\n"); "where weekday is 1=Monday..7=Sunday\n");
printf("\n"); printf("\n");
printf("--time hours:minutes:seconds.hundredths\n" printf("--time hours:minutes:seconds.hundredths\n"
"Time formatted 23:59:59.99 or 23:59:59 or 23:59\n"); "Time formatted 23:59:59.99 or 23:59:59 or 23:59\n");
printf("\n"); printf("\n");
printf("--utc\n" printf("--utc\n"
"Send BACnet UTCTimeSynchronization request.\n"); "Send BACnet UTCTimeSynchronization request.\n");
printf("\n"); printf("\n");
printf("--mac A\n" printf("--mac A\n"
"BACnet mac address." "BACnet mac address."
"Valid ranges are from 0 to 255\n" "Valid ranges are from 0 to 255\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf("--dnet N\n"
"BACnet network number N for directed requests.\n" "BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"BACnet mac address on the destination BACnet network number.\n" "BACnet mac address on the destination BACnet network number.\n"
"Valid ranges are from 0 to 255\n" "Valid ranges are from 0 to 255\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("Examples:\n" printf(
"Examples:\n"
"Send a TimeSynchronization request to DNET 123:\n" "Send a TimeSynchronization request to DNET 123:\n"
"%s --dnet 123\n", "%s --dnet 123\n",
filename); filename);
@@ -130,8 +131,9 @@ static void print_help(const char *filename)
"Send a TimeSynchronization request to MAC 10.0.0.1 DNET 123 DADR 5:\n" "Send a TimeSynchronization request to MAC 10.0.0.1 DNET 123 DADR 5:\n"
"%s --mac 10.0.0.1 --dnet 123 --dadr 5\n", "%s --mac 10.0.0.1 --dnet 123 --dadr 5\n",
filename); filename);
printf("Send a TimeSynchronization request to MAC 10.1.2.3:47808:\n" printf(
"%s --mac 10.1.2.3:47808\n", "Send a TimeSynchronization request to MAC 10.1.2.3:47808:\n"
"%s --mac 10.1.2.3:47808\n",
filename); filename);
} }
@@ -255,7 +257,8 @@ int main(int argc, char *argv[])
atexit(datalink_cleanup); atexit(datalink_cleanup);
mstimer_init(); mstimer_init();
/* send the request */ /* send the request */
datetime_local(override_date ? NULL : &bdate, override_time ? NULL : &btime, datetime_local(
override_date ? NULL : &bdate, override_time ? NULL : &btime,
&utc_offset_minutes, &dst_active); &utc_offset_minutes, &dst_active);
if (use_utc) { if (use_utc) {
/* convert to UTC */ /* convert to UTC */
@@ -263,8 +266,8 @@ int main(int argc, char *argv[])
dst_adjust_minutes = -60; dst_adjust_minutes = -60;
} }
datetime_set(&local_time, &bdate, &btime); datetime_set(&local_time, &bdate, &btime);
datetime_local_to_utc(&utc_time, &local_time, utc_offset_minutes, datetime_local_to_utc(
dst_adjust_minutes); &utc_time, &local_time, utc_offset_minutes, dst_adjust_minutes);
Send_TimeSyncUTC_Remote(&dest, &utc_time.date, &utc_time.time); Send_TimeSyncUTC_Remote(&dest, &utc_time.date, &utc_time.time);
} else { } else {
Send_TimeSync_Remote(&dest, &bdate, &btime); Send_TimeSync_Remote(&dest, &bdate, &btime);
+48 -38
View File
@@ -50,62 +50,68 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Sends a BACnet Unconfirmed Change-of-Value Notification\n" printf("Sends a BACnet Unconfirmed Change-of-Value Notification\n"
"to the network.\n"); "to the network.\n");
printf("\n"); printf("\n");
printf("Usage: %s pid device-id object-type object-instance " printf(
"time property tag value [priority] [index]\n", filename); "Usage: %s pid device-id object-type object-instance "
"time property tag value [priority] [index]\n",
filename);
printf("\n"); printf("\n");
printf("pid:\n" printf("pid:\n"
"Process Identifier for this broadcast.\n"); "Process Identifier for this broadcast.\n");
printf("\n"); printf("\n");
printf("device-id:\n" printf("device-id:\n"
"The Initiating BACnet Device Object Instance number.\n"); "The Initiating BACnet Device Object Instance number.\n");
printf("\n"); printf("\n");
printf("object-type:\n" printf("object-type:\n"
"The object type is object that you are reading. It\n" "The object type is object that you are reading. It\n"
"can be defined either as the object-type name string\n" "can be defined either as the object-type name string\n"
"as defined in the BACnet specification, or as the\n" "as defined in the BACnet specification, or as the\n"
"integer value of the enumeration BACNET_OBJECT_TYPE\n" "integer value of the enumeration BACNET_OBJECT_TYPE\n"
"in bacenum.h. For example if you were reading Analog\n" "in bacenum.h. For example if you were reading Analog\n"
"Output 2, the object-type would be analog-output or 1.\n"); "Output 2, the object-type would be analog-output or 1.\n");
printf("\n"); printf("\n");
printf("object-instance:\n" printf("object-instance:\n"
"The monitored object instance number.\n"); "The monitored object instance number.\n");
printf("\n"); printf("\n");
printf("time:\n" printf("time:\n"
"The subscription time remaining is conveyed in seconds.\n"); "The subscription time remaining is conveyed in seconds.\n");
printf("\n"); printf("\n");
printf("property:\n" printf("property:\n"
"The property of the object that you are reading. It\n" "The property of the object that you are reading. It\n"
"can be defined either as the property name string as\n" "can be defined either as the property name string as\n"
"defined in the BACnet specification, or as an integer\n" "defined in the BACnet specification, or as an integer\n"
"value of the enumeration BACNET_PROPERTY_ID in\n" "value of the enumeration BACNET_PROPERTY_ID in\n"
"bacenum.h. For example, if you were reading the Present\n" "bacenum.h. For example, if you were reading the Present\n"
"Value property, use present-value or 85 as the property.\n"); "Value property, use present-value or 85 as the property.\n");
printf("\n"); printf("\n");
printf("tag:\n" printf(
"tag:\n"
"Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \n" "Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \n"
"in bacenum.h. It is the data type of the value that you are\n" "in bacenum.h. It is the data type of the value that you are\n"
"monitoring. For example, if you were monitoring a REAL value,\n" "monitoring. For example, if you were monitoring a REAL value,\n"
"you would use a tag of 4.\n"); "you would use a tag of 4.\n");
printf("\n"); printf("\n");
printf("value:\n" printf(
"value:\n"
"The value is an ASCII representation of some type of data that you\n" "The value is an ASCII representation of some type of data that you\n"
"are monitoring. It is encoded using the tag information provided.\n" "are monitoring. It is encoded using the tag information provided.\n"
"For example, if you were writing a REAL value of 100.0,\n" "For example, if you were writing a REAL value of 100.0,\n"
"you would use 100.0 as the value.\n"); "you would use 100.0 as the value.\n");
printf("\n"); printf("\n");
printf("[priority]:\n" printf("[priority]:\n"
"This optional parameter is used for reporting the priority of the\n" "This optional parameter is used for reporting the priority of the\n"
"value. If no priority is given, none is sent, and the BACnet \n" "value. If no priority is given, none is sent, and the BACnet \n"
"standard requires that the value is reported at the lowest \n" "standard requires that the value is reported at the lowest \n"
"priority (16) if the object property supports priorities.\n"); "priority (16) if the object property supports priorities.\n");
printf("\n"); printf("\n");
printf("[index]\n" printf(
"[index]\n"
"This optional integer parameter is the index number of an array.\n" "This optional integer parameter is the index number of an array.\n"
"If the property is an array, individual elements can be reported.\n"); "If the property is an array, individual elements can be reported.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"Example:\n"
"If you want generate an unconfirmed COV,\n" "If you want generate an unconfirmed COV,\n"
"you could send one of the following command:\n" "you could send one of the following command:\n"
"%s 1 2 analog-value 4 5 present-value 4 100.0\n" "%s 1 2 analog-value 4 5 present-value 4 100.0\n"
@@ -162,29 +168,32 @@ int main(int argc, char *argv[])
} }
if (cov_data.initiatingDeviceIdentifier > BACNET_MAX_INSTANCE) { if (cov_data.initiatingDeviceIdentifier > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
cov_data.initiatingDeviceIdentifier, BACNET_MAX_INSTANCE); cov_data.initiatingDeviceIdentifier, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (cov_data.monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) { if (cov_data.monitoredObjectIdentifier.type >= MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\n", fprintf(
stderr, "object-type=%u - it must be less than %u\n",
cov_data.monitoredObjectIdentifier.type, MAX_BACNET_OBJECT_TYPE); cov_data.monitoredObjectIdentifier.type, MAX_BACNET_OBJECT_TYPE);
return 1; return 1;
} }
if (cov_data.monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) { if (cov_data.monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - not greater than %u\n", fprintf(
cov_data.monitoredObjectIdentifier.instance, stderr, "object-instance=%u - not greater than %u\n",
BACNET_MAX_INSTANCE); cov_data.monitoredObjectIdentifier.instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (cov_data.listOfValues->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { if (cov_data.listOfValues->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "property-identifier=%u - not greater than %u\n", fprintf(
cov_data.listOfValues->propertyIdentifier, stderr, "property-identifier=%u - not greater than %u\n",
MAX_BACNET_PROPERTY_ID); cov_data.listOfValues->propertyIdentifier, MAX_BACNET_PROPERTY_ID);
return 1; return 1;
} }
if (tag >= MAX_BACNET_APPLICATION_TAG) { if (tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, "tag=%u - it must be less than %u\n", tag, fprintf(
stderr, "tag=%u - it must be less than %u\n", tag,
MAX_BACNET_APPLICATION_TAG); MAX_BACNET_APPLICATION_TAG);
return 1; return 1;
} }
@@ -200,8 +209,9 @@ int main(int argc, char *argv[])
Init_Service_Handlers(); Init_Service_Handlers();
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
Send_UCOV_Notify(&Handler_Transmit_Buffer[0], Send_UCOV_Notify(
sizeof(Handler_Transmit_Buffer), &cov_data); &Handler_Transmit_Buffer[0], sizeof(Handler_Transmit_Buffer),
&cov_data);
return 0; return 0;
} }
+21 -20
View File
@@ -51,13 +51,14 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s pid object-type object-instance \n" printf(
" event-object-type event-object-instance \n" "Usage: %s pid object-type object-instance \n"
" sequence-number notification-class priority event-type\n" " event-object-type event-object-instance \n"
" [reference-bit-string status-flags message notify-type\n" " sequence-number notification-class priority event-type\n"
" ack-required from-state to-state]\n" " [reference-bit-string status-flags message notify-type\n"
" [new-state status-flags message notify-type\n" " ack-required from-state to-state]\n"
" ack-required from-state to-state]\n", " [new-state status-flags message notify-type\n"
" ack-required from-state to-state]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -67,21 +68,21 @@ static void print_help(const char *filename)
{ {
printf("Send BACnet UnconfirmedEventNotification message for a device.\n"); printf("Send BACnet UnconfirmedEventNotification message for a device.\n");
printf("--mac A\n" printf("--mac A\n"
"Optional BACnet mac address." "Optional BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf("--dnet N\n"
"Optional BACnet network number N for directed requests.\n" "Optional BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"Optional BACnet mac address on the destination BACnet network\n" "Optional BACnet mac address on the destination BACnet network\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
(void)filename; (void)filename;
} }
@@ -296,8 +297,8 @@ int main(int argc, char *argv[])
} else if (event_data.eventType == EVENT_COMMAND_FAILURE) { } else if (event_data.eventType == EVENT_COMMAND_FAILURE) {
} else if (event_data.eventType == EVENT_FLOATING_LIMIT) { } else if (event_data.eventType == EVENT_FLOATING_LIMIT) {
} else if (event_data.eventType == EVENT_OUT_OF_RANGE) { } else if (event_data.eventType == EVENT_OUT_OF_RANGE) {
} else if (event_data.eventType == } else if (
EVENT_CHANGE_OF_LIFE_SAFETY) { event_data.eventType == EVENT_CHANGE_OF_LIFE_SAFETY) {
} else if (event_data.eventType == EVENT_EXTENDED) { } else if (event_data.eventType == EVENT_EXTENDED) {
} else if (event_data.eventType == EVENT_BUFFER_READY) { } else if (event_data.eventType == EVENT_BUFFER_READY) {
} else if (event_data.eventType == EVENT_UNSIGNED_RANGE) { } else if (event_data.eventType == EVENT_UNSIGNED_RANGE) {
+49 -39
View File
@@ -57,14 +57,16 @@ static uint8_t Request_Invoke_ID = 0;
static BACNET_ADDRESS Target_Address; static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -77,18 +79,19 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Abort: %s\n", printf(
bactext_abort_reason_name((int)abort_reason)); "BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -109,7 +112,8 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the data coming back from requests */ /* handle the data coming back from requests */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER, apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
handler_unconfirmed_private_transfer); handler_unconfirmed_private_transfer);
/* handle any errors coming back */ /* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler); apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
@@ -119,7 +123,8 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s <device-instance|broadcast|dnet=> vendor-id" printf(
"Usage: %s <device-instance|broadcast|dnet=> vendor-id"
" service-number tag value [tag value...]\n", " service-number tag value [tag value...]\n",
filename); filename);
} }
@@ -128,41 +133,42 @@ static void print_help(const char *filename)
{ {
printf("Send BACnet UnconfirmedPrivateTransfer message to the network.\n"); printf("Send BACnet UnconfirmedPrivateTransfer message to the network.\n");
printf("device-instance:\n" printf("device-instance:\n"
"BACnet Device Object Instance number that you are\n" "BACnet Device Object Instance number that you are\n"
"trying to communicate to. This number will be used\n" "trying to communicate to. This number will be used\n"
"to try and bind with the device using Who-Is and\n" "to try and bind with the device using Who-Is and\n"
"I-Am services. For example, if you were transferring to\n" "I-Am services. For example, if you were transferring to\n"
"Device Object 123, the device-instance would be 123.\n" "Device Object 123, the device-instance would be 123.\n"
"For Global Broadcast, use the word 'broadcast'.\n" "For Global Broadcast, use the word 'broadcast'.\n"
"For Local Broadcast to a particular DNET n, use 'dnet=n'.\n"); "For Local Broadcast to a particular DNET n, use 'dnet=n'.\n");
printf("\n"); printf("\n");
printf("vendor_id:\n" printf("vendor_id:\n"
"the unique vendor identification code for the type of\n" "the unique vendor identification code for the type of\n"
"vendor proprietary service to be performed.\n"); "vendor proprietary service to be performed.\n");
printf("\n"); printf("\n");
printf("service-number (Unsigned32):\n" printf("service-number (Unsigned32):\n"
"the desired proprietary service to be performed.\n"); "the desired proprietary service to be performed.\n");
printf("\n"); printf("\n");
printf("tag:\n" printf("tag:\n"
"Tag is the integer value of the enumeration \n" "Tag is the integer value of the enumeration \n"
"BACNET_APPLICATION_TAG in bacenum.h.\n" "BACNET_APPLICATION_TAG in bacenum.h.\n"
"It is the data type of the value that you are sending.\n" "It is the data type of the value that you are sending.\n"
"For example, if you were transfering a REAL value, you would\n" "For example, if you were transfering a REAL value, you would\n"
"use a tag of 4.\n" "use a tag of 4.\n"
"Context tags are created using two tags in a row.\n" "Context tags are created using two tags in a row.\n"
"The context tag is preceded by a C. Ctag tag.\n" "The context tag is preceded by a C. Ctag tag.\n"
"C2 4 creates a context 2 tagged REAL.\n"); "C2 4 creates a context 2 tagged REAL.\n");
printf("\n"); printf("\n");
printf("value:\n" printf("value:\n"
"The value is an ASCII representation of some type of data\n" "The value is an ASCII representation of some type of data\n"
"that you are transfering.\n" "that you are transfering.\n"
"It is encoded using the tag information provided.\n" "It is encoded using the tag information provided.\n"
"For example, if you were transferring a REAL value of 100.0,\n" "For example, if you were transferring a REAL value of 100.0,\n"
"you would use 100.0 as the value.\n" "you would use 100.0 as the value.\n"
"If you were transferring an object identifier for Device 123,\n" "If you were transferring an object identifier for Device 123,\n"
"you would use 8:123 as the value.\n"); "you would use 8:123 as the value.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"Example:\n"
"If you want to transfer a REAL value of 1.1 to service 23 of \n" "If you want to transfer a REAL value of 1.1 to service 23 of \n"
"vendor 260 in Device 99, you could send the following command:\n" "vendor 260 in Device 99, you could send the following command:\n"
"%s 99 260 23 4 1.1\n", "%s 99 260 23 4 1.1\n",
@@ -213,7 +219,8 @@ int main(int argc, char *argv[])
Target_Service_Number = strtol(argv[3], NULL, 0); Target_Service_Number = strtol(argv[3], NULL, 0);
if ((!Target_Broadcast) && if ((!Target_Broadcast) &&
(Target_Device_Object_Instance > BACNET_MAX_INSTANCE)) { (Target_Device_Object_Instance > BACNET_MAX_INSTANCE)) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -241,7 +248,8 @@ int main(int argc, char *argv[])
/* printf("tag[%d]=%u value[%d]=%s\n", /* printf("tag[%d]=%u value[%d]=%s\n",
i, property_tag, i, value_string); */ i, property_tag, i, value_string); */
if (property_tag >= MAX_BACNET_APPLICATION_TAG) { if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, "Error: tag=%u - it must be less than %u\n", fprintf(
stderr, "Error: tag=%u - it must be less than %u\n",
property_tag, MAX_BACNET_APPLICATION_TAG); property_tag, MAX_BACNET_APPLICATION_TAG);
return 1; return 1;
} }
@@ -262,7 +270,8 @@ int main(int argc, char *argv[])
} }
} }
if (args_remaining > 0) { if (args_remaining > 0) {
fprintf(stderr, "Error: Exceeded %d tag-value pairs.\n", fprintf(
stderr, "Error: Exceeded %d tag-value pairs.\n",
MAX_PROPERTY_VALUES); MAX_PROPERTY_VALUES);
return 1; return 1;
} }
@@ -320,7 +329,8 @@ int main(int argc, char *argv[])
Send_UnconfirmedPrivateTransfer(&Target_Address, &private_data); Send_UnconfirmedPrivateTransfer(&Target_Address, &private_data);
printf("Sent PrivateTransfer."); printf("Sent PrivateTransfer.");
if (timeout_seconds) { if (timeout_seconds) {
printf(" Waiting %u seconds.\n", printf(
" Waiting %u seconds.\n",
(unsigned)(timeout_seconds - elapsed_seconds)); (unsigned)(timeout_seconds - elapsed_seconds));
} else { } else {
printf("\n"); printf("\n");
+30 -22
View File
@@ -61,8 +61,8 @@ static void MyAbortHandler(
* @param invoke_id [in] the invokeID from the rejected message * @param invoke_id [in] the invokeID from the rejected message
* @param reject_reason [in] the reason for the rejection * @param reject_reason [in] the reason for the rejection
*/ */
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -71,7 +71,8 @@ static void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void My_Router_Handler(BACNET_ADDRESS *src, static void My_Router_Handler(
BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, uint8_t *npdu,
uint16_t npdu_len) uint16_t npdu_len)
@@ -104,7 +105,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
that are sent with a local unicast address. */ that are sent with a local unicast address. */
if (npdu_len >= 2) { if (npdu_len >= 2) {
(void)decode_unsigned16(npdu, &dnet); (void)decode_unsigned16(npdu, &dnet);
printf(": network number = %u. SNET=%u\n", (unsigned)dnet, printf(
": network number = %u. SNET=%u\n", (unsigned)dnet,
(unsigned)src->net); (unsigned)src->net);
} else { } else {
printf(": network number = missing! SNET=%u\n", src->net); printf(": network number = missing! SNET=%u\n", src->net);
@@ -126,7 +128,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
} }
} }
static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ static void My_NPDU_Handler(
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* length PDU */ { /* length PDU */
@@ -136,7 +139,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data); apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data);
if (npdu_data.network_layer_message) { if (npdu_data.network_layer_message) {
My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], My_Router_Handler(
src, &npdu_data, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset)); (uint16_t)(pdu_len - apdu_offset));
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
@@ -150,7 +154,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
if (dest.net) { if (dest.net) {
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net); debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
} else { } else {
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n", debug_printf(
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
npdu_data.protocol_version); npdu_data.protocol_version);
} }
} }
@@ -186,8 +191,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
int index = 0; int index = 0;
if (argc > 0) { if (argc > 0) {
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], count = sscanf(
&mac[3], &mac[4], &mac[5]); argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3],
&mac[4], &mac[5]);
dst->mac_len = count; dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -203,8 +209,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
} }
if (dnet) { if (dnet) {
if (argc > 2) { if (argc > 2) {
count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], count = sscanf(
&mac[2], &mac[3], &mac[4], &mac[5]); argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->len = count; dst->len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -236,17 +243,18 @@ int main(int argc, char *argv[])
time_t timeout_seconds = 0; time_t timeout_seconds = 0;
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet What-Is-Network-Number message to a network.\r\n" printf(
"\r\n" "Send BACnet What-Is-Network-Number message to a network.\r\n"
"MAC:\r\n" "\r\n"
"Optional MAC address of router for unicast message\r\n" "MAC:\r\n"
"Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n" "Optional MAC address of router for unicast message\r\n"
"Use hexidecimal MAC addresses.\r\n" "Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n"
"\r\n" "Use hexidecimal MAC addresses.\r\n"
"To send a What-Is-Network-Number request to DNET 86:\r\n" "\r\n"
"%s 86\r\n" "To send a What-Is-Network-Number request to DNET 86:\r\n"
"To send a What-Is-Network-Number request to all devices:\r\n" "%s 86\r\n"
"%s -1\r\n", "To send a What-Is-Network-Number request to all devices:\r\n"
"%s -1\r\n",
filename_remove_path(argv[0]), filename_remove_path(argv[0])); filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0; return 0;
} }
+28 -21
View File
@@ -56,8 +56,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -87,23 +87,25 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s [device-instance-min device-instance-min] " printf(
"<object-type object-instance | object-name> [--help]\r\n", "Usage: %s [device-instance-min device-instance-min] "
"<object-type object-instance | object-name> [--help]\r\n",
filename); filename);
} }
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
print_usage(filename); print_usage(filename);
printf("Send BACnet WhoHas request to devices, \r\n" printf(
"and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n" "Send BACnet WhoHas request to devices, \r\n"
"The device-instance-min or max can be 0 to %d.\r\n" "and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n"
"\r\n" "The device-instance-min or max can be 0 to %d.\r\n"
"Use either:\r\n" "\r\n"
"The object-type can be 0 to %d, or a string e.g. analog-output.\r\n" "Use either:\r\n"
"The object-instance can be 0 to %d.\r\n" "The object-type can be 0 to %d, or a string e.g. analog-output.\r\n"
"or:\r\n" "The object-instance can be 0 to %d.\r\n"
"The object-name can be any string of characters.\r\n", "or:\r\n"
"The object-name can be any string of characters.\r\n",
BACNET_MAX_INSTANCE, (unsigned)apdu_timeout(), BACNET_MAX_OBJECT, BACNET_MAX_INSTANCE, (unsigned)apdu_timeout(), BACNET_MAX_OBJECT,
BACNET_MAX_INSTANCE); BACNET_MAX_INSTANCE);
} }
@@ -180,23 +182,27 @@ int main(int argc, char *argv[])
} }
} else { } else {
if (Target_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - not greater than %u\r\n", fprintf(
stderr, "object-instance=%u - not greater than %u\r\n",
Target_Object_Instance, BACNET_MAX_INSTANCE); Target_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_Object_Type > BACNET_MAX_OBJECT) { if (Target_Object_Type > BACNET_MAX_OBJECT) {
fprintf(stderr, "object-type=%u - not greater than %u\r\n", fprintf(
stderr, "object-type=%u - not greater than %u\r\n",
Target_Object_Type, BACNET_MAX_OBJECT); Target_Object_Type, BACNET_MAX_OBJECT);
return 1; return 1;
} }
} }
if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) { if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance-min=%u - not greater than %u\r\n", fprintf(
stderr, "object-instance-min=%u - not greater than %u\r\n",
Target_Object_Instance_Min, BACNET_MAX_INSTANCE); Target_Object_Instance_Min, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) { if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance-max=%u - not greater than %u\r\n", fprintf(
stderr, "object-instance-max=%u - not greater than %u\r\n",
Target_Object_Instance_Max, BACNET_MAX_INSTANCE); Target_Object_Instance_Max, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -210,12 +216,13 @@ int main(int argc, char *argv[])
timeout_seconds = apdu_timeout() / 1000; timeout_seconds = apdu_timeout() / 1000;
/* send the request */ /* send the request */
if (by_name) { if (by_name) {
Send_WhoHas_Name(Target_Object_Instance_Min, Target_Object_Instance_Max, Send_WhoHas_Name(
Target_Object_Instance_Min, Target_Object_Instance_Max,
Target_Object_Name); Target_Object_Name);
} else { } else {
Send_WhoHas_Object(Target_Object_Instance_Min, Send_WhoHas_Object(
Target_Object_Instance_Max, Target_Object_Type, Target_Object_Instance_Min, Target_Object_Instance_Max,
Target_Object_Instance); Target_Object_Type, Target_Object_Instance);
} }
/* loop forever */ /* loop forever */
for (;;) { for (;;) {
+53 -40
View File
@@ -120,7 +120,8 @@ static void my_i_am_handler(
if (BACnet_Debug_Enabled) { if (BACnet_Debug_Enabled) {
fprintf(stderr, " from %lu, MAC = ", (unsigned long)device_id); fprintf(stderr, " from %lu, MAC = ", (unsigned long)device_id);
if ((src->mac_len == 6) && (src->len == 0)) { if ((src->mac_len == 6) && (src->len == 0)) {
fprintf(stderr, "%u.%u.%u.%u %02X%02X\n", (unsigned)src->mac[0], fprintf(
stderr, "%u.%u.%u.%u %02X%02X\n", (unsigned)src->mac[0],
(unsigned)src->mac[1], (unsigned)src->mac[2], (unsigned)src->mac[1], (unsigned)src->mac[2],
(unsigned)src->mac[3], (unsigned)src->mac[4], (unsigned)src->mac[3], (unsigned)src->mac[4],
(unsigned)src->mac[5]); (unsigned)src->mac[5]);
@@ -156,13 +157,14 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
fprintf(stderr, "BACnet Reject: %s\n", fprintf(
stderr, "BACnet Reject: %s\n",
bactext_reject_reason_name(reject_reason)); bactext_reject_reason_name(reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -213,7 +215,8 @@ static void print_address_cache(void)
/* NOTE: this string format is parsed by src/address.c, /* NOTE: this string format is parsed by src/address.c,
so these must be compatible. */ so these must be compatible. */
printf(";%-7s %-20s %-5s %-20s %-4s\n", "Device", "MAC (hex)", "SNET", printf(
";%-7s %-20s %-5s %-20s %-4s\n", "Device", "MAC (hex)", "SNET",
"SADR (hex)", "APDU"); "SADR (hex)", "APDU");
printf(";-------- -------------------- ----- -------------------- ----\n"); printf(";-------- -------------------- ----- -------------------- ----\n");
@@ -257,68 +260,75 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Send BACnet WhoIs service request to a device or multiple\n" printf("Send BACnet WhoIs service request to a device or multiple\n"
"devices, and wait for responses. Displays any devices found\n" "devices, and wait for responses. Displays any devices found\n"
"and their network information.\n"); "and their network information.\n");
printf("\n"); printf("\n");
printf("device-instance:\n" printf("device-instance:\n"
"BACnet Device Object Instance number that you are trying\n" "BACnet Device Object Instance number that you are trying\n"
"to send a Who-Is service request. The value should be in\n" "to send a Who-Is service request. The value should be in\n"
"the range of 0 to 4194303. A range of values can also be\n" "the range of 0 to 4194303. A range of values can also be\n"
"specified by using a minimum value and a maximum value.\n"); "specified by using a minimum value and a maximum value.\n");
printf("\n"); printf("\n");
printf("--mac A\n" printf("--mac A\n"
"BACnet mac address." "BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--dnet N\n" printf("--dnet N\n"
"BACnet network number N for directed requests.\n" "BACnet network number N for directed requests.\n"
"Valid range is from 0 to 65535 where 0 is the local connection\n" "Valid range is from 0 to 65535 where 0 is the local connection\n"
"and 65535 is network broadcast.\n"); "and 65535 is network broadcast.\n");
printf("\n"); printf("\n");
printf("--dadr A\n" printf("--dadr A\n"
"BACnet mac address on the destination BACnet network number.\n" "BACnet mac address on the destination BACnet network number.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"); "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
printf("\n"); printf("\n");
printf("--repeat\n" printf("--repeat\n"
"Send the message repeatedly until signalled to quit.\n" "Send the message repeatedly until signalled to quit.\n"
"Default is disabled, using the APDU timeout as time to quit.\n"); "Default is disabled, using the APDU timeout as time to quit.\n");
printf("\n"); printf("\n");
printf("--retry C\n" printf("--retry C\n"
"Send the message C number of times\n" "Send the message C number of times\n"
"Default is retry 0, only sending one time.\n"); "Default is retry 0, only sending one time.\n");
printf("\n"); printf("\n");
printf("--timeout T\n" printf("--timeout T\n"
"Wait T milliseconds after sending before retry\n" "Wait T milliseconds after sending before retry\n"
"Default delay is 3000ms.\n"); "Default delay is 3000ms.\n");
printf("\n"); printf("\n");
printf("--delay M\n" printf("--delay M\n"
"Wait M milliseconds for responses after sending\n" "Wait M milliseconds for responses after sending\n"
"Default delay is 100ms.\n"); "Default delay is 100ms.\n");
printf("\n"); printf("\n");
printf("Example:\n"); printf("Example:\n");
printf("Send a WhoIs request to DNET 123:\n" printf(
"Send a WhoIs request to DNET 123:\n"
"%s --dnet 123\n", "%s --dnet 123\n",
filename); filename);
printf("Send a WhoIs request to MAC 10.0.0.1 DNET 123 DADR 05h:\n" printf(
"Send a WhoIs request to MAC 10.0.0.1 DNET 123 DADR 05h:\n"
"%s --mac 10.0.0.1 --dnet 123 --dadr 05\n", "%s --mac 10.0.0.1 --dnet 123 --dadr 05\n",
filename); filename);
printf("Send a WhoIs request to MAC 10.1.2.3:47808:\n" printf(
"Send a WhoIs request to MAC 10.1.2.3:47808:\n"
"%s --mac 10.1.2.3:47808\n", "%s --mac 10.1.2.3:47808\n",
filename); filename);
printf("Send a WhoIs request to Device 123:\n" printf(
"Send a WhoIs request to Device 123:\n"
"%s 123\n", "%s 123\n",
filename); filename);
printf("Send a WhoIs request to Devices from 1000 to 9000:\n" printf(
"Send a WhoIs request to Devices from 1000 to 9000:\n"
"%s 1000 9000\n", "%s 1000 9000\n",
filename); filename);
printf("Send a WhoIs request to Devices from 1000 to 9000 on DNET 123:\n" printf(
"Send a WhoIs request to Devices from 1000 to 9000 on DNET 123:\n"
"%s 1000 9000 --dnet 123\n", "%s 1000 9000 --dnet 123\n",
filename); filename);
printf("Send a WhoIs request to all devices:\n" printf(
"Send a WhoIs request to all devices:\n"
"%s\n", "%s\n",
filename); filename);
} }
@@ -446,12 +456,14 @@ int main(int argc, char *argv[])
} }
} }
if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) { if (Target_Object_Instance_Min > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance-min=%u - not greater than %u\n", fprintf(
stderr, "device-instance-min=%u - not greater than %u\n",
Target_Object_Instance_Min, BACNET_MAX_INSTANCE); Target_Object_Instance_Min, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) { if (Target_Object_Instance_Max > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance-max=%u - not greater than %u\n", fprintf(
stderr, "device-instance-max=%u - not greater than %u\n",
Target_Object_Instance_Max, BACNET_MAX_INSTANCE); Target_Object_Instance_Max, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -491,7 +503,8 @@ int main(int argc, char *argv[])
} }
if (mstimer_expired(&apdu_timer)) { if (mstimer_expired(&apdu_timer)) {
if (repeat_forever || retry_count) { if (repeat_forever || retry_count) {
Send_WhoIs_To_Network(&dest, Target_Object_Instance_Min, Send_WhoIs_To_Network(
&dest, Target_Object_Instance_Min,
Target_Object_Instance_Max); Target_Object_Instance_Max);
retry_count--; retry_count--;
} else { } else {
+33 -25
View File
@@ -50,8 +50,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -60,7 +60,8 @@ static void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void My_Router_Handler(BACNET_ADDRESS *src, static void My_Router_Handler(
BACNET_ADDRESS *src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *npdu, /* PDU data */ uint8_t *npdu, /* PDU data */
uint16_t npdu_len) uint16_t npdu_len)
@@ -108,7 +109,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
} }
} }
static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */ static void My_NPDU_Handler(
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* length PDU */ { /* length PDU */
@@ -118,7 +120,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data); apdu_offset = bacnet_npdu_decode(pdu, pdu_len, &dest, src, &npdu_data);
if (npdu_data.network_layer_message) { if (npdu_data.network_layer_message) {
My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], My_Router_Handler(
src, &npdu_data, &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset)); (uint16_t)(pdu_len - apdu_offset));
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
@@ -132,7 +135,8 @@ static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
if (dest.net) { if (dest.net) {
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net); debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
} else { } else {
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n", debug_printf(
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
npdu_data.protocol_version); npdu_data.protocol_version);
} }
} }
@@ -168,8 +172,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
int index = 0; int index = 0;
if (argc > 0) { if (argc > 0) {
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], count = sscanf(
&mac[3], &mac[4], &mac[5]); argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3],
&mac[4], &mac[5]);
dst->mac_len = count; dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -185,8 +190,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
} }
if (dnet) { if (dnet) {
if (argc > 2) { if (argc > 2) {
count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], count = sscanf(
&mac[2], &mac[3], &mac[4], &mac[5]); argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
&mac[3], &mac[4], &mac[5]);
dst->len = count; dst->len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -222,20 +228,21 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("Send BACnet Who-Is-Router-To-Network message to a network.\r\n" printf(
"\r\n" "Send BACnet Who-Is-Router-To-Network message to a network.\r\n"
"DNET:\r\n" "\r\n"
"BACnet destination network number 0-65535\r\n" "DNET:\r\n"
"To omit the BACnet destination network number, use -1.\r\n" "BACnet destination network number 0-65535\r\n"
"MAC:\r\n" "To omit the BACnet destination network number, use -1.\r\n"
"Optional MAC address of router for unicast message\r\n" "MAC:\r\n"
"Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n" "Optional MAC address of router for unicast message\r\n"
"Use hexidecimal MAC addresses.\r\n" "Format: xx[:xx:xx:xx:xx:xx] [dnet xx[:xx:xx:xx:xx:xx]]\r\n"
"\r\n" "Use hexidecimal MAC addresses.\r\n"
"To send a Who-Is-Router-To-Network request to DNET 86:\r\n" "\r\n"
"%s 86\r\n" "To send a Who-Is-Router-To-Network request to DNET 86:\r\n"
"To send a Who-Is-Router-To-Network request to all devices:\r\n" "%s 86\r\n"
"%s -1\r\n", "To send a Who-Is-Router-To-Network request to all devices:\r\n"
"%s -1\r\n",
filename_remove_path(argv[0]), filename_remove_path(argv[0])); filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0; return 0;
} }
@@ -243,7 +250,8 @@ int main(int argc, char *argv[])
if (argc > 1) { if (argc > 1) {
Target_Router_Network = strtol(argv[1], NULL, 0); Target_Router_Network = strtol(argv[1], NULL, 0);
if (Target_Router_Network > 65535) { if (Target_Router_Network > 65535) {
fprintf(stderr, "DNET=%u - it must be 0 to 65535\r\n", fprintf(
stderr, "DNET=%u - it must be 0 to 65535\r\n",
Target_Router_Network); Target_Router_Network);
return 1; return 1;
} }
+7 -5
View File
@@ -58,8 +58,8 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -106,7 +106,8 @@ int main(int argc, char *argv[])
uint16_t result_code = 0; uint16_t result_code = 0;
if (argc < 2) { if (argc < 2) {
printf("Usage: %s IP port <IP:port[:mask]> [<IP:port[:mask]>]\r\n", printf(
"Usage: %s IP port <IP:port[:mask]> [<IP:port[:mask]>]\r\n",
filename_remove_path(argv[0])); filename_remove_path(argv[0]));
return 0; return 0;
} }
@@ -153,8 +154,9 @@ int main(int argc, char *argv[])
argi = 3; argi = 3;
while (argc > argi) { while (argc > argi) {
bdt_entry = &BBMD_Table_Entry[bdti]; bdt_entry = &BBMD_Table_Entry[bdti];
c = sscanf(argv[argi], "%3u.%3u.%3u.%3u:%5u:%3u.%3u.%3u.%3u", &a[0], c = sscanf(
&a[1], &a[2], &a[3], &p, &m[0], &m[1], &m[2], &m[3]); argv[argi], "%3u.%3u.%3u.%3u:%5u:%3u.%3u.%3u.%3u", &a[0], &a[1],
&a[2], &a[3], &p, &m[0], &m[1], &m[2], &m[3]);
if ((c == 4) || (c == 5) || (c == 9)) { if ((c == 4) || (c == 5) || (c == 9)) {
bvlc_address_set(&bdt_entry->dest_address, a[0], a[1], a[2], a[3]); bvlc_address_set(&bdt_entry->dest_address, a[0], a[1], a[2], a[3]);
if ((c == 5) || (c == 9)) { if ((c == 5) || (c == 9)) {
+20 -12
View File
@@ -46,7 +46,8 @@ static bool End_Of_File_Detected = false;
static bool Error_Detected = false; static bool Error_Detected = false;
static uint8_t Current_Invoke_ID = 0; static uint8_t Current_Invoke_ID = 0;
static void Atomic_Write_File_Error_Handler(BACNET_ADDRESS *src, static void Atomic_Write_File_Error_Handler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -66,18 +67,20 @@ static void MyAbortHandler(
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Current_Invoke_ID)) { (invoke_id == Current_Invoke_ID)) {
printf("BACnet Abort: %s\r\n", printf(
"BACnet Abort: %s\r\n",
bactext_abort_reason_name((int)abort_reason)); bactext_abort_reason_name((int)abort_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Current_Invoke_ID)) { (invoke_id == Current_Invoke_ID)) {
printf("BACnet Reject: %s\r\n", printf(
"BACnet Reject: %s\r\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
@@ -148,8 +151,9 @@ int main(int argc, char *argv[])
if (argc < 4) { if (argc < 4) {
/* FIXME: what about access method - record or stream? */ /* FIXME: what about access method - record or stream? */
printf("%s device-instance file-instance local-name [octet count] [pad " printf(
"value]\r\n", "%s device-instance file-instance local-name [octet count] [pad "
"value]\r\n",
filename_remove_path(argv[0])); filename_remove_path(argv[0]));
return 0; return 0;
} }
@@ -158,12 +162,14 @@ int main(int argc, char *argv[])
Target_File_Object_Instance = strtol(argv[2], NULL, 0); Target_File_Object_Instance = strtol(argv[2], NULL, 0);
Local_File_Name = argv[3]; Local_File_Name = argv[3];
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\r\n", fprintf(
stderr, "device-instance=%u - not greater than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_File_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_File_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "file-instance=%u - not greater than %u\r\n", fprintf(
stderr, "file-instance=%u - not greater than %u\r\n",
Target_File_Object_Instance, BACNET_MAX_INSTANCE); Target_File_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -251,12 +257,14 @@ int main(int argc, char *argv[])
pFile = fopen(Local_File_Name, "rb"); pFile = fopen(Local_File_Name, "rb");
if (pFile) { if (pFile) {
(void)fseek(pFile, fileStartPosition, SEEK_SET); (void)fseek(pFile, fileStartPosition, SEEK_SET);
len = fread(octetstring_value(&fileData), 1, len = fread(
requestedOctetCount, pFile); octetstring_value(&fileData), 1, requestedOctetCount,
pFile);
if (len < requestedOctetCount) { if (len < requestedOctetCount) {
End_Of_File_Detected = true; End_Of_File_Detected = true;
if (pad_byte) { if (pad_byte) {
memset(octetstring_value(&fileData) + len + 1, memset(
octetstring_value(&fileData) + len + 1,
(int)Target_File_Requested_Octet_Pad_Byte, (int)Target_File_Requested_Octet_Pad_Byte,
requestedOctetCount - len); requestedOctetCount - len);
len = requestedOctetCount; len = requestedOctetCount;
+51 -46
View File
@@ -67,14 +67,16 @@ static BACNET_ADDRESS Target_Address;
/* needed for return value of main application */ /* needed for return value of main application */
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS *src, static void MyErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)error_class), bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code)); bactext_error_code_name((int)error_code));
Error_Detected = true; Error_Detected = true;
@@ -93,19 +95,20 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyWritePropertySimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -138,8 +141,9 @@ static void Init_Service_Handlers(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance " printf(
"property priority index tag value [tag value...]\n", "Usage: %s device-instance object-type object-instance "
"property priority index tag value [tag value...]\n",
filename); filename);
} }
@@ -152,14 +156,13 @@ static void print_help(const char *filename)
"the device using Who-Is and I-Am services. For example, if you were\n" "the device using Who-Is and I-Am services. For example, if you were\n"
"writing to Device Object 123, the device-instance would be 123.\n"); "writing to Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf( printf("object-type:\n"
"object-type:\n" "The object type is object that you are writing. It\n"
"The object type is object that you are writing. It\n" "can be defined either as the object-type name string\n"
"can be defined either as the object-type name string\n" "as defined in the BACnet specification, or as the\n"
"as defined in the BACnet specification, or as the\n" "integer value of the enumeration BACNET_OBJECT_TYPE\n"
"integer value of the enumeration BACNET_OBJECT_TYPE\n" "in bacenum.h. For example if you were writing Analog\n"
"in bacenum.h. For example if you were writing Analog\n" "Output 2, the object-type would be analog-output or 1.\n");
"Output 2, the object-type would be analog-output or 1.\n");
printf("\n"); printf("\n");
printf( printf(
"object-instance:\n" "object-instance:\n"
@@ -167,22 +170,20 @@ static void print_help(const char *filename)
"writing to. For example, if you were writing to Analog Output 2, \n" "writing to. For example, if you were writing to Analog Output 2, \n"
"the object-instance would be 2.\n"); "the object-instance would be 2.\n");
printf("\n"); printf("\n");
printf( printf("property:\n"
"property:\n" "The property of the object that you are writing. It\n"
"The property of the object that you are writing. It\n" "can be defined either as the property name string as\n"
"can be defined either as the property name string as\n" "defined in the BACnet specification, or as an integer\n"
"defined in the BACnet specification, or as an integer\n" "value of the enumeration BACNET_PROPERTY_ID in\n"
"value of the enumeration BACNET_PROPERTY_ID in\n" "bacenum.h. For example, if you were writing the Present\n"
"bacenum.h. For example, if you were writing the Present\n" "Value property, use present-value or 85 as the property.\n");
"Value property, use present-value or 85 as the property.\n");
printf("\n"); printf("\n");
printf( printf("priority:\n"
"priority:\n" "This parameter is used for setting the priority of the\n"
"This parameter is used for setting the priority of the\n" "write. If Priority 0 is given, no priority is sent. The BACnet \n"
"write. If Priority 0 is given, no priority is sent. The BACnet \n" "standard states that the value is written at the lowest \n"
"standard states that the value is written at the lowest \n" "priority (16) if the object property supports priorities\n"
"priority (16) if the object property supports priorities\n" "when no priority is sent.\n");
"when no priority is sent.\n");
printf("\n"); printf("\n");
printf( printf(
"index\n" "index\n"
@@ -199,10 +200,9 @@ static void print_help(const char *filename)
"Context tags are created using two tags in a row. The context tag\n" "Context tags are created using two tags in a row. The context tag\n"
"is preceded by a C, and followed by the application tag.\n" "is preceded by a C, and followed by the application tag.\n"
"Ctag atag. C2 4 creates a context 2 tagged REAL.\n"); "Ctag atag. C2 4 creates a context 2 tagged REAL.\n");
printf( printf("Complex data use the property argument and a tag number -1 to\n"
"Complex data use the property argument and a tag number -1 to\n" "lookup the appropriate internal application tag for the value.\n"
"lookup the appropriate internal application tag for the value.\n" "The complex data value argument varies in its construction.\n");
"The complex data value argument varies in its construction.\n");
printf("\n"); printf("\n");
printf( printf(
"value:\n" "value:\n"
@@ -283,8 +283,7 @@ int main(int argc, char *argv[])
} }
Target_Object_Property = object_property; Target_Object_Property = object_property;
priority = strtol(argv[5], NULL, 0); priority = strtol(argv[5], NULL, 0);
if ((priority < BACNET_MIN_PRIORITY) || if ((priority < BACNET_MIN_PRIORITY) || (priority > BACNET_MAX_PRIORITY)) {
(priority > BACNET_MAX_PRIORITY)) {
priority = BACNET_NO_PRIORITY; priority = BACNET_NO_PRIORITY;
} }
Target_Object_Property_Priority = priority; Target_Object_Property_Priority = priority;
@@ -293,22 +292,26 @@ int main(int argc, char *argv[])
Target_Object_Property_Index = BACNET_ARRAY_ALL; Target_Object_Property_Index = BACNET_ARRAY_ALL;
} }
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) { if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\n", fprintf(
stderr, "object-type=%u - it must be less than %u\n",
Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1); Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1);
return 1; return 1;
} }
if (Target_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - not greater than %u\n", fprintf(
stderr, "object-instance=%u - not greater than %u\n",
Target_Object_Instance, BACNET_MAX_INSTANCE); Target_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) { if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "property=%u - it must be less than %u\n", fprintf(
stderr, "property=%u - it must be less than %u\n",
Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1); Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1);
return 1; return 1;
} }
@@ -340,7 +343,8 @@ int main(int argc, char *argv[])
property_tag = bacapp_known_property_tag( property_tag = bacapp_known_property_tag(
Target_Object_Type, Target_Object_Property); Target_Object_Type, Target_Object_Property);
} else if (property_tag >= MAX_BACNET_APPLICATION_TAG) { } else if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, "Error: tag=%ld - it must be less than %u\n", fprintf(
stderr, "Error: tag=%ld - it must be less than %u\n",
property_tag, MAX_BACNET_APPLICATION_TAG); property_tag, MAX_BACNET_APPLICATION_TAG);
return 1; return 1;
} }
@@ -353,8 +357,8 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
} else { } else {
fprintf(stderr, fprintf(
"Error: parser for property %s is not implemented\n", stderr, "Error: parser for property %s is not implemented\n",
bactext_property_name(Target_Object_Property)); bactext_property_name(Target_Object_Property));
return 1; return 1;
} }
@@ -387,7 +391,8 @@ int main(int argc, char *argv[])
} }
} }
if (args_remaining > 0) { if (args_remaining > 0) {
fprintf(stderr, "Error: Exceeded %d tag-value pairs.\n", fprintf(
stderr, "Error: Exceeded %d tag-value pairs.\n",
MAX_PROPERTY_VALUES); MAX_PROPERTY_VALUES);
return 1; return 1;
} }
+88 -67
View File
@@ -57,7 +57,8 @@ static bool Error_Detected = false;
/* Used for verbose */ /* Used for verbose */
static bool Verbose = false; static bool Verbose = false;
static void MyWritePropertyMultipleErrorHandler(BACNET_ADDRESS *src, static void MyWritePropertyMultipleErrorHandler(
BACNET_ADDRESS *src,
uint8_t invoke_id, uint8_t invoke_id,
uint8_t service_choice, uint8_t service_choice,
uint8_t *service_request, uint8_t *service_request,
@@ -71,10 +72,12 @@ static void MyWritePropertyMultipleErrorHandler(BACNET_ADDRESS *src,
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
len = wpm_error_ack_decode_apdu(service_request, service_len, &wp_data); len = wpm_error_ack_decode_apdu(service_request, service_len, &wp_data);
if (len > 0) { if (len > 0) {
printf("BACnet Error: %s: %s\n", printf(
"BACnet Error: %s: %s\n",
bactext_error_class_name((int)wp_data.error_class), bactext_error_class_name((int)wp_data.error_class),
bactext_error_code_name((int)wp_data.error_code)); bactext_error_code_name((int)wp_data.error_code));
printf("BACnet Error: %s %u: %s\n", printf(
"BACnet Error: %s %u: %s\n",
bactext_object_type_name((int)wp_data.object_type), bactext_object_type_name((int)wp_data.object_type),
(unsigned)wp_data.object_instance, (unsigned)wp_data.object_instance,
bactext_property_name((int)wp_data.object_property)); bactext_property_name((int)wp_data.object_property));
@@ -95,20 +98,21 @@ static void MyAbortHandler(
} }
} }
static void MyRejectHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason) MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
printf("BACnet Reject: %s\n", printf(
"BACnet Reject: %s\n",
bactext_reject_reason_name((int)reject_reason)); bactext_reject_reason_name((int)reject_reason));
Error_Detected = true; Error_Detected = true;
} }
} }
static void MyWritePropertyMultipleSimpleAckHandler( static void
BACNET_ADDRESS *src, uint8_t invoke_id) MyWritePropertyMultipleSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
(invoke_id == Request_Invoke_ID)) { (invoke_id == Request_Invoke_ID)) {
@@ -131,10 +135,12 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler( apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the data coming back from confirmed requests */ /* handle the data coming back from confirmed requests */
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, apdu_set_confirmed_simple_ack_handler(
SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE,
MyWritePropertyMultipleSimpleAckHandler); MyWritePropertyMultipleSimpleAckHandler);
/* handle any errors coming back */ /* handle any errors coming back */
apdu_set_complex_error_handler(SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE, apdu_set_complex_error_handler(
SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE,
MyWritePropertyMultipleErrorHandler); MyWritePropertyMultipleErrorHandler);
apdu_set_abort_handler(MyAbortHandler); apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler); apdu_set_reject_handler(MyRejectHandler);
@@ -164,9 +170,10 @@ static void cleanup(void)
static void print_usage(const char *filename) static void print_usage(const char *filename)
{ {
printf("Usage: %s device-instance object-type object-instance " printf(
"property[index] priority tag value [property[index] priority tag " "Usage: %s device-instance object-type object-instance "
"value]\n", "property[index] priority tag value [property[index] priority tag "
"value]\n",
filename); filename);
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
} }
@@ -174,65 +181,69 @@ static void print_usage(const char *filename)
static void print_help(const char *filename) static void print_help(const char *filename)
{ {
printf("Write one or more properties to one or more objects\n" printf("Write one or more properties to one or more objects\n"
"in a BACnet device.\n"); "in a BACnet device.\n");
printf("\n"); printf("\n");
printf("device-instance:\n" printf("device-instance:\n"
"BACnet Device Object Instance number that you are\n" "BACnet Device Object Instance number that you are\n"
"trying to communicate to. This number will be used\n" "trying to communicate to. This number will be used\n"
"to try and bind with the device using Who-Is and\n" "to try and bind with the device using Who-Is and\n"
"I-Am services. For example, if you were writing\n" "I-Am services. For example, if you were writing\n"
"Device Object 123, the device-instance would be 123.\n"); "Device Object 123, the device-instance would be 123.\n");
printf("\n"); printf("\n");
printf("object-type:\n" printf("object-type:\n"
"The object type is object that you are writing. It\n" "The object type is object that you are writing. It\n"
"can be defined either as the object-type name string\n" "can be defined either as the object-type name string\n"
"as defined in the BACnet specification, or as the\n" "as defined in the BACnet specification, or as the\n"
"integer value of the enumeration BACNET_OBJECT_TYPE\n" "integer value of the enumeration BACNET_OBJECT_TYPE\n"
"in bacenum.h. For example if you were writing Analog\n" "in bacenum.h. For example if you were writing Analog\n"
"Output 2, the object-type would be analog-output or 1.\n"); "Output 2, the object-type would be analog-output or 1.\n");
printf("\n"); printf("\n");
printf("object-instance:\n" printf("object-instance:\n"
"This is the object instance number of the object that\n" "This is the object instance number of the object that\n"
"you are writing. For example, if you were writing\n" "you are writing. For example, if you were writing\n"
"Analog Output 2, the object-instance would be 2.\n"); "Analog Output 2, the object-instance would be 2.\n");
printf("\n"); printf("\n");
printf("property:\n" printf("property:\n"
"The property is an integer value of the enumeration\n" "The property is an integer value of the enumeration\n"
"BACNET_PROPERTY_ID in bacenum.h. It is the property\n" "BACNET_PROPERTY_ID in bacenum.h. It is the property\n"
"you are writing. For example, if you were writing the\n" "you are writing. For example, if you were writing the\n"
"Present Value property, use 85 as the property.\n"); "Present Value property, use 85 as the property.\n");
printf("\n"); printf("\n");
printf("priority:\n" printf("priority:\n"
"This parameter is used for setting the priority of the\n" "This parameter is used for setting the priority of the\n"
"write. If Priority 0 is given, no priority is sent. The BACnet \n" "write. If Priority 0 is given, no priority is sent. The BACnet \n"
"standard states that the value is written at the lowest \n" "standard states that the value is written at the lowest \n"
"priority (16) if the object property supports priorities\n" "priority (16) if the object property supports priorities\n"
"when no priority is sent.\n"); "when no priority is sent.\n");
printf("\n"); printf("\n");
printf("index:\n" printf(
"index:\n"
"This integer parameter is the index number of an array.\n" "This integer parameter is the index number of an array.\n"
"If the property is an array, individual elements can be written\n" "If the property is an array, individual elements can be written\n"
"to if supported. If this parameter is -1, the index is ignored.\n"); "to if supported. If this parameter is -1, the index is ignored.\n");
printf("\n"); printf("\n");
printf("tag:\n" printf(
"tag:\n"
"Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \n" "Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \n"
"in bacenum.h. It is the data type of the value that you are\n" "in bacenum.h. It is the data type of the value that you are\n"
"writing. For example, if you were writing a REAL value, you would \n" "writing. For example, if you were writing a REAL value, you would \n"
"use a tag of 4.\n" "use a tag of 4.\n"
"Context tags are created using two tags in a row. The context tag\n" "Context tags are created using two tags in a row. The context tag\n"
"is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged REAL.\n"); "is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged "
printf( "REAL.\n");
"Complex data use the property argument and a tag number -1 to\n" printf("Complex data use the property argument and a tag number -1 to\n"
"lookup the appropriate internal application tag for the value.\n" "lookup the appropriate internal application tag for the value.\n"
"The complex data value argument varies in its construction.\n"); "The complex data value argument varies in its construction.\n");
printf("\n"); printf("\n");
printf("value:\n" printf(
"value:\n"
"The value is an ASCII representation of some type of data that you\n" "The value is an ASCII representation of some type of data that you\n"
"are writing. It is encoded using the tag information provided. For\n" "are writing. It is encoded using the tag information provided. For\n"
"example, if you were writing a REAL value of 100.0, you would use \n" "example, if you were writing a REAL value of 100.0, you would use \n"
"100.0 as the value.\n"); "100.0 as the value.\n");
printf("\n"); printf("\n");
printf("Here is a brief overview of BACnet property and tags:\n" printf(
"Here is a brief overview of BACnet property and tags:\n"
"Certain properties are expected to be written with certain \n" "Certain properties are expected to be written with certain \n"
"application tags, so you probably need to know which ones to use\n" "application tags, so you probably need to know which ones to use\n"
"with each property of each object. It is almost safe to say that\n" "with each property of each object. It is almost safe to say that\n"
@@ -241,11 +252,12 @@ static void print_help(const char *filename)
"the Any property type in the schedule object and the Present Value\n" "the Any property type in the schedule object and the Present Value\n"
"accepting REAL, BOOLEAN, NULL, etc.\n"); "accepting REAL, BOOLEAN, NULL, etc.\n");
printf("Perhaps it would be simpler for the demo to use this\n" printf("Perhaps it would be simpler for the demo to use this\n"
"kind of table - but this tool can also be used for negative\n" "kind of table - but this tool can also be used for negative\n"
"testing by passing the wrong tag to validate that the server\n" "testing by passing the wrong tag to validate that the server\n"
"returns an error, reject, or abort message.\n"); "returns an error, reject, or abort message.\n");
printf("\n"); printf("\n");
printf("Example:\n" printf(
"Example:\n"
"If you want write a value of 100 to the Present-Value in\n" "If you want write a value of 100 to the Present-Value in\n"
"Analog Output 44 and 45 of Device 123 at priority 16,\n" "Analog Output 44 and 45 of Device 123 at priority 16,\n"
"send the following command:\n" "send the following command:\n"
@@ -304,7 +316,8 @@ int main(int argc, char *argv[])
/* decode the command line parameters */ /* decode the command line parameters */
Target_Device_Object_Instance = strtol(argv[1], NULL, 0); Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - not greater than %u\n", fprintf(
stderr, "device-instance=%u - not greater than %u\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE); Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -332,7 +345,8 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
if (wpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) { if (wpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) {
fprintf(stderr, "object-type=%u - it must be less than %u\n", fprintf(
stderr, "object-type=%u - it must be less than %u\n",
wpm_object->object_type, MAX_BACNET_OBJECT_TYPE); wpm_object->object_type, MAX_BACNET_OBJECT_TYPE);
return 1; return 1;
} }
@@ -347,7 +361,8 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
if (wpm_object->object_instance > BACNET_MAX_INSTANCE) { if (wpm_object->object_instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "object-instance=%u - not greater than %u\n", fprintf(
stderr, "object-instance=%u - not greater than %u\n",
wpm_object->object_instance, BACNET_MAX_INSTANCE); wpm_object->object_instance, BACNET_MAX_INSTANCE);
return 1; return 1;
} }
@@ -356,20 +371,22 @@ int main(int argc, char *argv[])
wpm_object->listOfProperties = wpm_property; wpm_object->listOfProperties = wpm_property;
if (wpm_property) { if (wpm_property) {
/* Property[index] */ /* Property[index] */
scan_count = sscanf(argv[tag_value_arg], "%u[%u]", &property_id, scan_count = sscanf(
argv[tag_value_arg], "%u[%u]", &property_id,
&property_array_index); &property_array_index);
tag_value_arg++; tag_value_arg++;
args_remaining--; args_remaining--;
if (scan_count > 0) { if (scan_count > 0) {
wpm_property->propertyIdentifier = property_id; wpm_property->propertyIdentifier = property_id;
if (Verbose) { if (Verbose) {
printf("property-identifier=%u, array-index=%u\n", printf(
"property-identifier=%u, array-index=%u\n",
property_id, property_array_index); property_id, property_array_index);
} }
if (wpm_property->propertyIdentifier > if (wpm_property->propertyIdentifier >
MAX_BACNET_PROPERTY_ID) { MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, fprintf(
"property=%u - it must be less than %u\n", stderr, "property=%u - it must be less than %u\n",
wpm_property->propertyIdentifier, wpm_property->propertyIdentifier,
MAX_BACNET_PROPERTY_ID + 1); MAX_BACNET_PROPERTY_ID + 1);
return 1; return 1;
@@ -381,7 +398,8 @@ int main(int argc, char *argv[])
wpm_property->propertyArrayIndex = BACNET_ARRAY_ALL; wpm_property->propertyArrayIndex = BACNET_ARRAY_ALL;
} }
if (args_remaining <= 0) { if (args_remaining <= 0) {
fprintf(stderr, fprintf(
stderr,
"Error: missing priority and tag value pair.\n"); "Error: missing priority and tag value pair.\n");
return 1; return 1;
} }
@@ -428,12 +446,12 @@ int main(int argc, char *argv[])
printf("tag=%ld value=%s\n", property_tag, value_string); printf("tag=%ld value=%s\n", property_tag, value_string);
} }
if (property_tag < 0) { if (property_tag < 0) {
property_tag = property_tag = bacapp_known_property_tag(
bacapp_known_property_tag(wpm_object->object_type, wpm_object->object_type,
wpm_property->propertyIdentifier); wpm_property->propertyIdentifier);
} else if (property_tag >= MAX_BACNET_APPLICATION_TAG) { } else if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
fprintf(stderr, fprintf(
"Error: tag=%ld - it must be less than %u\n", stderr, "Error: tag=%ld - it must be less than %u\n",
property_tag, MAX_BACNET_APPLICATION_TAG); property_tag, MAX_BACNET_APPLICATION_TAG);
return 1; return 1;
} }
@@ -447,10 +465,11 @@ int main(int argc, char *argv[])
return 1; return 1;
} }
} else { } else {
fprintf(stderr, fprintf(
stderr,
"Error: parser for property %s is not implemented\n", "Error: parser for property %s is not implemented\n",
bactext_property_name( bactext_property_name(
wpm_property->propertyIdentifier)); wpm_property->propertyIdentifier));
return 1; return 1;
} }
wpm_property->value.next = NULL; wpm_property->value.next = NULL;
@@ -480,7 +499,8 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance, &max_apdu, &Target_Address); Target_Device_Object_Instance, &max_apdu, &Target_Address);
if (found) { if (found) {
if (Verbose) { if (Verbose) {
printf("Found Device %u in address_cache.\n", printf(
"Found Device %u in address_cache.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
} else { } else {
@@ -508,7 +528,8 @@ int main(int argc, char *argv[])
if (found) { if (found) {
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
if (Verbose) { if (Verbose) {
printf("Sending WritePropertyMultiple to Device %u.\n", printf(
"Sending WritePropertyMultiple to Device %u.\n",
Target_Device_Object_Instance); Target_Device_Object_Instance);
} }
Request_Invoke_ID = Send_Write_Property_Multiple_Request( Request_Invoke_ID = Send_Write_Property_Multiple_Request(
+13 -8
View File
@@ -34,7 +34,8 @@ bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
return status; return status;
} }
uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */ uint16_t apdu_decode_confirmed_service_request(
uint8_t *apdu, /* APDU data */
uint16_t apdu_len, uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA *service_data, BACNET_CONFIRMED_SERVICE_DATA *service_data,
@@ -63,7 +64,8 @@ uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
return len; return len;
} }
void apdu_handler(BACNET_ADDRESS *src, void apdu_handler(
BACNET_ADDRESS *src,
uint8_t *apdu, /* APDU data */ uint8_t *apdu, /* APDU data */
uint16_t apdu_len) uint16_t apdu_len)
@@ -87,18 +89,21 @@ void apdu_handler(BACNET_ADDRESS *src,
break; break;
} }
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
handler_read_property(service_request, service_request_len, handler_read_property(
src, &service_data); service_request, service_request_len, src,
&service_data);
} }
#ifdef WRITE_PROPERTY #ifdef WRITE_PROPERTY
else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) { else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
handler_write_property(service_request, service_request_len, handler_write_property(
src, &service_data); service_request, service_request_len, src,
&service_data);
} }
#endif #endif
else { else {
handler_unrecognized_service(service_request, handler_unrecognized_service(
service_request_len, src, &service_data); service_request, service_request_len, src,
&service_data);
} }
break; break;
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
+6 -3
View File
@@ -29,8 +29,9 @@ float AV_Present_Value[MAX_ANALOG_VALUES];
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance(uint32_t object_instance) bool Analog_Value_Valid_Instance(uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES) {
return true; return true;
}
return false; return false;
} }
@@ -69,7 +70,8 @@ char *Analog_Value_Name(uint32_t object_instance)
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Encode_Property_APDU(uint8_t *apdu, int Analog_Value_Encode_Property_APDU(
uint8_t *apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
uint32_t array_index, uint32_t array_index,
@@ -136,7 +138,8 @@ int Analog_Value_Encode_Property_APDU(uint8_t *apdu,
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data, bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
+27 -27
View File
@@ -1,10 +1,10 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef AV_H #ifndef AV_H
#define AV_H #define AV_H
@@ -21,31 +21,31 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void Analog_Value_Property_Lists(const int **pRequired, void Analog_Value_Property_Lists(
const int **pOptional, const int **pRequired, const int **pOptional, const int **pProprietary);
const int **pProprietary); bool Analog_Value_Valid_Instance(uint32_t object_instance);
bool Analog_Value_Valid_Instance(uint32_t object_instance); unsigned Analog_Value_Count(void);
unsigned Analog_Value_Count(void); uint32_t Analog_Value_Index_To_Instance(unsigned index);
uint32_t Analog_Value_Index_To_Instance(unsigned index); char *Analog_Value_Name(uint32_t object_instance);
char *Analog_Value_Name(uint32_t object_instance);
int Analog_Value_Encode_Property_APDU(uint8_t * apdu, int Analog_Value_Encode_Property_APDU(
uint32_t object_instance, uint8_t *apdu,
BACNET_PROPERTY_ID property, uint32_t object_instance,
uint32_t array_index, BACNET_PROPERTY_ID property,
BACNET_ERROR_CLASS * error_class, uint32_t array_index,
BACNET_ERROR_CODE * error_code); BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, bool Analog_Value_Write_Property(
BACNET_ERROR_CLASS * error_class, BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_ERROR_CODE * error_code); BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
bool Analog_Value_Present_Value_Set(uint32_t object_instance, bool Analog_Value_Present_Value_Set(
float value, uint32_t object_instance, float value, uint8_t priority);
uint8_t priority); float Analog_Value_Present_Value(uint32_t object_instance);
float Analog_Value_Present_Value(uint32_t object_instance);
void Analog_Value_Init(void); void Analog_Value_Init(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
+9 -7
View File
@@ -12,7 +12,7 @@
#include "bacnet/datalink/bip.h" #include "bacnet/datalink/bip.h"
#include "socketWrapper.h" #include "socketWrapper.h"
#include "w5100Wrapper.h" #include "w5100Wrapper.h"
//#include "bacport.h" // #include "bacport.h"
/** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */ /** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */
@@ -61,7 +61,8 @@ void bip_set_interface(const char *ifname)
bip_set_addr(local_address); bip_set_addr(local_address);
if (BIP_Debug) { if (BIP_Debug) {
fprintf(stderr, "Interface: %s\n", ifname); fprintf(stderr, "Interface: %s\n", ifname);
fprintf(stderr, "IP Address: %d.%d.%d.%d\n", local_address[0], fprintf(
stderr, "IP Address: %d.%d.%d.%d\n", local_address[0],
local_address[1], local_address[2], local_address[3]); local_address[1], local_address[2], local_address[3]);
} }
@@ -74,9 +75,9 @@ void bip_set_interface(const char *ifname)
bip_set_broadcast_addr(broadcast_address); bip_set_broadcast_addr(broadcast_address);
if (BIP_Debug) { if (BIP_Debug) {
fprintf(stderr, "IP Broadcast Address: %d.%d.%d.%d\n", fprintf(
broadcast_address[0], broadcast_address[1], broadcast_address[2], stderr, "IP Broadcast Address: %d.%d.%d.%d\n", broadcast_address[0],
broadcast_address[3]); broadcast_address[1], broadcast_address[2], broadcast_address[3]);
} }
} }
@@ -102,10 +103,11 @@ bool bip_init(char *ifname)
uint8_t sock_fd = 0; uint8_t sock_fd = 0;
bool isOpen = false; bool isOpen = false;
if (ifname) if (ifname) {
bip_set_interface(ifname); bip_set_interface(ifname);
else } else {
bip_set_interface("eth0"); bip_set_interface("eth0");
}
/* assumes that the driver has already been initialized */ /* assumes that the driver has already been initialized */
for (sock_fd = 0; sock_fd < MAX_SOCK_NUM; sock_fd++) { for (sock_fd = 0; sock_fd < MAX_SOCK_NUM; sock_fd++) {
+27 -15
View File
@@ -37,7 +37,7 @@ static uint8_t BIP_Broadcast_Address[4] = { 0, 0, 0, 0 };
uint32_t convertBIP_Address2uint32(const suint8_t *bip_address) uint32_t convertBIP_Address2uint32(const suint8_t *bip_address)
{ {
return (uint32_t)((bip_address[0] * 2 ^ 24) + (bip_address[1] * 2 ^ 16) + return (uint32_t)((bip_address[0] * 2 ^ 24) + (bip_address[1] * 2 ^ 16) +
(bip_address[2] * 2 ^ 8) + bip_address[3]); (bip_address[2] * 2 ^ 8) + bip_address[3]);
} }
/** Convert from uint32_t IPv4 address to uint8_t[4] address /** Convert from uint32_t IPv4 address to uint8_t[4] address
@@ -76,8 +76,9 @@ bool bip_valid(void)
void bip_set_addr(const uint8_t *net_address) void bip_set_addr(const uint8_t *net_address)
{ /* in network byte order */ { /* in network byte order */
for (uint8_t i = 0; i < 4; i++) for (uint8_t i = 0; i < 4; i++) {
BIP_Address[i] = net_address[i]; BIP_Address[i] = net_address[i];
}
} }
/* returns network byte order */ /* returns network byte order */
@@ -88,8 +89,9 @@ uint8_t *bip_get_addr(void)
void bip_set_broadcast_addr(const uint8_t *net_address) void bip_set_broadcast_addr(const uint8_t *net_address)
{ /* in network byte order */ { /* in network byte order */
for (uint8_t i = 0; i < 4; i++) for (uint8_t i = 0; i < 4; i++) {
BIP_Broadcast_Address[i] = net_address[i]; BIP_Broadcast_Address[i] = net_address[i];
}
} }
/* returns network byte order */ /* returns network byte order */
@@ -109,7 +111,8 @@ uint16_t bip_get_port(void)
return ntohs(BIP_Port); return ntohs(BIP_Port);
} }
static int bip_decode_bip_address(const BACNET_ADDRESS *bac_addr, static int bip_decode_bip_address(
const BACNET_ADDRESS *bac_addr,
uint8_t *address, /* in network format */ uint8_t *address, /* in network format */
uint16_t *port) uint16_t *port)
{ /* in network format */ { /* in network format */
@@ -133,7 +136,8 @@ static int bip_decode_bip_address(const BACNET_ADDRESS *bac_addr,
* @param pdu_len [in] Number of bytes in the pdu buffer. * @param pdu_len [in] Number of bytes in the pdu buffer.
* @return Number of bytes sent on success, negative number on failure. * @return Number of bytes sent on success, negative number on failure.
*/ */
int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */ int bip_send_pdu(
BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
@@ -159,19 +163,22 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
if ((dest->net == BACNET_BROADCAST_NETWORK) || if ((dest->net == BACNET_BROADCAST_NETWORK) ||
((dest->net > 0) && (dest->len == 0)) || (dest->mac_len == 0)) { ((dest->net > 0) && (dest->len == 0)) || (dest->mac_len == 0)) {
/* broadcast */ /* broadcast */
for (uint8_t i = 0; i < 4; i++) for (uint8_t i = 0; i < 4; i++) {
address[i] = BIP_Broadcast_Address[i]; address[i] = BIP_Broadcast_Address[i];
}
port = BIP_Port; port = BIP_Port;
mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU; mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0], fprintf(
stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0],
address[1], address[2], address[3], port); address[1], address[2], address[3], port);
#endif #endif
} else if (dest->mac_len == 6) { } else if (dest->mac_len == 6) {
bip_decode_bip_address(dest, address, &port); bip_decode_bip_address(dest, address, &port);
mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU; mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0], fprintf(
stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0],
address[1], address[2], address[3], port); address[1], address[2], address[3], port);
#endif #endif
} else { } else {
@@ -207,7 +214,8 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
* @param timeout [in] The number of milliseconds to wait for a packet. * @param timeout [in] The number of milliseconds to wait for a packet.
* @return The number of octets (remaining) in the PDU, or zero on failure. * @return The number of octets (remaining) in the PDU, or zero on failure.
*/ */
uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */ uint16_t bip_receive(
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
@@ -224,8 +232,9 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
int function = 0; int function = 0;
/* Make sure the socket is open */ /* Make sure the socket is open */
if (BIP_Socket < 0) if (BIP_Socket < 0) {
return 0; return 0;
}
if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) { if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) {
memcpy(&src_addr, &src->mac[0], 4); memcpy(&src_addr, &src->mac[0], 4);
@@ -240,12 +249,14 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
} }
/* no problem, just no bytes */ /* no problem, just no bytes */
if (received_bytes == 0) if (received_bytes == 0) {
return 0; return 0;
}
/* the signature of a BACnet/IP packet */ /* the signature of a BACnet/IP packet */
if (pdu[0] != BVLL_TYPE_BACNET_IP) if (pdu[0] != BVLL_TYPE_BACNET_IP) {
return 0; return 0;
}
/* Erase up to 16 bytes after the received bytes as safety margin to /* Erase up to 16 bytes after the received bytes as safety margin to
* ensure that the decoding functions will run into a 'safe field' * ensure that the decoding functions will run into a 'safe field'
@@ -272,7 +283,7 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
(function == BVLC_ORIGINAL_BROADCAST_NPDU)) { (function == BVLC_ORIGINAL_BROADCAST_NPDU)) {
/* ignore messages from me */ /* ignore messages from me */
if ((convertBIP_Address2uint32(src_addr) == if ((convertBIP_Address2uint32(src_addr) ==
convertBIP_Address2uint32(BIP_Address)) && convertBIP_Address2uint32(BIP_Address)) &&
(src_port == BIP_Port)) { (src_port == BIP_Port)) {
pdu_len = 0; pdu_len = 0;
#if 0 #if 0
@@ -284,7 +295,8 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
memcpy(&src->mac[0], &src_addr, 4); memcpy(&src->mac[0], &src_addr, 4);
memcpy(&src->mac[4], &src_port, 2); memcpy(&src->mac[4], &src_port, 2);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0], fprintf(
stderr, "BIP receive from %d.%d.%d.%d\n", src->mac[0],
src->mac[1], src->mac[2], src->mac[3]); src->mac[1], src->mac[2], src->mac[3]);
#endif #endif
/* FIXME: check destination address */ /* FIXME: check destination address */
@@ -321,7 +333,7 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
memcpy(&src_addr, &pdu[4], 4); memcpy(&src_addr, &pdu[4], 4);
memcpy(&src_port, &pdu[8], 2); memcpy(&src_port, &pdu[8], 2);
if ((convertBIP_Address2uint32(src_addr) == if ((convertBIP_Address2uint32(src_addr) ==
convertBIP_Address2uint32(BIP_Address)) && convertBIP_Address2uint32(BIP_Address)) &&
(src_port == BIP_Port)) { (src_port == BIP_Port)) {
/* ignore messages from me */ /* ignore messages from me */
pdu_len = 0; pdu_len = 0;
+56 -55
View File
@@ -1,10 +1,10 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef BIP_H #ifndef BIP_H
#define BIP_H #define BIP_H
@@ -16,7 +16,7 @@
/* specific defines for BACnet/IP over Ethernet */ /* specific defines for BACnet/IP over Ethernet */
#define BIP_HEADER_MAX (1 + 1 + 2) #define BIP_HEADER_MAX (1 + 1 + 2)
#define BIP_MPDU_MAX (BIP_HEADER_MAX+MAX_PDU) #define BIP_MPDU_MAX (BIP_HEADER_MAX + MAX_PDU)
#define BVLL_TYPE_BACNET_IP (0x81) #define BVLL_TYPE_BACNET_IP (0x81)
@@ -24,69 +24,70 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* note: define init, set_interface, and cleanup in your port */ /* note: define init, set_interface, and cleanup in your port */
/* on Linux, ifname is eth0, ath0, arc0, and others. /* on Linux, ifname is eth0, ath0, arc0, and others.
on Windows, ifname is the dotted ip address of the interface */ on Windows, ifname is the dotted ip address of the interface */
bool bip_init(char *ifname); bool bip_init(char *ifname);
void bip_set_interface(const char *ifname); void bip_set_interface(const char *ifname);
void bip_cleanup(void); void bip_cleanup(void);
/* Convert uint8_t IPv4 to uint32 */ /* Convert uint8_t IPv4 to uint32 */
uint32_t convertBIP_Address2uint32(const uint8_t * bip_address); uint32_t convertBIP_Address2uint32(const uint8_t *bip_address);
void convertUint32Address_2_uint8Address(uint32_t ip, void convertUint32Address_2_uint8Address(uint32_t ip, uint8_t *address);
uint8_t * address); /* common BACnet/IP functions */
/* common BACnet/IP functions */ void bip_set_socket(uint8_t sock_fd);
void bip_set_socket(uint8_t sock_fd); uint8_t bip_socket(void);
uint8_t bip_socket(void); bool bip_valid(void);
bool bip_valid(void); void bip_get_broadcast_address(BACNET_ADDRESS *dest); /* destination address */
void bip_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */ void bip_get_my_address(BACNET_ADDRESS *my_address);
void bip_get_my_address(BACNET_ADDRESS * my_address);
/* function to send a packet out the BACnet/IP socket */ /* function to send a packet out the BACnet/IP socket */
/* returns zero on success, non-zero on failure */ /* returns zero on success, non-zero on failure */
int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */ int bip_send_pdu(
BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len); /* number of bytes of data */ unsigned pdu_len); /* number of bytes of data */
/* receives a BACnet/IP packet */ /* receives a BACnet/IP packet */
/* returns the number of octets in the PDU, or zero on failure */ /* returns the number of octets in the PDU, or zero on failure */
uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */ uint16_t bip_receive(
BACNET_ADDRESS *src, /* source address */
uint8_t * pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout); /* milliseconds to wait for a packet */ unsigned timeout); /* milliseconds to wait for a packet */
/* use host byte order for setting */ /* use host byte order for setting */
void bip_set_port(uint16_t port); void bip_set_port(uint16_t port);
/* returns host byte order */ /* returns host byte order */
uint16_t bip_get_port(void); uint16_t bip_get_port(void);
/* use network byte order for setting */ /* use network byte order for setting */
void bip_set_addr(const uint8_t * net_address); void bip_set_addr(const uint8_t *net_address);
/* returns network byte order */ /* returns network byte order */
uint8_t *bip_get_addr(void); uint8_t *bip_get_addr(void);
/* use network byte order for setting */ /* use network byte order for setting */
void bip_set_broadcast_addr(const uint8_t * net_address); void bip_set_broadcast_addr(const uint8_t *net_address);
/* returns network byte order */ /* returns network byte order */
uint8_t *bip_get_broadcast_addr(void); uint8_t *bip_get_broadcast_addr(void);
/* gets an IP address by name, where name can be a /* gets an IP address by name, where name can be a
string that is an IP address in dotted form, or string that is an IP address in dotted form, or
a name that is a domain name a name that is a domain name
returns 0 if not found, or returns 0 if not found, or
an IP address in network byte order */ an IP address in network byte order */
long bip_getaddrbyname(const char *host_name); long bip_getaddrbyname(const char *host_name);
void bip_debug_enable(void); void bip_debug_enable(void);
void bip_debug_disable(void); void bip_debug_disable(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
+8 -4
View File
@@ -27,8 +27,9 @@ static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance(uint32_t object_instance) bool Binary_Value_Valid_Instance(uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_VALUES) if (object_instance < MAX_BINARY_VALUES) {
return true; return true;
}
return false; return false;
} }
@@ -50,8 +51,9 @@ unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_VALUES; unsigned index = MAX_BINARY_VALUES;
if (object_instance < MAX_BINARY_VALUES) if (object_instance < MAX_BINARY_VALUES) {
index = object_instance; index = object_instance;
}
return index; return index;
} }
@@ -81,7 +83,8 @@ char *Binary_Value_Name(uint32_t object_instance)
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Binary_Value_Encode_Property_APDU(uint8_t *apdu, int Binary_Value_Encode_Property_APDU(
uint8_t *apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
uint32_t array_index, uint32_t array_index,
@@ -153,7 +156,8 @@ int Binary_Value_Encode_Property_APDU(uint8_t *apdu,
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data, bool Binary_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
+24 -24
View File
@@ -1,10 +1,10 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef BV_H #ifndef BV_H
#define BV_H #define BV_H
@@ -18,31 +18,31 @@
#define MAX_BINARY_VALUES 10 #define MAX_BINARY_VALUES 10
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void Binary_Value_Property_Lists(const int **pRequired, void Binary_Value_Property_Lists(
const int **pOptional, const int **pRequired, const int **pOptional, const int **pProprietary);
const int **pProprietary); bool Binary_Value_Valid_Instance(uint32_t object_instance);
bool Binary_Value_Valid_Instance(uint32_t object_instance); unsigned Binary_Value_Count(void);
unsigned Binary_Value_Count(void); uint32_t Binary_Value_Index_To_Instance(unsigned index);
uint32_t Binary_Value_Index_To_Instance(unsigned index); char *Binary_Value_Name(uint32_t object_instance);
char *Binary_Value_Name(uint32_t object_instance);
void Binary_Value_Init(void); void Binary_Value_Init(void);
int Binary_Value_Encode_Property_APDU(uint8_t * apdu, int Binary_Value_Encode_Property_APDU(
uint32_t object_instance, uint8_t *apdu,
BACNET_PROPERTY_ID property, uint32_t object_instance,
uint32_t array_index, BACNET_PROPERTY_ID property,
BACNET_ERROR_CLASS * error_class, uint32_t array_index,
BACNET_ERROR_CODE * error_code); BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, bool Binary_Value_Write_Property(
BACNET_ERROR_CLASS * error_class, BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_ERROR_CODE * error_code); BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
#ifdef __cplusplus #ifdef __cplusplus
} }
+4 -2
View File
@@ -54,7 +54,8 @@ static int bvlc_encode_bvlc_result(uint8_t *pdu, BACNET_BVLC_RESULT result_code)
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
static int bvlc_send_mpdu(const uint8_t *dest_addr, /* the destination address */ static int bvlc_send_mpdu(
const uint8_t *dest_addr, /* the destination address */
const uint16_t *dest_port, /* the destination port */ const uint16_t *dest_port, /* the destination port */
uint8_t *mtu, /* the data */ uint8_t *mtu, /* the data */
uint16_t mtu_len) uint16_t mtu_len)
@@ -72,7 +73,8 @@ static int bvlc_send_mpdu(const uint8_t *dest_addr, /* the destination address *
* @param dest_addr - destination address * @param dest_addr - destination address
* @param dest_port - destination port * @param dest_port - destination port
*/ */
static void bvlc_send_result(const uint8_t *dest_addr, static void bvlc_send_result(
const uint8_t *dest_addr,
const uint16_t *dest_port, /* the destination address */ const uint16_t *dest_port, /* the destination address */
BACNET_BVLC_RESULT result_code) BACNET_BVLC_RESULT result_code)
{ {
+2 -4
View File
@@ -16,10 +16,8 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
uint16_t bvlc_for_non_bbmd(uint8_t * addr, uint16_t bvlc_for_non_bbmd(
uint16_t * port, uint8_t *addr, uint16_t *port, uint8_t *npdu, uint16_t received_bytes);
uint8_t * npdu,
uint16_t received_bytes);
BACNET_BVLC_FUNCTION bvlc_get_function_code(void); BACNET_BVLC_FUNCTION bvlc_get_function_code(void);
+27 -27
View File
@@ -1,10 +1,10 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef DATALINK_H #ifndef DATALINK_H
#define DATALINK_H #define DATALINK_H
@@ -46,17 +46,17 @@
#include "bvlc-arduino.h" #include "bvlc-arduino.h"
#define datalink_init bip_init #define datalink_init bip_init
//#if defined(BBMD_ENABLED) && BBMD_ENABLED // #if defined(BBMD_ENABLED) && BBMD_ENABLED
//#define datalink_send_pdu bvlc_send_pdu // #define datalink_send_pdu bvlc_send_pdu
//#define datalink_receive bvlc_receive // #define datalink_receive bvlc_receive
//#else // #else
#define datalink_send_pdu bip_send_pdu #define datalink_send_pdu bip_send_pdu
#define datalink_receive bip_receive #define datalink_receive bip_receive
//#endif // #endif
#define datalink_cleanup bip_cleanup #define datalink_cleanup bip_cleanup
#define datalink_get_broadcast_address bip_get_broadcast_address #define datalink_get_broadcast_address bip_get_broadcast_address
#ifdef BAC_ROUTING #ifdef BAC_ROUTING
extern void routed_get_my_address(BACNET_ADDRESS * my_address); extern void routed_get_my_address(BACNET_ADDRESS *my_address);
#define datalink_get_my_address routed_get_my_address #define datalink_get_my_address routed_get_my_address
#else #else
#define datalink_get_my_address bip_get_my_address #define datalink_get_my_address bip_get_my_address
@@ -66,25 +66,24 @@ extern void routed_get_my_address(BACNET_ADDRESS * my_address);
#include "bacnet/npdu.h" #include "bacnet/npdu.h"
#define MAX_HEADER (8) #define MAX_HEADER (8)
#define MAX_MPDU (MAX_HEADER+MAX_PDU) #define MAX_MPDU (MAX_HEADER + MAX_PDU)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int datalink_send_pdu(BACNET_ADDRESS * dest, int datalink_send_pdu(
BACNET_NPDU_DATA * npdu_data, BACNET_ADDRESS *dest,
uint8_t * pdu, BACNET_NPDU_DATA *npdu_data,
unsigned pdu_len); uint8_t *pdu,
extern uint16_t datalink_receive(BACNET_ADDRESS * src, unsigned pdu_len);
uint8_t * pdu, extern uint16_t datalink_receive(
uint16_t max_pdu, BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout);
unsigned timeout); extern void datalink_cleanup(void);
extern void datalink_cleanup(void); extern void datalink_get_broadcast_address(BACNET_ADDRESS *dest);
extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest); extern void datalink_get_my_address(BACNET_ADDRESS *my_address);
extern void datalink_get_my_address(BACNET_ADDRESS * my_address); extern void datalink_set_interface(char *ifname);
extern void datalink_set_interface(char *ifname); extern void datalink_set(char *datalink_string);
extern void datalink_set(char *datalink_string);
#ifdef __cplusplus #ifdef __cplusplus
} }
@@ -111,7 +110,8 @@ extern "C" {
* chosen at runtime from among these choices. * chosen at runtime from among these choices.
* - Clause 10 POINT-TO-POINT (PTP) and Clause 11 EIA/CEA-709.1 ("LonTalk") LAN * - Clause 10 POINT-TO-POINT (PTP) and Clause 11 EIA/CEA-709.1 ("LonTalk") LAN
* are not currently supported by this project. * are not currently supported by this project.
*//** @defgroup DLTemplates DataLink Template Functions */
/** @defgroup DLTemplates DataLink Template Functions
* @ingroup DataLink * @ingroup DataLink
* Most of the functions in this group are function templates which are assigned * Most of the functions in this group are function templates which are assigned
* to a specific DataLink network layer implementation either at compile time or * to a specific DataLink network layer implementation either at compile time or
+16 -10
View File
@@ -60,8 +60,9 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
(char *)&Object_Instance_Number, (char *)&Object_Instance_Number,
sizeof(Object_Instance_Number), sizeof(Object_Instance_Number),
EEPROM_BACNET_ID_ADDR); */ EEPROM_BACNET_ID_ADDR); */
} else } else {
status = false; status = false;
}
return status; return status;
} }
@@ -69,7 +70,8 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
bool Device_Valid_Object_Instance_Number(uint32_t object_id) bool Device_Valid_Object_Instance_Number(uint32_t object_id)
{ {
/* BACnet allows for a wildcard instance number */ /* BACnet allows for a wildcard instance number */
return ((Object_Instance_Number == object_id) || return (
(Object_Instance_Number == object_id) ||
(object_id == BACNET_MAX_INSTANCE)); (object_id == BACNET_MAX_INSTANCE));
} }
@@ -136,7 +138,8 @@ bool Device_Object_List_Identifier(
} }
/* return the length of the apdu encoded or -1 for error */ /* return the length of the apdu encoded or -1 for error */
int Device_Encode_Property_APDU(uint8_t *apdu, int Device_Encode_Property_APDU(
uint8_t *apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
uint32_t array_index, uint32_t array_index,
@@ -207,7 +210,8 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
bitstring_init(&bit_string); bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */ /* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t)i, bitstring_set_bit(
&bit_string, (uint8_t)i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
} }
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
@@ -230,8 +234,9 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
count = Device_Object_List_Count(); count = Device_Object_List_Count();
/* Array element zero is the number of objects in the list */ /* Array element zero is the number of objects in the list */
if (array_index == 0) if (array_index == 0) {
apdu_len = encode_application_unsigned(&apdu[0], count); apdu_len = encode_application_unsigned(&apdu[0], count);
}
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. Note that more than likely you will have */ /* into one packet. Note that more than likely you will have */
/* to return an error if the number of encoded objects exceeds */ /* to return an error if the number of encoded objects exceeds */
@@ -254,10 +259,10 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
} }
} else { } else {
if (Device_Object_List_Identifier( if (Device_Object_List_Identifier(
array_index, &object_type, &instance)) array_index, &object_type, &instance)) {
apdu_len = encode_application_object_id( apdu_len = encode_application_object_id(
&apdu[0], object_type, instance); &apdu[0], object_type, instance);
else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX; *error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -321,7 +326,8 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
return apdu_len; return apdu_len;
} }
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data, bool Device_Write_Property(
BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
@@ -399,8 +405,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data,
encoding = encoding =
characterstring_encoding(&value.type.Character_String); characterstring_encoding(&value.type.Character_String);
if (encoding == CHARACTER_ANSI_X34) { if (encoding == CHARACTER_ANSI_X34) {
if (characterstring_ansi_copy(&Object_Name[0], if (characterstring_ansi_copy(
sizeof(Object_Name), &Object_Name[0], sizeof(Object_Name),
&value.type.Character_String)) { &value.type.Character_String)) {
status = true; status = true;
} else { } else {
+62 -66
View File
@@ -15,98 +15,94 @@
#include "bacnet/wp.h" #include "bacnet/wp.h"
#include "bacnet/readrange.h" #include "bacnet/readrange.h"
typedef unsigned (*object_count_function) (void); typedef unsigned (*object_count_function)(void);
typedef uint32_t(*object_index_to_instance_function) typedef uint32_t (*object_index_to_instance_function)(unsigned index);
(unsigned index); typedef char *(*object_name_function)(uint32_t object_instance);
typedef char *(*object_name_function)
(uint32_t object_instance);
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void Device_Object_Function_Set(BACNET_OBJECT_TYPE object_type, void Device_Object_Function_Set(
object_count_function count_function, BACNET_OBJECT_TYPE object_type,
object_index_to_instance_function index_function, object_count_function count_function,
object_name_function name_function); object_index_to_instance_function index_function,
object_name_function name_function);
void Device_Init(void); void Device_Init(void);
void Device_Property_Lists(const int **pRequired, void Device_Property_Lists(
const int **pOptional, const int **pRequired, const int **pOptional, const int **pProprietary);
const int **pProprietary);
uint32_t Device_Object_Instance_Number(void); uint32_t Device_Object_Instance_Number(void);
bool Device_Set_Object_Instance_Number(uint32_t object_id); bool Device_Set_Object_Instance_Number(uint32_t object_id);
bool Device_Valid_Object_Instance_Number(uint32_t object_id); bool Device_Valid_Object_Instance_Number(uint32_t object_id);
unsigned Device_Object_List_Count(void); unsigned Device_Object_List_Count(void);
bool Device_Object_List_Identifier(uint32_t array_index, bool Device_Object_List_Identifier(
BACNET_OBJECT_TYPE *object_type, uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance);
uint32_t * instance);
BACNET_DEVICE_STATUS Device_System_Status(void); BACNET_DEVICE_STATUS Device_System_Status(void);
void Device_Set_System_Status(BACNET_DEVICE_STATUS status); void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
const char *Device_Vendor_Name(void); const char *Device_Vendor_Name(void);
uint16_t Device_Vendor_Identifier(void); uint16_t Device_Vendor_Identifier(void);
const char *Device_Model_Name(void); const char *Device_Model_Name(void);
bool Device_Set_Model_Name(const char *name, bool Device_Set_Model_Name(const char *name, size_t length);
size_t length);
const char *Device_Firmware_Revision(void); const char *Device_Firmware_Revision(void);
const char *Device_Application_Software_Version(void); const char *Device_Application_Software_Version(void);
bool Device_Set_Application_Software_Version(const char *name, bool Device_Set_Application_Software_Version(const char *name, size_t length);
size_t length);
bool Device_Set_Object_Name(const char *name, bool Device_Set_Object_Name(const char *name, size_t length);
size_t length); const char *Device_Object_Name(void);
const char *Device_Object_Name(void);
const char *Device_Description(void); const char *Device_Description(void);
bool Device_Set_Description(const char *name, bool Device_Set_Description(const char *name, size_t length);
size_t length);
const char *Device_Location(void); const char *Device_Location(void);
bool Device_Set_Location(const char *name, bool Device_Set_Location(const char *name, size_t length);
size_t length);
/* some stack-centric constant values - no set methods */ /* some stack-centric constant values - no set methods */
uint8_t Device_Protocol_Version(void); uint8_t Device_Protocol_Version(void);
uint8_t Device_Protocol_Revision(void); uint8_t Device_Protocol_Revision(void);
BACNET_SEGMENTATION Device_Segmentation_Supported(void); BACNET_SEGMENTATION Device_Segmentation_Supported(void);
uint8_t Device_Database_Revision(void); uint8_t Device_Database_Revision(void);
void Device_Set_Database_Revision(uint8_t revision); void Device_Set_Database_Revision(uint8_t revision);
bool Device_Valid_Object_Name(const char *object_name, bool Device_Valid_Object_Name(
BACNET_OBJECT_TYPE *object_type, const char *object_name,
uint32_t * object_instance); BACNET_OBJECT_TYPE *object_type,
char *Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type, uint32_t *object_instance);
uint32_t object_instance); char *Device_Valid_Object_Id(
BACNET_OBJECT_TYPE object_type, uint32_t object_instance);
int Device_Encode_Property_APDU(uint8_t * apdu, int Device_Encode_Property_APDU(
uint32_t object_instance, uint8_t *apdu,
BACNET_PROPERTY_ID property, uint32_t object_instance,
uint32_t array_index, BACNET_PROPERTY_ID property,
BACNET_ERROR_CLASS * error_class, uint32_t array_index,
BACNET_ERROR_CODE * error_code); BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, bool Device_Write_Property(
BACNET_ERROR_CLASS * error_class, BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_ERROR_CODE * error_code); BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
bool DeviceGetRRInfo(uint32_t Object, /* Which particular object - obviously not important for device object */ bool DeviceGetRRInfo(
uint32_t Object, /* Which particular object - obviously not important for
device object */
BACNET_PROPERTY_ID Property, /* Which property */ BACNET_PROPERTY_ID Property, /* Which property */
RR_PROP_INFO * pInfo, /* Where to put the information */ RR_PROP_INFO *pInfo, /* Where to put the information */
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code);
#ifdef __cplusplus #ifdef __cplusplus
} }
+30 -24
View File
@@ -26,7 +26,8 @@
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */ or sets the error, and returns -1 */
int Encode_Property_APDU(uint8_t *apdu, int Encode_Property_APDU(
uint8_t *apdu,
BACNET_READ_PROPERTY_DATA *rp_data, BACNET_READ_PROPERTY_DATA *rp_data,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
@@ -37,23 +38,26 @@ int Encode_Property_APDU(uint8_t *apdu,
switch (rp_data->object_type) { switch (rp_data->object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
apdu_len = Device_Encode_Property_APDU(&apdu[0], apdu_len = Device_Encode_Property_APDU(
rp_data->object_instance, rp_data->object_property, &apdu[0], rp_data->object_instance,
rp_data->array_index, error_class, error_code); rp_data->object_property, rp_data->array_index, error_class,
error_code);
} }
break; break;
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Valid_Instance(rp_data->object_instance)) { if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
apdu_len = Analog_Value_Encode_Property_APDU(&apdu[0], apdu_len = Analog_Value_Encode_Property_APDU(
rp_data->object_instance, rp_data->object_property, &apdu[0], rp_data->object_instance,
rp_data->array_index, error_class, error_code); rp_data->object_property, rp_data->array_index, error_class,
error_code);
} }
break; break;
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Valid_Instance(rp_data->object_instance)) { if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
apdu_len = Binary_Value_Encode_Property_APDU(&apdu[0], apdu_len = Binary_Value_Encode_Property_APDU(
rp_data->object_instance, rp_data->object_property, &apdu[0], rp_data->object_instance,
rp_data->array_index, error_class, error_code); rp_data->object_property, rp_data->array_index, error_class,
error_code);
} }
break; break;
default: default:
@@ -65,7 +69,8 @@ int Encode_Property_APDU(uint8_t *apdu,
return apdu_len; return apdu_len;
} }
void handler_read_property(uint8_t *service_request, void handler_read_property(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
@@ -87,25 +92,26 @@ void handler_read_property(uint8_t *service_request,
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RP_ABORT; goto RP_ABORT;
} }
len = rp_decode_service_request(service_request, service_len, &data); len = rp_decode_service_request(service_request, service_len, &data);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, ABORT_REASON_OTHER, true); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_OTHER, true);
goto RP_ABORT; goto RP_ABORT;
} }
/* most cases will be error */ /* most cases will be error */
ack_len = rp_ack_encode_apdu_init( ack_len = rp_ack_encode_apdu_init(
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
/* FIXME: add buffer len as passed into function or use smart buffer */ /* FIXME: add buffer len as passed into function or use smart buffer */
property_len = property_len = Encode_Property_APDU(
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], &data, &Handler_Transmit_Buffer[pdu_len + ack_len], &data, &error_class,
&error_class, &error_code); &error_code);
if (property_len >= 0) { if (property_len >= 0) {
len = rp_ack_encode_apdu_object_property_end( len = rp_ack_encode_apdu_object_property_end(
&Handler_Transmit_Buffer[pdu_len + property_len + ack_len]); &Handler_Transmit_Buffer[pdu_len + property_len + ack_len]);
@@ -115,14 +121,14 @@ void handler_read_property(uint8_t *service_request,
/* BACnet APDU too small to fit data, so proper response is /* BACnet APDU too small to fit data, so proper response is
* Abort */ * Abort */
case BACNET_STATUS_ABORT: case BACNET_STATUS_ABORT:
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
break; break;
default: default:
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = bacerror_encode_apdu(
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
error_class, error_code); SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
break; break;
} }
} }
+3 -3
View File
@@ -41,9 +41,9 @@ void sendIamUnicast(uint8_t *buffer, BACNET_ADDRESS *src)
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_encode_pdu(&buffer[0], &dest, &my_address, &npdu_data); npdu_len = npdu_encode_pdu(&buffer[0], &dest, &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
apdu_len = apdu_len = iam_encode_apdu(
iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(), &buffer[npdu_len], Device_Object_Instance_Number(), MAX_APDU,
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); SEGMENTATION_NONE, Device_Vendor_Identifier());
/* send data */ /* send data */
pdu_len = npdu_len + apdu_len; pdu_len = npdu_len + apdu_len;
int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
+32 -27
View File
@@ -27,7 +27,8 @@
/* too big to reside on stack frame for PIC */ /* too big to reside on stack frame for PIC */
static BACNET_WRITE_PROPERTY_DATA wp_data; static BACNET_WRITE_PROPERTY_DATA wp_data;
void handler_write_property(uint8_t *service_request, void handler_write_property(
uint8_t *service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
@@ -48,60 +49,64 @@ void handler_write_property(uint8_t *service_request,
&Handler_Transmit_Buffer[0], src, &my_address, &npdu_data); &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, ABORT_REASON_OTHER, true); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
ABORT_REASON_OTHER, true);
} else if (service_data->segmented_message) { } else if (service_data->segmented_message) {
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
} else { } else {
switch (wp_data.object_type) { switch (wp_data.object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Write_Property( if (Device_Write_Property(
&wp_data, &error_class, &error_code)) { &wp_data, &error_class, &error_code)) {
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], len = encode_simple_ack(
&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code); error_code);
} }
break; break;
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property( if (Analog_Value_Write_Property(
&wp_data, &error_class, &error_code)) { &wp_data, &error_class, &error_code)) {
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], len = encode_simple_ack(
&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code); error_code);
} }
break; break;
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property( if (Binary_Value_Write_Property(
&wp_data, &error_class, &error_code)) { &wp_data, &error_class, &error_code)) {
len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], len = encode_simple_ack(
&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code); error_code);
} }
break; break;
default: default:
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = bacerror_encode_apdu(
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
error_class, error_code); SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
break; break;
} }
} }
+12 -9
View File
@@ -32,8 +32,8 @@
extern bool Send_I_Am_Flag; extern bool Send_I_Am_Flag;
/* local version override */ /* local version override */
const char *BACnet_Version = "1.0"; const char *BACnet_Version = "1.0";
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE, 0xEF, static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE,
0xFE, 0xED }; 0xEF, 0xFE, 0xED };
uint8_t ipAddress[] = { 192, 168, 0, 185 }; uint8_t ipAddress[] = { 192, 168, 0, 185 };
uint8_t gateway[] = { 192, 168, 0, 1 }; uint8_t gateway[] = { 192, 168, 0, 1 };
uint8_t netmask[] = { 255, 255, 255, 0 }; uint8_t netmask[] = { 255, 255, 255, 0 };
@@ -70,14 +70,17 @@ void setup()
#endif #endif
} }
/** Static receive buffer, initialized with zeros by the C Library Startup Code. */ /** Static receive buffer, initialized with zeros by the C Library Startup Code.
*/
static uint8_t PDUBuffer[MAX_MPDU + 16 /* Add a little safety margin to the buffer, static uint8_t PDUBuffer
* so that in the rare case, the message [MAX_MPDU + 16 /* Add a little safety margin to the buffer,
* would be filled up to MAX_MPDU and some * so that in the rare case, the message
* decoding functions would overrun, these * would be filled up to MAX_MPDU and some
* decoding functions will just end up in * decoding functions would overrun, these
* a safe field of static zeros. */]; * decoding functions will just end up in
* a safe field of static zeros. */
];
/** Main */ /** Main */
+1 -1
View File
@@ -22,7 +22,7 @@
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#endif #endif
#endif #endif
+8 -8
View File
@@ -5,12 +5,12 @@
#include <stddef.h> #include <stddef.h>
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
typedef signed char int8_t; /* 1 byte -127 to 127 */ typedef signed char int8_t; /* 1 byte -127 to 127 */
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
#define INT8_MIN (-128) #define INT8_MIN (-128)
#define INT16_MIN (-32768) #define INT16_MIN (-32768)
@@ -20,8 +20,8 @@ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
#define INT16_MAX 32767 #define INT16_MAX 32767
#define INT32_MAX 2147483647 #define INT32_MAX 2147483647
#define UINT8_MAX 0xff /* 255U */ #define UINT8_MAX 0xff /* 255U */
#define UINT16_MAX 0xffff /* 65535U */ #define UINT16_MAX 0xffff /* 65535U */
#define UINT32_MAX 0xffffffff /* 4294967295U */ #define UINT32_MAX 0xffffffff /* 4294967295U */
#endif /* STDINT_H */ #endif /* STDINT_H */
+6 -6
View File
@@ -1,10 +1,10 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef TXBUF_H #ifndef TXBUF_H
#define TXBUF_H #define TXBUF_H
+2 -3
View File
@@ -17,9 +17,8 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void uart_init(void); void uart_init(void);
void uart_putchar(char c, void uart_putchar(char c, FILE *stream);
FILE * stream); char uart_getchar(FILE *stream);
char uart_getchar(FILE * stream);
#ifdef __cplusplus #ifdef __cplusplus
} }
+4 -2
View File
@@ -437,11 +437,13 @@ extern "C" {
* - The interface between the implemented Objects and the BAC-stack services, * - The interface between the implemented Objects and the BAC-stack services,
* specifically the handlers, which are mediated through function calls to * specifically the handlers, which are mediated through function calls to
* the Device object. * the Device object.
*//** @defgroup ObjHelpers Object Helper Functions */
/** @defgroup ObjHelpers Object Helper Functions
* @ingroup ObjFrmwk * @ingroup ObjFrmwk
* This section describes the function templates for the helper functions that * This section describes the function templates for the helper functions that
* provide common object support. * provide common object support.
*//** @defgroup ObjIntf Handler-to-Object Interface Functions */
/** @defgroup ObjIntf Handler-to-Object Interface Functions
* @ingroup ObjFrmwk * @ingroup ObjFrmwk
* This section describes the fairly limited set of functions that link the * This section describes the fairly limited set of functions that link the
* BAC-stack handlers to the BACnet Object instances. All of these calls are * BAC-stack handlers to the BACnet Object instances. All of these calls are
+54 -30
View File
@@ -62,8 +62,9 @@ bool arcnet_valid(void)
void arcnet_cleanup(void) void arcnet_cleanup(void)
{ {
if (arcnet_valid()) if (arcnet_valid()) {
close(ARCNET_Sock_FD); close(ARCNET_Sock_FD);
}
ARCNET_Sock_FD = -1; ARCNET_Sock_FD = -1;
return; return;
@@ -79,7 +80,8 @@ static int arcnet_bind(const char *interface_name)
/* check to see if we are being run as root */ /* check to see if we are being run as root */
uid = getuid(); uid = getuid();
if (uid != 0) { if (uid != 0) {
fprintf(stderr, fprintf(
stderr,
"arcnet: Unable to open an af_packet socket. " "arcnet: Unable to open an af_packet socket. "
"Try running with root priveleges.\n"); "Try running with root priveleges.\n");
return sock_fd; return sock_fd;
@@ -92,7 +94,8 @@ static int arcnet_bind(const char *interface_name)
if ((sock_fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) { if ((sock_fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
/* Error occured */ /* Error occured */
fprintf(stderr, "arcnet: Error opening socket: %s\n", strerror(errno)); fprintf(stderr, "arcnet: Error opening socket: %s\n", strerror(errno));
fprintf(stderr, fprintf(
stderr,
"You might need to add the following to modules.conf\n" "You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n" "(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n" "alias net-pf-17 af_packet\n"
@@ -108,19 +111,24 @@ static int arcnet_bind(const char *interface_name)
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET; ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
/*ARCNET_Socket_Address.sa_family = PF_INET; */ /*ARCNET_Socket_Address.sa_family = PF_INET; */
/* Clear the memory before copying */ /* Clear the memory before copying */
memset(ARCNET_Socket_Address.sa_data, '\0', memset(
ARCNET_Socket_Address.sa_data, '\0',
sizeof(ARCNET_Socket_Address.sa_data)); sizeof(ARCNET_Socket_Address.sa_data));
/* Strcpy the interface name into the address */ /* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name, strncpy(
ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data) - 1); sizeof(ARCNET_Socket_Address.sa_data) - 1);
fprintf( fprintf(
stderr, "arcnet: binding \"%s\"\n", ARCNET_Socket_Address.sa_data); stderr, "arcnet: binding \"%s\"\n", ARCNET_Socket_Address.sa_data);
if (bind(sock_fd, &ARCNET_Socket_Address, if (bind(
sock_fd, &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)) != 0) { sizeof(ARCNET_Socket_Address)) != 0) {
/* Bind problem, close socket and return */ /* Bind problem, close socket and return */
fprintf(stderr, "arcnet: Unable to bind socket : %s\n", fprintf(
stderr, "arcnet: Unable to bind socket : %s\n",
strerror(errno)); strerror(errno));
fprintf(stderr, fprintf(
stderr,
"You might need to add the following to modules.conf\n" "You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n" "(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n" "alias net-pf-17 af_packet\n"
@@ -134,18 +142,22 @@ static int arcnet_bind(const char *interface_name)
} }
strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name));
rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr); rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr);
if (rv != -1) /* worked okay */ if (rv != -1) { /* worked okay */
ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0]; ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0];
}
/* copy this info into the local copy since bind wiped it out */ /* copy this info into the local copy since bind wiped it out */
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET; ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
/*ARCNET_Socket_Address.sa_family = PF_INET; */ /*ARCNET_Socket_Address.sa_family = PF_INET; */
/* Clear the memory before copying */ /* Clear the memory before copying */
memset(ARCNET_Socket_Address.sa_data, '\0', memset(
ARCNET_Socket_Address.sa_data, '\0',
sizeof(ARCNET_Socket_Address.sa_data)); sizeof(ARCNET_Socket_Address.sa_data));
/* Strcpy the interface name into the address */ /* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name, strncpy(
ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data) - 1); sizeof(ARCNET_Socket_Address.sa_data) - 1);
fprintf(stderr, "arcnet: MAC=%02Xh iface=\"%s\"\n", ARCNET_MAC_Address, fprintf(
stderr, "arcnet: MAC=%02Xh iface=\"%s\"\n", ARCNET_MAC_Address,
ARCNET_Socket_Address.sa_data); ARCNET_Socket_Address.sa_data);
atexit(arcnet_cleanup); atexit(arcnet_cleanup);
@@ -155,17 +167,19 @@ static int arcnet_bind(const char *interface_name)
bool arcnet_init(char *interface_name) bool arcnet_init(char *interface_name)
{ {
if (interface_name) if (interface_name) {
ARCNET_Sock_FD = arcnet_bind(interface_name); ARCNET_Sock_FD = arcnet_bind(interface_name);
else } else {
ARCNET_Sock_FD = arcnet_bind("arc0"); ARCNET_Sock_FD = arcnet_bind("arc0");
}
return arcnet_valid(); return arcnet_valid();
} }
/* function to send a PDU out the socket */ /* function to send a PDU out the socket */
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */ int arcnet_send_pdu(
BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -186,15 +200,15 @@ int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
return -1; return -1;
} }
/* load destination MAC address */ /* load destination MAC address */
if (dest->mac_len == 1) if (dest->mac_len == 1) {
pkt->hard.dest = dest->mac[0]; pkt->hard.dest = dest->mac[0];
else { } else {
fprintf(stderr, "arcnet: invalid destination MAC address!\n"); fprintf(stderr, "arcnet: invalid destination MAC address!\n");
return -2; return -2;
} }
if (src.mac_len == 1) if (src.mac_len == 1) {
pkt->hard.source = src.mac[0]; pkt->hard.source = src.mac[0];
else { } else {
fprintf(stderr, "arcnet: invalid source MAC address!\n"); fprintf(stderr, "arcnet: invalid source MAC address!\n");
return -3; return -3;
} }
@@ -211,19 +225,22 @@ int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
} }
memcpy(&pkt->soft.raw[4], pdu, pdu_len); memcpy(&pkt->soft.raw[4], pdu, pdu_len);
/* Send the packet */ /* Send the packet */
bytes = sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0, bytes = sendto(
ARCNET_Sock_FD, &mtu, mtu_len, 0,
(struct sockaddr *)&ARCNET_Socket_Address, (struct sockaddr *)&ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)); sizeof(ARCNET_Socket_Address));
/* did it get sent? */ /* did it get sent? */
if (bytes < 0) if (bytes < 0) {
fprintf(stderr, "arcnet: Error sending packet: %s\n", strerror(errno)); fprintf(stderr, "arcnet: Error sending packet: %s\n", strerror(errno));
}
return bytes; return bytes;
} }
/* receives an framed packet */ /* receives an framed packet */
/* returns the number of octets in the PDU, or zero on failure */ /* returns the number of octets in the PDU, or zero on failure */
uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */ uint16_t arcnet_receive(
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -237,8 +254,9 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
struct archdr *pkt = (struct archdr *)buf; struct archdr *pkt = (struct archdr *)buf;
/* Make sure the socket is open */ /* Make sure the socket is open */
if (ARCNET_Sock_FD <= 0) if (ARCNET_Sock_FD <= 0) {
return 0; return 0;
}
/* we could just use a non-blocking socket, but that consumes all /* we could just use a non-blocking socket, but that consumes all
the CPU time. We can use a timeout; it is only supported as the CPU time. We can use a timeout; it is only supported as
@@ -255,24 +273,28 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
FD_SET(ARCNET_Sock_FD, &read_fds); FD_SET(ARCNET_Sock_FD, &read_fds);
max = ARCNET_Sock_FD; max = ARCNET_Sock_FD;
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
received_bytes = read(ARCNET_Sock_FD, &buf[0], sizeof(buf)); received_bytes = read(ARCNET_Sock_FD, &buf[0], sizeof(buf));
else } else {
return 0; return 0;
}
/* See if there is a problem */ /* See if there is a problem */
if (received_bytes < 0) { if (received_bytes < 0) {
/* EAGAIN Non-blocking I/O has been selected */ /* EAGAIN Non-blocking I/O has been selected */
/* using O_NONBLOCK and no data */ /* using O_NONBLOCK and no data */
/* was immediately available for reading. */ /* was immediately available for reading. */
if (errno != EAGAIN) if (errno != EAGAIN) {
fprintf(stderr, "ethernet: Read error in receiving packet: %s\n", fprintf(
stderr, "ethernet: Read error in receiving packet: %s\n",
strerror(errno)); strerror(errno));
}
return 0; return 0;
} }
if (received_bytes == 0) if (received_bytes == 0) {
return 0; return 0;
}
/* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) " /* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) "
"from %02Xh (proto==%02Xh)\n", "from %02Xh (proto==%02Xh)\n",
@@ -312,11 +334,13 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
pdu_len = received_bytes - ARC_HDR_SIZE; pdu_len = received_bytes - ARC_HDR_SIZE;
pdu_len -= 4 /* SC, DSAP, SSAP, LLC Control */; pdu_len -= 4 /* SC, DSAP, SSAP, LLC Control */;
/* copy the buffer into the PDU */ /* copy the buffer into the PDU */
if (pdu_len < max_pdu) if (pdu_len < max_pdu) {
memmove(&pdu[0], &pkt->soft.raw[4], pdu_len); memmove(&pdu[0], &pkt->soft.raw[4], pdu_len);
}
/* silently ignore packets that are too large */ /* silently ignore packets that are too large */
else else {
pdu_len = 0; pdu_len = 0;
}
return pdu_len; return pdu_len;
} }
+43 -47
View File
@@ -1,56 +1,56 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef BACPORT_H #ifndef BACPORT_H
#define BACPORT_H #define BACPORT_H
/* common unix sockets headers needed */ /* common unix sockets headers needed */
#include <sys/types.h> /* basic system data types */ #include <sys/types.h> /* basic system data types */
#include <sys/time.h> /* timeval{} for select() */ #include <sys/time.h> /* timeval{} for select() */
#include <time.h> /* timespec{} for pselect() */ #include <time.h> /* timespec{} for pselect() */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */ #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */ #include <arpa/inet.h> /* inet(3) functions */
#include <fcntl.h> /* for nonblocking */ #include <fcntl.h> /* for nonblocking */
#include <netdb.h> #include <netdb.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> /* for S_xxx file mode constants */ #include <sys/stat.h> /* for S_xxx file mode constants */
#include <sys/uio.h> /* for iovec{} and readv/writev */ #include <sys/uio.h> /* for iovec{} and readv/writev */
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/un.h> /* for Unix domain sockets */ #include <sys/un.h> /* for Unix domain sockets */
#ifdef HAVE_SYS_SELECT_H #ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> /* for convenience */ #include <sys/select.h> /* for convenience */
#endif #endif
#ifdef HAVE_POLL_H #ifdef HAVE_POLL_H
#include <poll.h> /* for convenience */ #include <poll.h> /* for convenience */
#endif #endif
#ifdef HAVE_STRINGS_H #ifdef HAVE_STRINGS_H
#include <strings.h> /* for convenience */ #include <strings.h> /* for convenience */
#endif #endif
/* Three headers are normally needed for socket/file ioctl's: /* Three headers are normally needed for socket/file ioctl's:
* <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>. * <sys/ioctl.h>, <sys/filio.h>, and <sys/sockio.h>.
*/ */
#ifdef HAVE_SYS_IOCTL_H #ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif #endif
#ifdef HAVE_SYS_FILIO_H #ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h> #include <sys/filio.h>
#endif #endif
#ifdef HAVE_SYS_SOCKIO_H #ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h> #include <sys/sockio.h>
#endif #endif
#include <pthread.h> #include <pthread.h>
@@ -65,10 +65,10 @@
#ifndef __CYGWIN__ #ifndef __CYGWIN__
#include <net/if_arp.h> #include <net/if_arp.h>
#endif #endif
#include <features.h> /* for the glibc version number */ #include <features.h> /* for the glibc version number */
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1 #if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h> #include <netpacket/packet.h>
#include <net/ethernet.h> /* the L2 protocols */ #include <net/ethernet.h> /* the L2 protocols */
#else #else
#include <asm/types.h> #include <asm/types.h>
#ifndef __CYGWIN__ #ifndef __CYGWIN__
@@ -84,24 +84,20 @@
#include <netdb.h> #include <netdb.h>
#include "bacnet/basic/sys/bacnet_stack_exports.h" #include "bacnet/basic/sys/bacnet_stack_exports.h"
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \ #define BACNET_OBJECT_TABLE( \
_index_to_instance, _valid_instance, _object_name, \ table_name, _type, _init, _count, _index_to_instance, _valid_instance, \
_read_property, _write_property, _RPM_list, \ _object_name, _read_property, _write_property, _RPM_list, _RR_info, \
_RR_info, _iterator, _value_list, _COV, \ _iterator, _value_list, _COV, _COV_clear, _intrinsic_reporting) \
_COV_clear, _intrinsic_reporting) \
static_assert(false, "Unsupported BACNET_OBJECT_TABLE for this platform") static_assert(false, "Unsupported BACNET_OBJECT_TABLE for this platform")
/** @file linux/bacport.h Includes Linux network headers. */ /** @file linux/bacport.h Includes Linux network headers. */
/* Local helper functions for this port */ /* Local helper functions for this port */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
extern int bip_get_local_netmask( extern int bip_get_local_netmask(struct in_addr *netmask);
struct in_addr *netmask);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
extern int bip_get_local_address_ioctl( extern int bip_get_local_address_ioctl(
const char *ifname, const char *ifname, struct in_addr *addr, int request);
struct in_addr *addr,
int request);
#endif #endif
+40 -26
View File
@@ -60,13 +60,15 @@ static char BIP_Interface_Name[IF_NAMESIZE] = { 0 };
* @param str - debug info string * @param str - debug info string
* @param addr - IPv4 address * @param addr - IPv4 address
*/ */
static void debug_print_ipv4(const char *str, static void debug_print_ipv4(
const char *str,
const struct in_addr *addr, const struct in_addr *addr,
const unsigned int port, const unsigned int port,
const unsigned int count) const unsigned int count)
{ {
if (BIP_Debug) { if (BIP_Debug) {
fprintf(stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr), fprintf(
stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
ntohs(port), count); ntohs(port), count);
fflush(stderr); fflush(stderr);
} }
@@ -293,8 +295,9 @@ int bip_send_mpdu(
/* Send the packet */ /* Send the packet */
debug_print_ipv4( debug_print_ipv4(
"Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len); "Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
return sendto(BIP_Socket, (const char *)mtu, mtu_len, 0, return sendto(
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); BIP_Socket, (const char *)mtu, mtu_len, 0, (struct sockaddr *)&bip_dest,
sizeof(struct sockaddr));
} }
/** /**
@@ -345,10 +348,11 @@ uint16_t bip_receive(
/* see if there is a packet for us */ /* see if there is a packet for us */
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
socket = FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket : socket =
BIP_Broadcast_Socket; FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket : BIP_Broadcast_Socket;
received_bytes = recvfrom(socket, (char *)&npdu[0], max_npdu, 0, received_bytes = recvfrom(
(struct sockaddr *)&sin, &sin_len); socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
&sin_len);
} else { } else {
return 0; return 0;
} }
@@ -423,7 +427,8 @@ uint16_t bip_receive(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
int bip_send_pdu(BACNET_ADDRESS *dest, int bip_send_pdu(
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu, uint8_t *pdu,
unsigned pdu_len) unsigned pdu_len)
@@ -466,8 +471,8 @@ bool bip_get_addr_by_name(const char *host_name, BACNET_IP_ADDRESS *addr)
* @param request - the ioctl() request * @param request - the ioctl() request
* @return 0 on success, else the error from the ioctl() call. * @return 0 on success, else the error from the ioctl() call.
*/ */
static int get_local_ifr_ioctl( static int
const char *ifname, struct ifreq *ifr, int request) get_local_ifr_ioctl(const char *ifname, struct ifreq *ifr, int request)
{ {
int fd; int fd;
int rv; /* return value */ int rv; /* return value */
@@ -526,8 +531,8 @@ struct route_info {
* @param pId - process identifier of our specific request response * @param pId - process identifier of our specific request response
* @return number of bytes placed into the buffer * @return number of bytes placed into the buffer
*/ */
static int readNlSock( static int
int sockFd, char *bufPtr, size_t buf_size, int seqNum, int pId) readNlSock(int sockFd, char *bufPtr, size_t buf_size, int seqNum, int pId)
{ {
struct nlmsghdr *nlHdr; struct nlmsghdr *nlHdr;
int readLen = 0, msgLen = 0; int readLen = 0, msgLen = 0;
@@ -574,7 +579,8 @@ static char *ntoa(uint32_t addr)
{ {
static char buffer[18]; static char buffer[18];
snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d", (addr & 0x000000FF), snprintf(
buffer, sizeof(buffer), "%d.%d.%d.%d", (addr & 0x000000FF),
(addr & 0x0000FF00) >> 8, (addr & 0x00FF0000) >> 16, (addr & 0x0000FF00) >> 8, (addr & 0x00FF0000) >> 16,
(addr & 0xFF000000) >> 24); (addr & 0xFF000000) >> 24);
@@ -589,18 +595,21 @@ static void printRoute(struct route_info *rtInfo)
{ {
if (BIP_Debug) { if (BIP_Debug) {
/* Print Destination address */ /* Print Destination address */
fprintf(stderr, "%s\t", fprintf(
stderr, "%s\t",
rtInfo->dstAddr ? ntoa(rtInfo->dstAddr) : "0.0.0.0 "); rtInfo->dstAddr ? ntoa(rtInfo->dstAddr) : "0.0.0.0 ");
/* Print Gateway address */ /* Print Gateway address */
fprintf(stderr, "%s\t", fprintf(
stderr, "%s\t",
rtInfo->gateWay ? ntoa(rtInfo->gateWay) : "*.*.*.*"); rtInfo->gateWay ? ntoa(rtInfo->gateWay) : "*.*.*.*");
/* Print Interface Name */ /* Print Interface Name */
fprintf(stderr, "%s\t", rtInfo->ifName); fprintf(stderr, "%s\t", rtInfo->ifName);
/* Print Source address */ /* Print Source address */
fprintf(stderr, "%s\n", fprintf(
stderr, "%s\n",
rtInfo->srcAddr ? ntoa(rtInfo->srcAddr) : "*.*.*.*"); rtInfo->srcAddr ? ntoa(rtInfo->srcAddr) : "*.*.*.*");
} }
} }
@@ -620,8 +629,9 @@ static void parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
/* If the route is not for AF_INET or does not belong to main routing table /* If the route is not for AF_INET or does not belong to main routing table
then return. */ then return. */
if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN)) if ((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN)) {
return; return;
}
/* get the rtattr field */ /* get the rtattr field */
rtAttr = (struct rtattr *)RTM_RTA(rtMsg); rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
@@ -700,7 +710,8 @@ static char *ifname_default(void)
if (BIP_Interface_Name[0] == 0) { if (BIP_Interface_Name[0] == 0) {
if ((rtInfo->dstAddr == 0) && (rtInfo->ifName[0] != 0)) { if ((rtInfo->dstAddr == 0) && (rtInfo->ifName[0] != 0)) {
/* default route */ /* default route */
memcpy(BIP_Interface_Name, rtInfo->ifName, memcpy(
BIP_Interface_Name, rtInfo->ifName,
sizeof(BIP_Interface_Name)); sizeof(BIP_Interface_Name));
} }
} }
@@ -734,8 +745,7 @@ int bip_get_local_netmask(struct in_addr *netmask)
* @param baddr The broadcast socket binding address, in host order. * @param baddr The broadcast socket binding address, in host order.
* @return 0 on success * @return 0 on success
*/ */
int bip_set_broadcast_binding( int bip_set_broadcast_binding(const char *ip4_broadcast)
const char *ip4_broadcast)
{ {
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast); BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
BIP_Broadcast_Binding_Address_Override = true; BIP_Broadcast_Binding_Address_Override = true;
@@ -799,9 +809,11 @@ void bip_set_interface(const char *ifname)
} }
#endif #endif
if (BIP_Debug) { if (BIP_Debug) {
fprintf(stderr, "BIP: Broadcast Address: %s\n", fprintf(
stderr, "BIP: Broadcast Address: %s\n",
inet_ntoa(BIP_Broadcast_Addr)); inet_ntoa(BIP_Broadcast_Addr));
fprintf(stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port), fprintf(
stderr, "BIP: UDP Port: 0x%04X [%hu]\n", ntohs(BIP_Port),
ntohs(BIP_Port)); ntohs(BIP_Port));
fflush(stderr); fflush(stderr);
} }
@@ -835,8 +847,9 @@ static int createSocket(const struct sockaddr_in *sin)
return status; return status;
} }
/* Bind to the proper interface to send without default gateway */ /* Bind to the proper interface to send without default gateway */
status = setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, status = setsockopt(
BIP_Interface_Name, strlen(BIP_Interface_Name)); sock_fd, SOL_SOCKET, SO_BINDTODEVICE, BIP_Interface_Name,
strlen(BIP_Interface_Name));
if (status < 0) { if (status < 0) {
if (BIP_Debug) { if (BIP_Debug) {
perror("SO_BINDTODEVICE: "); perror("SO_BINDTODEVICE: ");
@@ -882,7 +895,8 @@ bool bip_init(char *ifname)
bip_set_interface(ifname_default()); bip_set_interface(ifname_default());
} }
if (BIP_Address.s_addr == 0) { if (BIP_Address.s_addr == 0) {
fprintf(stderr, "BIP: Failed to get an IP address from %s!\n", fprintf(
stderr, "BIP: Failed to get an IP address from %s!\n",
BIP_Interface_Name); BIP_Interface_Name);
fflush(stderr); fflush(stderr);
return false; return false;
+36 -24
View File
@@ -55,16 +55,16 @@ static void debug_fprintf_bip6(FILE *stream, const char *format, ...)
*/ */
static void debug_print_ipv6(const char *str, const struct in6_addr *addr) static void debug_print_ipv6(const char *str, const struct in6_addr *addr)
{ {
debug_fprintf_bip6(stdout, "BIP6: %s " debug_fprintf_bip6(
stdout,
"BIP6: %s "
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:" "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
"%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", "%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
str, (int)addr->s6_addr[0], (int)addr->s6_addr[1], str, (int)addr->s6_addr[0], (int)addr->s6_addr[1],
(int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[4],
(int)addr->s6_addr[4], (int)addr->s6_addr[5], (int)addr->s6_addr[5], (int)addr->s6_addr[6], (int)addr->s6_addr[7],
(int)addr->s6_addr[6], (int)addr->s6_addr[7], (int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[10],
(int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[11], (int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]); (int)addr->s6_addr[14], (int)addr->s6_addr[15]);
} }
@@ -106,12 +106,13 @@ void bip6_set_interface(char *ifname)
while (ifa_tmp) { while (ifa_tmp) {
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) { if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
debug_fprintf_bip6( debug_fprintf_bip6(
stdout, "BIP6: found interface: %s\n",ifa_tmp->ifa_name); stdout, "BIP6: found interface: %s\n", ifa_tmp->ifa_name);
} }
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) && if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
(strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) { (strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) {
sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr; sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr;
bvlc6_address_set(&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]), bvlc6_address_set(
&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]),
ntohs(sin->sin6_addr.s6_addr16[1]), ntohs(sin->sin6_addr.s6_addr16[1]),
ntohs(sin->sin6_addr.s6_addr16[2]), ntohs(sin->sin6_addr.s6_addr16[2]),
ntohs(sin->sin6_addr.s6_addr16[3]), ntohs(sin->sin6_addr.s6_addr16[3]),
@@ -127,7 +128,8 @@ void bip6_set_interface(char *ifname)
ifa_tmp = ifa_tmp->ifa_next; ifa_tmp = ifa_tmp->ifa_next;
} }
if (!found) { if (!found) {
debug_fprintf_bip6(stderr, "BIP6: unable to set interface: %s\n", ifname); debug_fprintf_bip6(
stderr, "BIP6: unable to set interface: %s\n", ifname);
exit(1); exit(1);
} }
} }
@@ -246,8 +248,9 @@ int bip6_send_mpdu(
} }
/* load destination IP address */ /* load destination IP address */
bvlc_dest.sin6_family = AF_INET6; bvlc_dest.sin6_family = AF_INET6;
bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], bvlc6_address_get(
&addr16[4], &addr16[5], &addr16[6], &addr16[7]); dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], &addr16[4],
&addr16[5], &addr16[6], &addr16[7]);
bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]); bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]);
bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]); bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]);
bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]); bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]);
@@ -260,7 +263,8 @@ int bip6_send_mpdu(
bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id; bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id;
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr); debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
/* Send the packet */ /* Send the packet */
return sendto(BIP6_Socket, (const char *)mtu, mtu_len, 0, return sendto(
BIP6_Socket, (const char *)mtu, mtu_len, 0,
(struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest)); (struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest));
} }
@@ -276,7 +280,8 @@ int bip6_send_mpdu(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
int bip6_send_pdu(BACNET_ADDRESS *dest, int bip6_send_pdu(
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu, uint8_t *pdu,
unsigned pdu_len) unsigned pdu_len)
@@ -328,8 +333,9 @@ uint16_t bip6_receive(
max = BIP6_Socket; max = BIP6_Socket;
/* see if there is a packet for us */ /* see if there is a packet for us */
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0, received_bytes = recvfrom(
(struct sockaddr *)&sin, &sin_len); BIP6_Socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
&sin_len);
} else { } else {
return 0; return 0;
} }
@@ -347,7 +353,8 @@ uint16_t bip6_receive(
} }
/* pass the packet into the BBMD handler */ /* pass the packet into the BBMD handler */
debug_print_ipv6("Received MPDU->", &sin.sin6_addr); debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
bvlc6_address_set(&addr, ntohs(sin.sin6_addr.s6_addr16[0]), bvlc6_address_set(
&addr, ntohs(sin.sin6_addr.s6_addr16[0]),
ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[2]), ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[2]),
ntohs(sin.sin6_addr.s6_addr16[3]), ntohs(sin.sin6_addr.s6_addr16[4]), ntohs(sin.sin6_addr.s6_addr16[3]), ntohs(sin.sin6_addr.s6_addr16[4]),
ntohs(sin.sin6_addr.s6_addr16[5]), ntohs(sin.sin6_addr.s6_addr16[6]), ntohs(sin.sin6_addr.s6_addr16[5]), ntohs(sin.sin6_addr.s6_addr16[6]),
@@ -418,13 +425,15 @@ bool bip6_init(char *ifname)
} }
debug_fprintf_bip6(stdout, "BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port); debug_fprintf_bip6(stdout, "BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port);
if (BIP6_Broadcast_Addr.address[0] == 0) { if (BIP6_Broadcast_Addr.address[0] == 0) {
bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, bvlc6_address_set(
0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID); &BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
} }
/* assumes that the driver has already been initialized */ /* assumes that the driver has already been initialized */
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (BIP6_Socket < 0) if (BIP6_Socket < 0) {
return false; return false;
}
/* Allow us to use the same socket for sending and receiving */ /* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */ /* This makes sure that the src port is correct when sending */
sockopt = 1; sockopt = 1;
@@ -444,14 +453,17 @@ bool bip6_init(char *ifname)
return false; return false;
} }
/* subscribe to a multicast address */ /* subscribe to a multicast address */
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], memcpy(
&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0],
IP6_ADDRESS_MAX); IP6_ADDRESS_MAX);
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address, memcpy(
&join_request.ipv6mr_multiaddr, &broadcast_address,
sizeof(struct in6_addr)); sizeof(struct in6_addr));
/* Let system not choose the interface */ /* Let system not choose the interface */
join_request.ipv6mr_interface = BIP6_Socket_Scope_Id; join_request.ipv6mr_interface = BIP6_Socket_Scope_Id;
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, status = setsockopt(
&join_request, sizeof(join_request)); BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &join_request,
sizeof(join_request));
if (status < 0) { if (status < 0) {
perror("BIP: setsockopt(IPV6_JOIN_GROUP)"); perror("BIP: setsockopt(IPV6_JOIN_GROUP)");
} }
+1 -1
View File
@@ -23,7 +23,7 @@ static int32_t Time_Offset; /* Time offset in ms */
/** /**
* @brief Calculate the time offset from the system clock. * @brief Calculate the time offset from the system clock.
* @return Time offset in ms * @return Time offset in ms
*/ */
static int32_t time_difference(struct timeval t0, struct timeval t1) static int32_t time_difference(struct timeval t0, struct timeval t1)
{ {
return (t0.tv_sec - t1.tv_sec) * 1000 + (t0.tv_usec - t1.tv_usec) / 1000; return (t0.tv_sec - t1.tv_sec) * 1000 + (t0.tv_usec - t1.tv_usec) / 1000;
+10 -5
View File
@@ -267,16 +267,19 @@ static void *dlmstp_master_fsm_task(void *pArg)
silence = MSTP_Port.SilenceTimer(&MSTP_Port); silence = MSTP_Port.SilenceTimer(&MSTP_Port);
switch (MSTP_Port.master_state) { switch (MSTP_Port.master_state) {
case MSTP_MASTER_STATE_IDLE: case MSTP_MASTER_STATE_IDLE:
if (silence >= Tno_token) if (silence >= Tno_token) {
run_master = true; run_master = true;
}
break; break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
if (silence >= Treply_timeout) if (silence >= Treply_timeout) {
run_master = true; run_master = true;
}
break; break;
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (silence >= Tusage_timeout) if (silence >= Tusage_timeout) {
run_master = true; run_master = true;
}
break; break;
default: default:
run_master = true; run_master = true;
@@ -290,8 +293,9 @@ static void *dlmstp_master_fsm_task(void *pArg)
/* do nothing while immediate transitioning */ /* do nothing while immediate transitioning */
run_loop = MSTP_Master_Node_FSM(&MSTP_Port); run_loop = MSTP_Master_Node_FSM(&MSTP_Port);
pthread_mutex_lock(&Thread_Mutex); pthread_mutex_lock(&Thread_Mutex);
if (!run_thread) if (!run_thread) {
run_loop = false; run_loop = false;
}
pthread_mutex_unlock(&Thread_Mutex); pthread_mutex_unlock(&Thread_Mutex);
} }
} else if (MSTP_Port.This_Station < 255) { } else if (MSTP_Port.This_Station < 255) {
@@ -578,8 +582,9 @@ void dlmstp_set_mac_address(uint8_t mac_address)
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
MSTP_Port.This_Station = mac_address; MSTP_Port.This_Station = mac_address;
if (mac_address > MSTP_Port.Nmax_master) if (mac_address > MSTP_Port.Nmax_master) {
dlmstp_set_max_master(mac_address); dlmstp_set_max_master(mac_address);
}
} }
return; return;
+10 -5
View File
@@ -258,16 +258,19 @@ static void *dlmstp_master_fsm_task(void *pArg)
silence = mstp_port->SilenceTimer(NULL); silence = mstp_port->SilenceTimer(NULL);
switch (mstp_port->master_state) { switch (mstp_port->master_state) {
case MSTP_MASTER_STATE_IDLE: case MSTP_MASTER_STATE_IDLE:
if (silence >= Tno_token) if (silence >= Tno_token) {
run_master = true; run_master = true;
}
break; break;
case MSTP_MASTER_STATE_WAIT_FOR_REPLY: case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
if (silence >= mstp_port->Treply_timeout) if (silence >= mstp_port->Treply_timeout) {
run_master = true; run_master = true;
}
break; break;
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (silence >= mstp_port->Tusage_timeout) if (silence >= mstp_port->Tusage_timeout) {
run_master = true; run_master = true;
}
break; break;
default: default:
run_master = true; run_master = true;
@@ -324,8 +327,9 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
if (!poSharedData->Receive_Packet.ready) { if (!poSharedData->Receive_Packet.ready) {
/* bounds check - maybe this should send an abort? */ /* bounds check - maybe this should send an abort? */
pdu_len = mstp_port->DataLength; pdu_len = mstp_port->DataLength;
if (pdu_len > sizeof(poSharedData->Receive_Packet.pdu)) if (pdu_len > sizeof(poSharedData->Receive_Packet.pdu)) {
pdu_len = sizeof(poSharedData->Receive_Packet.pdu); pdu_len = sizeof(poSharedData->Receive_Packet.pdu);
}
memmove( memmove(
(void *)&poSharedData->Receive_Packet.pdu[0], (void *)&poSharedData->Receive_Packet.pdu[0],
(void *)&mstp_port->InputBuffer[0], pdu_len); (void *)&mstp_port->InputBuffer[0], pdu_len);
@@ -580,8 +584,9 @@ void dlmstp_set_mac_address(void *poPort, uint8_t mac_address)
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
mstp_port->This_Station = mac_address; mstp_port->This_Station = mac_address;
if (mac_address > mstp_port->Nmax_master) if (mac_address > mstp_port->Nmax_master) {
dlmstp_set_max_master(mstp_port, mac_address); dlmstp_set_max_master(mstp_port, mac_address);
}
} }
return; return;

Some files were not shown because too many files have changed in this diff Show More