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
+8 -5
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;
@@ -90,7 +90,8 @@ 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("--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");
@@ -109,7 +110,8 @@ static void print_help(const char *filename)
"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;
+18 -11
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,7 +146,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-id process-id\n" printf(
"Usage: %s device-id process-id\n"
" event-object-type event-object-instance event-state-acked\n" " event-object-type event-object-instance event-state-acked\n"
" event-time-stamp ack-source-name ack-time-stamp\n", " event-time-stamp ack-source-name ack-time-stamp\n",
filename); filename);
@@ -154,7 +158,8 @@ 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"
@@ -164,7 +169,8 @@ static void print_help(const char *filename)
"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");
@@ -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 */
+32 -20
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,7 +142,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 " printf(
"Usage: %s device-instance object-type object-instance "
"property array-index tag value\n", "property array-index tag value\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
@@ -211,7 +215,8 @@ 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(
"Example:\n"
"If you want to AddListElement to the Recipient-List property in\n" "If you want to AddListElement to the Recipient-List property in\n"
"Notification Class 1 of Device 123, send the following command:\n" "Notification Class 1 of Device 123, send the following command:\n"
"%s 123 15 1 102 -1 4 100\n", "%s 123 15 1 102 -1 4 100\n",
@@ -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(
+24 -14
View File
@@ -57,12 +57,14 @@ 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(
" \"%s\": {\n"
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"", " \"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));
@@ -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,16 +182,20 @@ 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(
"Send an APDU to DNET 123:\n"
"%s 1 --dnet 123 0123456789ABCDEF\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(
"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", "%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(
"Send APDU to MAC 10.1.2.3:47808:\n"
"%s 1 --mac 10.1.2.3:47808 0123456789ABCDEF\n", "%s 1 --mac 10.1.2.3:47808 0123456789ABCDEF\n",
filename); filename);
printf("Send an APDU to Device 1:\n" printf(
"Send an APDU to Device 1:\n"
"%s 1 0123456789ABCDEF\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;
} }
+224 -95
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,
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 */ }, 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 */,
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 }, 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)
{ {
@@ -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 */
+21 -12
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,7 +321,8 @@ 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(
"Example:\n"
"%s 9009\n", "%s 9009\n",
filename); filename);
} }
@@ -375,12 +382,14 @@ 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 Raspberry Pi Blinkt! Demo\n"
"BACnet Stack Version %s\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "BACnet Device ID: %u\n"
"Max APDU: %d\n", "Max APDU: %d\n",
+43 -32
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,7 +213,8 @@ 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(
"Example:\n"
"If you want to CreateObject of an Analog Input 1\n" "If you want to CreateObject of an Analog Input 1\n"
"send the following command:\n" "send the following command:\n"
"%s 123 0 1\n", "%s 123 0 1\n",
@@ -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;
@@ -374,7 +384,8 @@ int main(int argc, char *argv[])
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;
} }
+28 -25
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,7 +167,8 @@ 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(
"Example:\n"
"If you want to DeleteObject an Analog Input 1\n" "If you want to DeleteObject an Analog Input 1\n"
"send the following command:\n" "send the following command:\n"
"%s 123 0 1\n", "%s 123 0 1\n",
@@ -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 */
@@ -335,7 +337,8 @@ int main(int argc, char *argv[])
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;
} }
+9 -5
View File
@@ -70,16 +70,20 @@ 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,
GET_HEADING_RESPONSE,
PRINT_HEADING,
/** Getting ALL properties and values at once with RPM. */ /** Getting ALL properties and values at once with RPM. */
GET_ALL_REQUEST, GET_ALL_RESPONSE, GET_ALL_REQUEST,
GET_ALL_RESPONSE,
/** Getting ALL properties with array index = 0, just to get the list. */ /** Getting ALL properties with array index = 0, just to get the list. */
GET_LIST_OF_ALL_REQUEST, GET_LIST_OF_ALL_RESPONSE, GET_LIST_OF_ALL_REQUEST,
GET_LIST_OF_ALL_RESPONSE,
/** Processing the properties individually with ReadProperty. */ /** Processing the properties individually with ReadProperty. */
GET_PROPERTY_REQUEST, GET_PROPERTY_RESPONSE, GET_PROPERTY_REQUEST,
GET_PROPERTY_RESPONSE,
/** Done with this Object; move onto the next. */ /** Done with this Object; move onto the next. */
NEXT_OBJECT NEXT_OBJECT
} EPICS_STATES; } EPICS_STATES;
#endif /* BACEPICS_H_ */ #endif /* BACEPICS_H_ */
+82 -51
View File
@@ -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;
@@ -376,7 +386,8 @@ static bool PrettyPrintPropertyValue(
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,7 +906,8 @@ 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(
"Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
" device-instance\n", " device-instance\n",
filename); filename);
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
@@ -984,8 +1005,8 @@ 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;
@@ -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");
@@ -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,
@@ -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);
@@ -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;
} }
+11 -7
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");
@@ -92,7 +93,8 @@ 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("--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");
@@ -103,7 +105,8 @@ 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("error-class:\n" printf(
"error-class:\n"
" number from 0 to 65535\n" " number from 0 to 65535\n"
"error-code:\n" "error-code:\n"
" number from 0 to 65535\n" " number from 0 to 65535\n"
@@ -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;
} }
+32 -24
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,7 +146,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-id process-id initiating-device-id\n" printf(
"Usage: %s device-id process-id initiating-device-id\n"
" event-object-type event-object-instance\n" " event-object-type event-object-instance\n"
" sequence-number notification-class priority message-text\n" " sequence-number notification-class priority message-text\n"
" notify-type ack-required from-state to-state event-type\n" " notify-type ack-required from-state to-state event-type\n"
@@ -157,7 +161,8 @@ 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"
@@ -170,7 +175,8 @@ static void print_help(const char *filename)
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");
@@ -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;
} }
+65 -41
View File
@@ -39,78 +39,103 @@
// 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();
@@ -121,5 +146,4 @@ int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
} }
return 0; return 0;
} }
+5 -4
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,12 +226,12 @@ 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 Router Demo\n"
"BACnet Stack Version %s\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "BACnet Device ID: %u\n"
"Max APDU: %d\n" "Max APDU: %d\n"
+19 -11
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,7 +169,8 @@ 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(
"Usage:\n"
"\n" "\n"
"%s device-instance [--help]\n" "%s device-instance [--help]\n"
"\n" "\n"
+11 -7
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");
@@ -101,7 +102,8 @@ static void print_help(const char *filename)
"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 "
"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");
@@ -130,7 +132,8 @@ static void print_help(const char *filename)
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);
+6 -4
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,7 +83,8 @@ 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(
"Send BACnet I-Am-Router-To-Network message for \n"
"one or more networks.\n" "one or more networks.\n"
"\nDNET:\n" "\nDNET:\n"
"BACnet destination network number 0-65534\n" "BACnet destination network number 0-65534\n"
@@ -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;
} }
+19 -13
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) {
+67 -56
View File
@@ -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;
@@ -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,7 +936,8 @@ 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(
"%s --scan <filename>\n"
"perform statistic analysis on MS/TP capture file.\n", "perform statistic analysis on MS/TP capture file.\n",
filename); filename);
printf("\n"); printf("\n");
@@ -957,7 +964,8 @@ 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(
"%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n"
"[--capture][--baud baud][--fifo pipe]\n" "[--capture][--baud baud][--fifo pipe]\n"
"[--extcap-interface iface]\n" "[--extcap-interface iface]\n"
"Usage from Wireshark ExtCap interface\n", "Usage from Wireshark ExtCap interface\n",
@@ -1053,7 +1061,8 @@ 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(
"dlt {number=%u}{name=BACnet MS/TP}"
"{display=BACnet MS/TP}\n", "{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));
} }
} }
+26 -15
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,7 +264,8 @@ 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(
"Send BACnet What-Is-Network-Number message to a network.\r\n"
"\r\n" "\r\n"
"DNET:\r\n" "DNET:\r\n"
"BACnet destination network number 0-65535\r\n" "BACnet destination network number 0-65535\r\n"
@@ -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)
+180 -81
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,
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 */ }, 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_Input_Encode_Value_List,
Binary_Input_Change_Of_Value,
Binary_Input_Change_Of_Value_Clear,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
NULL /* Create */,
NULL /* Delete */,
NULL /* Timer */ },
{ OBJECT_BINARY_LIGHTING_OUTPUT,
Binary_Lighting_Output_Init,
Binary_Lighting_Output_Count,
Binary_Lighting_Output_Index_To_Instance,
Binary_Lighting_Output_Valid_Instance, Binary_Lighting_Output_Valid_Instance,
Binary_Lighting_Output_Object_Name, Binary_Lighting_Output_Object_Name,
Binary_Lighting_Output_Read_Property, Binary_Lighting_Output_Read_Property,
Binary_Lighting_Output_Write_Property, Binary_Lighting_Output_Write_Property,
Binary_Lighting_Output_Property_Lists, NULL /* ReadRangeInfo */, Binary_Lighting_Output_Property_Lists,
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */, NULL /* ReadRangeInfo */,
NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* Iterator */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* Value_Lists */,
Binary_Lighting_Output_Create, Binary_Lighting_Output_Delete, NULL /* COV */,
NULL /* COV Clear */,
NULL /* Intrinsic Reporting */,
NULL /* Add_List_Element */,
NULL /* Remove_List_Element */,
Binary_Lighting_Output_Create,
Binary_Lighting_Output_Delete,
Binary_Lighting_Output_Timer }, Binary_Lighting_Output_Timer },
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, { OBJECT_BINARY_OUTPUT,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, Binary_Output_Init,
Binary_Output_Object_Name, Binary_Output_Read_Property, Binary_Output_Count,
Binary_Output_Write_Property, Binary_Output_Property_Lists, Binary_Output_Index_To_Instance,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, Binary_Output_Valid_Instance,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, Binary_Output_Object_Name,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, Binary_Output_Read_Property,
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */ }, Binary_Output_Write_Property,
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */, Binary_Output_Property_Lists,
NULL /* Index_To_Instance */, NULL /* Valid_Instance */, NULL /* ReadRangeInfo */,
NULL /* Object_Name */, NULL /* Read_Property */, NULL /* Iterator */,
NULL /* Write_Property */, NULL /* Property_Lists */, NULL /* Value_Lists */,
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */, NULL /* COV Clear */,
NULL /* Add_List_Element */, NULL /* Remove_List_Element */, NULL /* Intrinsic Reporting */,
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ } 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)
{ {
@@ -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 */
+14 -10
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,7 +305,8 @@ 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 Raspberry Pi PiFace Digital Demo\n"
"BACnet Stack Version %s\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "BACnet Device ID: %u\n"
"Max APDU: %d\n", "Max APDU: %d\n",
+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;
+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
+16 -10
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,7 +187,8 @@ 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(
"Usage: %s server local-device-instance\r\n or\r\n"
" %s remote-device-instance\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)) {
@@ -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,7 +354,8 @@ 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(
"Requesting block %d with invalid "
"Vendor ID\n", "Vendor ID\n",
iCount); iCount);
invoke_id = Send_Private_Transfer_Request( invoke_id = Send_Private_Transfer_Request(
+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
+5 -2
View File
@@ -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 device_id,
uint16_t vendor_id,
uint32_t service_number, uint32_t service_number,
char block_number, DATABLOCK *block); 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;
+4 -3
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,7 +98,8 @@ 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(
"Send a Read-Foreign-Device-Table message to a BBMD.\r\n"
"\r\n" "\r\n"
"IP:\r\n" "IP:\r\n"
"IP address of the BBMD in dotted decimal notation\r\n" "IP address of the BBMD in dotted decimal notation\r\n"
+30 -19
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,16 +220,17 @@ 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");
@@ -230,7 +238,8 @@ static void print_help(const char *filename)
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,9 +367,9 @@ 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)) {
+24 -24
View File
@@ -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,7 +153,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 " printf(
"Usage: %s device-instance object-type object-instance "
"property [index]\n", "property [index]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\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,8 +211,7 @@ 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"
@@ -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;
} }
@@ -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)) {
+48 -29
View File
@@ -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,7 +240,8 @@ 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(
"Usage: %s device-instance object-type object-instance "
"property[index][,property[index]] [object-type ...]\n", "property[index][,property[index]] [object-type ...]\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\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(
"Example:\n"
"If you want read the PRESENT_VALUE property and various\n" "If you want read the PRESENT_VALUE property and various\n"
"array elements of the PRIORITY_ARRAY in Device 123\n" "array elements of the PRIORITY_ARRAY in Device 123\n"
"Analog Output object 99, use one of the following commands:\n" "Analog Output object 99, use one of the following commands:\n"
"%s 123 analog-output 99 85,87[0],87\n" "%s 123 analog-output 99 85,87[0],87\n"
"%s 123 1 99 85,87[0],87\n", filename, filename); "%s 123 1 99 85,87[0],87\n",
printf("If you want read the PRESENT_VALUE property in objects\n" filename, filename);
printf(
"If you want read the PRESENT_VALUE property in objects\n"
"Analog Input 77 and Analog Input 78 in Device 123\n" "Analog Input 77 and Analog Input 78 in Device 123\n"
"use one of the following commands:\n" "use one of the following commands:\n"
"%s 123 analog-input 77 85 analog-input 78 85\n" "%s 123 analog-input 77 85 analog-input 78 85\n"
"%s 123 0 77 85 0 78 85\n", filename, filename); "%s 123 0 77 85 0 78 85\n",
printf("If you want read the ALL property in\n" filename, filename);
printf(
"If you want read the ALL property in\n"
"Device object 123, you would use one of the following commands:\n" "Device object 123, you would use one of the following commands:\n"
"%s 123 device 123 8\n" "%s 123 device 123 8\n"
"%s 123 8 123 8\n", filename, filename); "%s 123 8 123 8\n",
printf("If you want read the OPTIONAL property in\n" filename, filename);
printf(
"If you want read the OPTIONAL property in\n"
"Device object 123, you would use one of the following commands:\n" "Device object 123, you would use one of the following commands:\n"
"%s 123 device 123 80\n" "%s 123 device 123 80\n"
"%s 123 8 123 80\n", filename, filename); "%s 123 8 123 80\n",
printf("If you want read the REQUIRED property in\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" "Device object 123, you would one of use the following commands:\n"
"%s 123 device 123 105\n" "%s 123 device 123 105\n"
"%s 123 8 123 105\n", filename, filename); "%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);
+15 -9
View File
@@ -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");
@@ -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;
+14 -9
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,7 +128,8 @@ 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(
"Usage: %s device-instance state [password]\r\n"
"Send BACnet ReinitializeDevice service to device.\r\n" "Send BACnet ReinitializeDevice service to device.\r\n"
"\r\n" "\r\n"
"The device-instance can be 0 to %d.\r\n" "The device-instance can be 0 to %d.\r\n"
@@ -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;
} }
+35 -23
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,7 +143,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 " printf(
"Usage: %s device-instance object-type object-instance "
"property array-index tag value\n", "property array-index tag value\n",
filename); filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
@@ -211,7 +216,8 @@ 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(
"Example:\n"
"If you want to RemoveListElement to the Recipient-List property in\n" "If you want to RemoveListElement to the Recipient-List property in\n"
"Notification Class 1 of Device 123, send the following command:\n" "Notification Class 1 of Device 123, send the following command:\n"
"%s 123 15 1 102 -1 4 100\n", "%s 123 15 1 102 -1 4 100\n",
@@ -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(
+40 -27
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,
@@ -967,12 +977,14 @@ static void my_routing_npdu_handler(
/* 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));
} }
} }
@@ -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"))) {
+37 -26
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,
@@ -986,12 +996,14 @@ static void my_routing_npdu_handler(
/* 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.
+22 -13
View File
@@ -18,8 +18,8 @@
#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 {
+3 -8
View File
@@ -35,13 +35,9 @@ 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,
@@ -55,7 +51,6 @@ int dl_ip_recv(
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 {
+7 -22
View File
@@ -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;
+1 -2
View File
@@ -13,7 +13,6 @@
#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)
{ {
+2 -4
View File
@@ -24,10 +24,8 @@
#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,
+11 -30
View File
@@ -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 {
@@ -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 */
+40 -23
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,7 +169,8 @@ 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(
"Usage: %s device-id object-type object-instance "
"process-id <[un]confirmed lifetime|cancel>\n", "process-id <[un]confirmed lifetime|cancel>\n",
filename); filename);
} }
@@ -202,16 +209,22 @@ static void print_help(const char *filename)
"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,7 +392,8 @@ 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(
"Sent SubscribeCOV request. "
" Waiting up to %u seconds....\n", " 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)) {
+18 -10
View File
@@ -68,7 +68,8 @@ 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(
"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"
@@ -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,11 +163,13 @@ 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 Server-Client Demo\n"
"BACnet Stack Version %s\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "BACnet Device ID: %u\n"
"Max APDU: %d\n", "Max APDU: %d\n",
@@ -175,8 +179,9 @@ int main(int argc, char *argv[])
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,
+15 -10
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,12 +257,14 @@ 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 Server-Discovery Demo\n"
"BACnet Stack Version %s\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "BACnet Device ID: %u\n"
"DNET: %u every %lu seconds\n" "DNET: %u every %lu seconds\n"
+17 -10
View File
@@ -106,8 +106,7 @@ 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 },
@@ -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(
@@ -269,10 +271,12 @@ 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(
"To simulate Device 123, use the following command:\n"
"%s 123\n", "%s 123\n",
filename); filename);
printf("To simulate Device 123 named Fred, use following command:\n" printf(
"To simulate Device 123 named Fred, use following command:\n"
"%s 123 Fred\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,7 +347,8 @@ 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 Server Demo\n"
"BACnet Stack Version %s\n" "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n" "BACnet Device ID: %u\n"
"Max APDU: %d\n", "Max APDU: %d\n",
@@ -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);
+10 -7
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;
@@ -122,7 +122,8 @@ 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("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,7 +131,8 @@ 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(
"Send a TimeSynchronization 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);
} }
@@ -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);
+27 -17
View File
@@ -52,8 +52,10 @@ 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");
@@ -83,13 +85,15 @@ static void print_usage(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("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"
@@ -101,11 +105,13 @@ static void print_usage(const char *filename)
"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;
} }
+4 -3
View File
@@ -51,7 +51,8 @@ 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(
"Usage: %s pid object-type object-instance \n"
" event-object-type event-object-instance \n" " event-object-type event-object-instance \n"
" sequence-number notification-class priority event-type\n" " sequence-number notification-class priority event-type\n"
" [reference-bit-string status-flags message notify-type\n" " [reference-bit-string status-flags message notify-type\n"
@@ -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) {
+24 -14
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);
} }
@@ -162,7 +167,8 @@ static void print_help(const char *filename)
"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");
+20 -12
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,7 +243,8 @@ 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(
"Send BACnet What-Is-Network-Number message to a network.\r\n"
"\r\n" "\r\n"
"MAC:\r\n" "MAC:\r\n"
"Optional MAC address of router for unicast message\r\n" "Optional MAC address of router for unicast message\r\n"
+19 -12
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,7 +87,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-min device-instance-min] " printf(
"Usage: %s [device-instance-min device-instance-min] "
"<object-type object-instance | object-name> [--help]\r\n", "<object-type object-instance | object-name> [--help]\r\n",
filename); filename);
} }
@@ -95,7 +96,8 @@ static void print_usage(const char *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(
"Send BACnet WhoHas request to devices, \r\n"
"and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n" "and wait %u milliseconds (BACNET_APDU_TIMEOUT) for responses.\r\n"
"The device-instance-min or max can be 0 to %d.\r\n" "The device-instance-min or max can be 0 to %d.\r\n"
"\r\n" "\r\n"
@@ -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 (;;) {
+28 -15
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");
@@ -300,25 +303,32 @@ 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 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 {
+20 -12
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,7 +228,8 @@ 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(
"Send BACnet Who-Is-Router-To-Network message to a network.\r\n"
"\r\n" "\r\n"
"DNET:\r\n" "DNET:\r\n"
"BACnet destination network number 0-65535\r\n" "BACnet destination network number 0-65535\r\n"
@@ -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)) {
+19 -11
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,7 +151,8 @@ 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(
"%s device-instance file-instance local-name [octet count] [pad "
"value]\r\n", "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;
+31 -26
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,7 +141,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 " printf(
"Usage: %s device-instance object-type object-instance "
"property priority index tag value [tag value...]\n", "property priority index tag value [tag value...]\n",
filename); filename);
} }
@@ -152,8 +156,7 @@ 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"
@@ -167,8 +170,7 @@ 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"
@@ -176,8 +178,7 @@ static void print_help(const char *filename)
"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"
@@ -199,8 +200,7 @@ 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");
@@ -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;
} }
+55 -34
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,7 +170,8 @@ 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(
"Usage: %s device-instance object-type object-instance "
"property[index] priority tag value [property[index] priority tag " "property[index] priority tag value [property[index] priority tag "
"value]\n", "value]\n",
filename); filename);
@@ -209,30 +216,34 @@ static void print_help(const char *filename)
"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"
@@ -245,7 +256,8 @@ static void print_help(const char *filename)
"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,7 +465,8 @@ 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));
@@ -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)
{ {
+8 -8
View File
@@ -21,28 +21,28 @@
#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(
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,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code); BACNET_ERROR_CODE *error_code);
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);
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);
+8 -6
View File
@@ -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++) {
+24 -12
View File
@@ -76,9 +76,10 @@ 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 */
uint8_t *bip_get_addr(void) uint8_t *bip_get_addr(void)
@@ -88,9 +89,10 @@ 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 */
uint8_t *bip_get_broadcast_addr(void) uint8_t *bip_get_broadcast_addr(void)
@@ -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'
@@ -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 */
+5 -4
View File
@@ -33,8 +33,7 @@ extern "C" {
/* 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);
@@ -44,7 +43,8 @@ extern "C" {
/* 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 */
@@ -54,7 +54,8 @@ extern "C" {
/* 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 */
+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)
{ {
+6 -6
View File
@@ -18,14 +18,12 @@
#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);
@@ -33,14 +31,16 @@ extern "C" {
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(
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,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code); BACNET_ERROR_CODE *error_code);
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);
+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);
+6 -6
View File
@@ -72,14 +72,13 @@ extern void routed_get_my_address(BACNET_ADDRESS * my_address);
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int datalink_send_pdu(BACNET_ADDRESS * dest, int datalink_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);
extern uint16_t datalink_receive(BACNET_ADDRESS * src, extern uint16_t datalink_receive(
uint8_t * pdu, BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout);
uint16_t max_pdu,
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);
@@ -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 {
+24 -28
View File
@@ -16,33 +16,30 @@
#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(
BACNET_OBJECT_TYPE object_type,
object_count_function count_function, object_count_function count_function,
object_index_to_instance_function index_function, object_index_to_instance_function index_function,
object_name_function name_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);
@@ -52,26 +49,21 @@ extern "C" {
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);
@@ -81,24 +73,29 @@ extern "C" {
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(
const char *object_name,
BACNET_OBJECT_TYPE *object_type, BACNET_OBJECT_TYPE *object_type,
uint32_t *object_instance); uint32_t *object_instance);
char *Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type, char *Device_Valid_Object_Id(
uint32_t object_instance); BACNET_OBJECT_TYPE object_type, uint32_t object_instance);
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,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code); BACNET_ERROR_CODE *error_code);
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);
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 */
@@ -107,7 +104,6 @@ extern "C" {
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code); BACNET_ERROR_CODE *error_code);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __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);
+23 -18
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,23 +49,25 @@ 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);
@@ -73,12 +76,13 @@ void handler_write_property(uint8_t *service_request,
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);
@@ -87,21 +91,22 @@ void handler_write_property(uint8_t *service_request,
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;
} }
} }
+8 -5
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
[MAX_MPDU + 16 /* Add a little safety margin to the buffer,
* so that in the rare case, the message * so that in the rare case, the message
* would be filled up to MAX_MPDU and some * would be filled up to MAX_MPDU and some
* decoding functions would overrun, these * decoding functions would overrun, these
* decoding functions will just end up in * decoding functions will just end up in
* a safe field of static zeros. */]; * a safe field of static zeros. */
];
/** Main */ /** Main */
+1 -2
View File
@@ -17,8 +17,7 @@ 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;
} }
+6 -10
View File
@@ -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;
+35 -23
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]);
} }
@@ -111,7 +111,8 @@ void bip6_set_interface(char *ifname)
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)");
} }
+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,9 +582,10 @@ 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,9 +584,10 @@ 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;
} }
+14 -35
View File
@@ -104,15 +104,11 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
bool dlmstp_init( bool dlmstp_init(void *poShared, char *ifname);
void *poShared,
char *ifname);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_reset( void dlmstp_reset(void *poShared);
void *poShared);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_cleanup( void dlmstp_cleanup(void *poShared);
void *poShared);
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
@@ -139,12 +135,9 @@ extern "C" {
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(void *poShared, uint8_t max_info_frames);
void *poShared,
uint8_t max_info_frames);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint8_t dlmstp_max_info_frames( uint8_t dlmstp_max_info_frames(void *poShared);
void *poShared);
/* This parameter represents the value of the Max_Master property of the */ /* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */ /* node's Device object. The value of Max_Master specifies the highest */
@@ -152,47 +145,33 @@ extern "C" {
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_set_max_master( void dlmstp_set_max_master(void *poShared, uint8_t max_master);
void *poShared,
uint8_t max_master);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void *poShared);
void *poShared);
/* MAC address 0-127 */ /* MAC address 0-127 */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_set_mac_address( void dlmstp_set_mac_address(void *poShared, uint8_t my_address);
void *poShared,
uint8_t my_address);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint8_t dlmstp_mac_address( uint8_t dlmstp_mac_address(void *poShared);
void *poShared);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_get_my_address( void dlmstp_get_my_address(void *poShared, BACNET_ADDRESS *my_address);
void *poShared,
BACNET_ADDRESS * my_address);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(
BACNET_ADDRESS *dest); /* destination address */ BACNET_ADDRESS *dest); /* destination address */
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */ /* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_set_baud_rate( void dlmstp_set_baud_rate(void *poShared, uint32_t baud);
void *poShared,
uint32_t baud);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint32_t dlmstp_baud_rate( uint32_t dlmstp_baud_rate(void *poShared);
void *poShared);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address);
BACNET_ADDRESS * src,
uint8_t mstp_address);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
bool dlmstp_sole_master( bool dlmstp_sole_master(void);
void);
#ifdef __cplusplus #ifdef __cplusplus
} }
+48 -27
View File
@@ -17,8 +17,9 @@
* BACnet/Ethernet. */ * BACnet/Ethernet. */
/* commonly used comparison address for ethernet */ /* commonly used comparison address for ethernet */
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = {
0xFF }; 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
/* commonly used empty address for ethernet quick compare */ /* commonly used empty address for ethernet quick compare */
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 }; uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
@@ -35,8 +36,9 @@ bool ethernet_valid(void)
void ethernet_cleanup(void) void ethernet_cleanup(void)
{ {
if (ethernet_valid()) if (ethernet_valid()) {
close(eth802_sockfd); close(eth802_sockfd);
}
eth802_sockfd = -1; eth802_sockfd = -1;
return; return;
@@ -76,7 +78,8 @@ static int ethernet_bind(struct sockaddr *eth_addr, 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,
"ethernet: Unable to open an 802.2 socket. " "ethernet: Unable to open an 802.2 socket. "
"Try running with root priveleges.\n"); "Try running with root priveleges.\n");
return sock_fd; return sock_fd;
@@ -93,7 +96,8 @@ static int ethernet_bind(struct sockaddr *eth_addr, const char *interface_name)
/* Error occured */ /* Error occured */
fprintf( fprintf(
stderr, "ethernet: Error opening socket: %s\n", strerror(errno)); stderr, "ethernet: 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"
@@ -121,9 +125,11 @@ static int ethernet_bind(struct sockaddr *eth_addr, const char *interface_name)
/* Attempt to bind the socket to the interface */ /* Attempt to bind the socket to the interface */
if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0) { if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0) {
/* Bind problem, close socket and return */ /* Bind problem, close socket and return */
fprintf(stderr, "ethernet: Unable to bind 802.2 socket : %s\n", fprintf(
stderr, "ethernet: Unable to bind 802.2 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"
@@ -150,13 +156,14 @@ static int get_local_hwaddr(const char *ifname, unsigned char *mac)
/* determine the local MAC address */ /* determine the local MAC address */
strcpy(ifr.ifr_name, ifname); strcpy(ifr.ifr_name, ifname);
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (fd < 0) if (fd < 0) {
rv = fd; rv = fd;
else { } else {
rv = ioctl(fd, SIOCGIFHWADDR, &ifr); rv = ioctl(fd, SIOCGIFHWADDR, &ifr);
if (rv >= 0) /* worked okay */ if (rv >= 0) { /* worked okay */
memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
} }
}
return rv; return rv;
} }
@@ -179,19 +186,22 @@ int ethernet_send(uint8_t *mtu, int mtu_len)
int bytes = 0; int bytes = 0;
/* Send the packet */ /* Send the packet */
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0, bytes = sendto(
(struct sockaddr *)&eth_addr, sizeof(struct sockaddr)); eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *)&eth_addr,
sizeof(struct sockaddr));
/* did it get sent? */ /* did it get sent? */
if (bytes < 0) if (bytes < 0) {
fprintf( fprintf(
stderr, "ethernet: Error sending packet: %s\n", strerror(errno)); stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
}
return bytes; return bytes;
} }
/* function to send a packet out the 802.2 socket */ /* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */ int ethernet_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)
@@ -248,19 +258,22 @@ int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
encode_unsigned16(&mtu[12], 3 + pdu_len); encode_unsigned16(&mtu[12], 3 + pdu_len);
/* Send the packet */ /* Send the packet */
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0, bytes = sendto(
(struct sockaddr *)&eth_addr, sizeof(struct sockaddr)); eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *)&eth_addr,
sizeof(struct sockaddr));
/* did it get sent? */ /* did it get sent? */
if (bytes < 0) if (bytes < 0) {
fprintf( fprintf(
stderr, "ethernet: Error sending packet: %s\n", strerror(errno)); stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
}
return bytes; return bytes;
} }
/* receives an 802.2 framed packet */ /* receives an 802.2 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 ethernet_receive(BACNET_ADDRESS *src, /* source address */ uint16_t ethernet_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)
@@ -273,8 +286,9 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
struct timeval select_timeout; struct timeval select_timeout;
/* Make sure the socket is open */ /* Make sure the socket is open */
if (eth802_sockfd <= 0) if (eth802_sockfd <= 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
@@ -291,24 +305,28 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
FD_SET(eth802_sockfd, &read_fds); FD_SET(eth802_sockfd, &read_fds);
max = eth802_sockfd; max = eth802_sockfd;
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(eth802_sockfd, &buf[0], sizeof(buf)); received_bytes = read(eth802_sockfd, &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;
}
/* the signature of an 802.2 BACnet packet */ /* the signature of an 802.2 BACnet packet */
if ((buf[14] != 0x82) && (buf[15] != 0x82)) { if ((buf[14] != 0x82) && (buf[15] != 0x82)) {
@@ -330,11 +348,13 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
(void)decode_unsigned16(&buf[12], &pdu_len); (void)decode_unsigned16(&buf[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */; pdu_len -= 3 /* 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], &buf[17], pdu_len); memmove(&pdu[0], &buf[17], pdu_len);
}
/* ignore packets that are too large */ /* ignore packets that are too large */
else else {
pdu_len = 0; pdu_len = 0;
}
return pdu_len; return pdu_len;
} }
@@ -391,8 +411,9 @@ void ethernet_debug_address(const char *info, const BACNET_ADDRESS *dest)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
if (info) if (info) {
fprintf(stderr, "%s", info); fprintf(stderr, "%s", info);
}
if (dest) { if (dest) {
fprintf(stderr, "Address:\n"); fprintf(stderr, "Address:\n");
fprintf(stderr, " MAC Length=%d\n", dest->mac_len); fprintf(stderr, " MAC Length=%d\n", dest->mac_len);
+6 -7
View File
@@ -68,8 +68,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;
@@ -92,8 +91,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;
@@ -140,8 +138,8 @@ static int network_init(const char *name, int protocol)
return sockfd; return sockfd;
} }
static void snap_received_packet( static void
const struct mstp_port_struct_t *mstp_port, int sockfd) snap_received_packet(const struct mstp_port_struct_t *mstp_port, int sockfd)
{ {
uint16_t mtu_len = 0; /* number of octets of packet saved in file */ uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */ unsigned i = 0; /* counter */
@@ -267,7 +265,8 @@ int main(int argc, char *argv[])
MSTP_Port.SilenceTimer = Timer_Silence; MSTP_Port.SilenceTimer = Timer_Silence;
MSTP_Port.SilenceTimerReset = Timer_Silence_Reset; MSTP_Port.SilenceTimerReset = Timer_Silence_Reset;
MSTP_Init(mstp_port); MSTP_Init(mstp_port);
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());
atexit(cleanup); atexit(cleanup);
#if defined(_WIN32) #if defined(_WIN32)
+13 -7
View File
@@ -569,12 +569,14 @@ void RS485_Initialize(void)
newserial.custom_divisor = round(((float)newserial.baud_base) / 76800); newserial.custom_divisor = round(((float)newserial.baud_base) / 76800);
/* we must check that we calculated some sane value; /* we must check that we calculated some sane value;
small baud bases yield bad custom divisor values */ small baud bases yield bad custom divisor values */
baud_error = fabs(1 - baud_error = fabs(
1 -
((float)newserial.baud_base) / ((float)newserial.custom_divisor) / ((float)newserial.baud_base) / ((float)newserial.custom_divisor) /
76800); 76800);
if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) { if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) {
/* bad divisor */ /* bad divisor */
fprintf(stderr, "RS485 bad custom divisor %d, base baud %d\n", fprintf(
stderr, "RS485 bad custom divisor %d, base baud %d\n",
newserial.custom_divisor, newserial.baud_base); newserial.custom_divisor, newserial.baud_base);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -617,19 +619,22 @@ void RS485_Print_Ports(void)
while (n--) { while (n--) {
if (strcmp(namelist[n]->d_name, "..") && if (strcmp(namelist[n]->d_name, "..") &&
strcmp(namelist[n]->d_name, ".")) { strcmp(namelist[n]->d_name, ".")) {
snprintf(device_dir, sizeof(device_dir), "%s%s/device", sysdir, snprintf(
device_dir, sizeof(device_dir), "%s%s/device", sysdir,
namelist[n]->d_name); namelist[n]->d_name);
/* Stat the devicedir and handle it if it is a symlink */ /* Stat the devicedir and handle it if it is a symlink */
if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) { if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) {
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
snprintf(device_dir, sizeof(device_dir), snprintf(
"%s%s/device/driver", sysdir, namelist[n]->d_name); device_dir, sizeof(device_dir), "%s%s/device/driver",
sysdir, namelist[n]->d_name);
if (readlink(device_dir, buffer, sizeof(buffer)) > 0) { if (readlink(device_dir, buffer, sizeof(buffer)) > 0) {
valid_port = false; valid_port = false;
driver_name = basename(buffer); driver_name = basename(buffer);
if (strcmp(driver_name, "serial8250") == 0) { if (strcmp(driver_name, "serial8250") == 0) {
/* serial8250-devices must be probed */ /* serial8250-devices must be probed */
snprintf(device_dir, sizeof(device_dir), "/dev/%s", snprintf(
device_dir, sizeof(device_dir), "/dev/%s",
namelist[n]->d_name); namelist[n]->d_name);
fd = open( fd = open(
device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY); device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY);
@@ -649,7 +654,8 @@ void RS485_Print_Ports(void)
} }
if (valid_port) { if (valid_port) {
/* print full absolute file path */ /* print full absolute file path */
printf("interface {value=/dev/%s}" printf(
"interface {value=/dev/%s}"
"{display=MS/TP Capture on /dev/%s}\n", "{display=MS/TP Capture on /dev/%s}\n",
namelist[n]->d_name, namelist[n]->d_name); namelist[n]->d_name, namelist[n]->d_name);
} }
+8 -16
View File
@@ -16,15 +16,12 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Set_Interface( void RS485_Set_Interface(char *ifname);
char *ifname);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
const char *RS485_Interface( const char *RS485_Interface(void);
void);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Initialize( void RS485_Initialize(void);
void);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Send_Frame( void RS485_Send_Frame(
@@ -36,21 +33,16 @@ extern "C" {
void RS485_Check_UART_Data( void RS485_Check_UART_Data(
struct mstp_port_struct_t *mstp_port); /* port specific data */ struct mstp_port_struct_t *mstp_port); /* port specific data */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint32_t RS485_Get_Port_Baud_Rate( uint32_t RS485_Get_Port_Baud_Rate(struct mstp_port_struct_t *mstp_port);
struct mstp_port_struct_t *mstp_port);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(void);
void);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(uint32_t baud);
uint32_t baud);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Cleanup( void RS485_Cleanup(void);
void);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Print_Ports( void RS485_Print_Ports(void);
void);
#ifdef __cplusplus #ifdef __cplusplus
} }
+4 -5
View File
@@ -19,11 +19,10 @@
#include "lwip/dhcp.h" #include "lwip/dhcp.h"
#include "lwip/inet.h" #include "lwip/inet.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")
#endif #endif
+8 -8
View File
@@ -153,9 +153,8 @@ static void bip_mac_to_addr(ip4_addr_t *address, const uint8_t *mac)
* @param address - IPv4 address from LwIP * @param address - IPv4 address from LwIP
* @param port - IPv4 UDP port number * @param port - IPv4 UDP port number
*/ */
static int bip_decode_bip_address(const BACNET_IP_ADDRESS *baddr, static int bip_decode_bip_address(
ip_addr_t *address, const BACNET_IP_ADDRESS *baddr, ip_addr_t *address, uint16_t *port)
uint16_t *port)
{ {
int len = 0; int len = 0;
@@ -190,9 +189,8 @@ static void bip_addr_to_mac(uint8_t *mac, const ip4_addr_t *address)
* @param address - IPv4 address from LwIP * @param address - IPv4 address from LwIP
* @param port - IPv4 UDP port number * @param port - IPv4 UDP port number
*/ */
static int bip_encode_bip_address(BACNET_IP_ADDRESS *baddr, static int bip_encode_bip_address(
const ip_addr_t *address, BACNET_IP_ADDRESS *baddr, const ip_addr_t *address, uint16_t port)
uint16_t port)
{ {
int len = 0; int len = 0;
@@ -249,7 +247,8 @@ int bip_send_mpdu(
* *
* @return number of bytes sent * @return number of bytes sent
*/ */
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) unsigned pdu_len)
@@ -265,7 +264,8 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
* @param addr [in] UDP source address * @param addr [in] UDP source address
* @param port [in] UDP port number * @param port [in] UDP port number
*/ */
void bip_server_callback(void *arg, void bip_server_callback(
void *arg,
struct udp_pcb *upcb, struct udp_pcb *upcb,
struct pbuf *pkt, struct pbuf *pkt,
const ip_addr_t *addr, const ip_addr_t *addr,

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