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:
@@ -47,11 +47,10 @@ repos:
|
||||
args: ["--whitespaces-count", "2"]
|
||||
files: '.*\.(yaml|yml|html|htm)|Dockerfile$'
|
||||
|
||||
# We will enable this in future.
|
||||
# - repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
# rev: 3b03191b6a60cba0fc25c2dc2e30ea4854d897eb # v17.0.5
|
||||
# hooks:
|
||||
# - id: clang-format
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: 05241dc3def184dba136e62d54ff57f1c8a497a9 # v17.0.6
|
||||
hooks:
|
||||
- id: clang-format
|
||||
|
||||
# We might enable this in future.
|
||||
# - repo: https://github.com/pre-commit/mirrors-prettier
|
||||
|
||||
+8
-5
@@ -46,8 +46,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
(void)src;
|
||||
(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 Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
|
||||
printf("\n");
|
||||
printf("--dnet N\n"
|
||||
printf(
|
||||
"--dnet N\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"
|
||||
"and 65535 is network broadcast.\n");
|
||||
@@ -109,7 +110,8 @@ static void print_help(const char *filename)
|
||||
"server:\n"
|
||||
" 0=false, 1=true\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"%s 3 2 1\n",
|
||||
filename);
|
||||
}
|
||||
@@ -214,7 +216,8 @@ int main(int argc, char *argv[])
|
||||
dlenv_init();
|
||||
atexit(datalink_cleanup);
|
||||
/* 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);
|
||||
|
||||
return 0;
|
||||
|
||||
+18
-11
@@ -51,14 +51,16 @@ static bool Error_Detected = false;
|
||||
* @param error_class [in] the error class
|
||||
* @param error_code [in] the error code
|
||||
*/
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -90,12 +92,13 @@ static void MyAbortHandler(
|
||||
* @param invoke_id [in] the invokeID from the rejected message
|
||||
* @param reject_reason [in] the reason for the rejection
|
||||
*/
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -106,8 +109,8 @@ static void MyRejectHandler(
|
||||
* @param src [in] BACNET_ADDRESS of the source of the message
|
||||
* @param invoke_id [in] the invokeID from the rejected message
|
||||
*/
|
||||
static void MyWritePropertySimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -143,7 +146,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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-time-stamp ack-source-name ack-time-stamp\n",
|
||||
filename);
|
||||
@@ -154,7 +158,8 @@ static void print_usage(const char *filename)
|
||||
static void print_help(const char *filename)
|
||||
{
|
||||
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"
|
||||
"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"
|
||||
@@ -164,7 +169,8 @@ static void print_help(const char *filename)
|
||||
"Process Identifier in the receiving device for which the\n"
|
||||
"notification is intended.\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"
|
||||
"as defined in the BACnet specification, or as the integer value.\n");
|
||||
printf("\n");
|
||||
@@ -345,7 +351,8 @@ int main(int argc, char *argv[])
|
||||
dest.len = 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
/* setup my info */
|
||||
|
||||
@@ -57,7 +57,8 @@ static bool Error_Detected = false;
|
||||
/* Used for verbose */
|
||||
static bool Verbose = false;
|
||||
|
||||
static void MyAddListElementErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyAddListElementErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
uint8_t service_choice,
|
||||
uint8_t *service_request,
|
||||
@@ -72,7 +73,8 @@ static void MyAddListElementErrorHandler(BACNET_ADDRESS *src,
|
||||
len = list_element_error_ack_decode(
|
||||
service_request, service_len, &list_element);
|
||||
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_code_name((int)list_element.error_code),
|
||||
(unsigned)list_element.first_failed_element_number);
|
||||
@@ -81,8 +83,8 @@ static void MyAddListElementErrorHandler(BACNET_ADDRESS *src,
|
||||
}
|
||||
}
|
||||
|
||||
static void MyAddListElementSimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyAddListElementSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -102,13 +104,14 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -139,7 +142,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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",
|
||||
filename);
|
||||
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"
|
||||
"accepting REAL, BOOLEAN, NULL, etc.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"If you want to AddListElement to the Recipient-List property in\n"
|
||||
"Notification Class 1 of Device 123, send the following command:\n"
|
||||
"%s 123 15 1 102 -1 4 100\n",
|
||||
@@ -287,8 +292,8 @@ int main(int argc, char *argv[])
|
||||
if (target_args == 0) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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",
|
||||
object_instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
@@ -305,8 +310,8 @@ int main(int argc, char *argv[])
|
||||
} else if (target_args == 2) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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);
|
||||
return 1;
|
||||
}
|
||||
@@ -330,7 +335,8 @@ int main(int argc, char *argv[])
|
||||
property_array_index = strtol(argv[argi], NULL, 0);
|
||||
Target_Object_Array_Index = property_array_index;
|
||||
if (Verbose) {
|
||||
printf("Array_Index=%i=%s\n", property_array_index,
|
||||
printf(
|
||||
"Array_Index=%i=%s\n", property_array_index,
|
||||
argv[argi]);
|
||||
}
|
||||
target_args++;
|
||||
@@ -357,14 +363,16 @@ int main(int argc, char *argv[])
|
||||
} else if (tag_value_arg == 1) {
|
||||
value_string = argv[argi];
|
||||
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) {
|
||||
/* find the application tag for internal properties */
|
||||
property_tag = bacapp_known_property_tag(
|
||||
Target_Object_Type, Target_Object_Property);
|
||||
} else if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: tag=%ld - it must be less than %u\n",
|
||||
property_tag, MAX_BACNET_APPLICATION_TAG);
|
||||
return 1;
|
||||
@@ -374,13 +382,15 @@ int main(int argc, char *argv[])
|
||||
status = bacapp_parse_application_data(
|
||||
property_tag, value_string, application_value);
|
||||
if (!status) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: unable to parse the tag value\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* FIXME: show the expected entry format for the tag */
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: unable to parse the known property"
|
||||
" \"%s\"\r\n",
|
||||
value_string);
|
||||
@@ -422,7 +432,8 @@ int main(int argc, char *argv[])
|
||||
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||
if (found) {
|
||||
if (Verbose) {
|
||||
printf("Found Device %u in address_cache.\n",
|
||||
printf(
|
||||
"Found Device %u in address_cache.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
} else {
|
||||
@@ -435,7 +446,8 @@ int main(int argc, char *argv[])
|
||||
/* device is bound! */
|
||||
if (Request_Invoke_ID == 0) {
|
||||
if (Verbose) {
|
||||
printf("Sending AddListElement to Device %u.\n",
|
||||
printf(
|
||||
"Sending AddListElement to Device %u.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
Request_Invoke_ID = Send_Add_List_Element_Request(
|
||||
@@ -465,7 +477,7 @@ int main(int argc, char *argv[])
|
||||
mstimer_reset(&maintenance_timer);
|
||||
tsm_timer_milliseconds(mstimer_interval(&maintenance_timer));
|
||||
datalink_maintenance_timer(
|
||||
mstimer_interval(&maintenance_timer)/1000L);
|
||||
mstimer_interval(&maintenance_timer) / 1000L);
|
||||
}
|
||||
if (mstimer_expired(&apdu_timer)) {
|
||||
printf("\rError: APDU Timeout!\n");
|
||||
|
||||
+24
-14
@@ -57,12 +57,14 @@ static bool BACnet_Debug_Enabled;
|
||||
/**
|
||||
* @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_CODE error_code)
|
||||
{
|
||||
debug_printf("[{\n");
|
||||
debug_printf(" \"%s\": {\n"
|
||||
debug_printf(
|
||||
" \"%s\": {\n"
|
||||
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"",
|
||||
hex_ascii, bactext_error_class_name((int)error_class),
|
||||
bactext_error_code_name((int)error_code));
|
||||
@@ -78,7 +80,8 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -87,12 +90,13 @@ static void MyAbortHandler(
|
||||
/**
|
||||
* @brief Handler for reject messages
|
||||
*/
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -178,16 +182,20 @@ static void print_help(const char *filename)
|
||||
"Default delay is 100ms.\n");
|
||||
printf("\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",
|
||||
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",
|
||||
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",
|
||||
filename);
|
||||
printf("Send an APDU to Device 1:\n"
|
||||
printf(
|
||||
"Send an APDU to Device 1:\n"
|
||||
"%s 1 0123456789ABCDEF\n",
|
||||
filename);
|
||||
}
|
||||
@@ -228,8 +236,8 @@ static void Send_APDU_To_Network(
|
||||
* @param ascii_hex [in] The string of ASCII hex.
|
||||
* @return number of bytes converted, or 0 if error.
|
||||
*/
|
||||
static size_t ascii_hex_to_binary(
|
||||
uint8_t *buffer, size_t buffer_size, const char *ascii_hex)
|
||||
static size_t
|
||||
ascii_hex_to_binary(uint8_t *buffer, size_t buffer_size, const char *ascii_hex)
|
||||
{
|
||||
unsigned index = 0; /* offset into buffer */
|
||||
uint8_t value = 0;
|
||||
@@ -401,7 +409,8 @@ int main(int argc, char *argv[])
|
||||
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||
if (found) {
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
@@ -432,7 +441,8 @@ int main(int argc, char *argv[])
|
||||
if (found) {
|
||||
/* device is bound! */
|
||||
if (BACnet_Debug_Enabled) {
|
||||
printf("Sending APDU to Device %u.\n",
|
||||
printf(
|
||||
"Sending APDU to Device %u.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
if (mstimer_expired(&apdu_timer)) {
|
||||
|
||||
@@ -52,8 +52,9 @@ void blinkt_clear(void)
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (led >= BLINKT_NUM_LEDS)
|
||||
if (led >= BLINKT_NUM_LEDS) {
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (led >= BLINKT_NUM_LEDS)
|
||||
if (led >= BLINKT_NUM_LEDS) {
|
||||
return;
|
||||
}
|
||||
|
||||
Blinkt_LED[led] = color;
|
||||
}
|
||||
@@ -206,8 +209,9 @@ void blinkt_test_task(void)
|
||||
}
|
||||
blinkt_show();
|
||||
test_y += 1;
|
||||
if (test_y > 254)
|
||||
if (test_y > 254) {
|
||||
test_column++;
|
||||
}
|
||||
test_column %= 3;
|
||||
test_y %= 255;
|
||||
}
|
||||
|
||||
+224
-95
@@ -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 My_Object_Table[] = {
|
||||
{ OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */,
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number, Device_Object_Name,
|
||||
Device_Read_Property_Local, 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 */,
|
||||
{ OBJECT_DEVICE,
|
||||
NULL /* Init - don't init Device or it will recourse! */,
|
||||
Device_Count,
|
||||
Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number,
|
||||
Device_Object_Name,
|
||||
Device_Read_Property_Local,
|
||||
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 */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
||||
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
||||
Network_Port_Object_Name, Network_Port_Read_Property,
|
||||
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 */ },
|
||||
{ OBJECT_NETWORK_PORT,
|
||||
Network_Port_Init,
|
||||
Network_Port_Count,
|
||||
Network_Port_Index_To_Instance,
|
||||
Network_Port_Valid_Instance,
|
||||
Network_Port_Object_Name,
|
||||
Network_Port_Read_Property,
|
||||
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
|
||||
{ OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count,
|
||||
Load_Control_Index_To_Instance, Load_Control_Valid_Instance,
|
||||
Load_Control_Object_Name, Load_Control_Read_Property,
|
||||
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 */ },
|
||||
{ OBJECT_LOAD_CONTROL,
|
||||
Load_Control_Init,
|
||||
Load_Control_Count,
|
||||
Load_Control_Index_To_Instance,
|
||||
Load_Control_Valid_Instance,
|
||||
Load_Control_Object_Name,
|
||||
Load_Control_Read_Property,
|
||||
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)
|
||||
{ OBJECT_LIGHTING_OUTPUT, Lighting_Output_Init, Lighting_Output_Count,
|
||||
Lighting_Output_Index_To_Instance, Lighting_Output_Valid_Instance,
|
||||
Lighting_Output_Object_Name, Lighting_Output_Read_Property,
|
||||
Lighting_Output_Write_Property, Lighting_Output_Property_Lists,
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
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 */ },
|
||||
{ OBJECT_LIGHTING_OUTPUT,
|
||||
Lighting_Output_Init,
|
||||
Lighting_Output_Count,
|
||||
Lighting_Output_Index_To_Instance,
|
||||
Lighting_Output_Valid_Instance,
|
||||
Lighting_Output_Object_Name,
|
||||
Lighting_Output_Read_Property,
|
||||
Lighting_Output_Write_Property,
|
||||
Lighting_Output_Property_Lists,
|
||||
NULL /* ReadRangeInfo */,
|
||||
NULL /* Iterator */,
|
||||
NULL /* Value_Lists */,
|
||||
NULL /* COV */,
|
||||
NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
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
|
||||
#if (BACNET_PROTOCOL_REVISION >= 24)
|
||||
{ OBJECT_COLOR, Color_Init, Color_Count, Color_Index_To_Instance,
|
||||
Color_Valid_Instance, Color_Object_Name, Color_Read_Property,
|
||||
Color_Write_Property, Color_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_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,
|
||||
{ OBJECT_COLOR,
|
||||
Color_Init,
|
||||
Color_Count,
|
||||
Color_Index_To_Instance,
|
||||
Color_Valid_Instance,
|
||||
Color_Object_Name,
|
||||
Color_Read_Property,
|
||||
Color_Write_Property,
|
||||
Color_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_Create,
|
||||
Color_Delete,
|
||||
Color_Timer },
|
||||
{ OBJECT_COLOR_TEMPERATURE,
|
||||
Color_Temperature_Init,
|
||||
Color_Temperature_Count,
|
||||
Color_Temperature_Index_To_Instance,
|
||||
Color_Temperature_Valid_Instance,
|
||||
Color_Temperature_Object_Name,
|
||||
Color_Temperature_Read_Property,
|
||||
Color_Temperature_Write_Property,
|
||||
Color_Temperature_Property_Lists,
|
||||
NULL /* ReadRangeInfo */,
|
||||
NULL /* Iterator */,
|
||||
NULL /* Value_Lists */,
|
||||
NULL /* COV */,
|
||||
NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
Color_Temperature_Create,
|
||||
Color_Temperature_Delete,
|
||||
Color_Temperature_Timer },
|
||||
#endif
|
||||
{ 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 */ }
|
||||
{ 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,
|
||||
@@ -128,8 +224,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
* @return Pointer to the group of object helper functions that implement this
|
||||
* type of Object.
|
||||
*/
|
||||
static struct object_functions *Device_Objects_Find_Functions(
|
||||
BACNET_OBJECT_TYPE Object_Type)
|
||||
static struct object_functions *
|
||||
Device_Objects_Find_Functions(BACNET_OBJECT_TYPE Object_Type)
|
||||
{
|
||||
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
|
||||
* 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,
|
||||
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);
|
||||
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
|
||||
pObject->Object_RPM_List(&pPropertyList->Required.pList,
|
||||
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList);
|
||||
pObject->Object_RPM_List(
|
||||
&pPropertyList->Required.pList, &pPropertyList->Optional.pList,
|
||||
&pPropertyList->Proprietary.pList);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, 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_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_SYSTEM_STATUS,
|
||||
PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER,
|
||||
PROP_MODEL_NAME,
|
||||
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[] = {
|
||||
#if defined(BACDL_MSTP)
|
||||
PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES,
|
||||
PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES,
|
||||
#endif
|
||||
PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE,
|
||||
PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_LOCAL_TIME,
|
||||
PROP_UTC_OFFSET,
|
||||
PROP_LOCAL_DATE,
|
||||
PROP_DAYLIGHT_SAVINGS_STATUS,
|
||||
PROP_LOCATION,
|
||||
PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||
#if defined(BACNET_TIME_MASTER)
|
||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||
PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET,
|
||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||
PROP_ALIGN_INTERVALS,
|
||||
PROP_INTERVAL_OFFSET,
|
||||
#endif
|
||||
-1
|
||||
};
|
||||
@@ -803,7 +923,8 @@ int Device_Object_List_Element_Encode(
|
||||
* Object.
|
||||
* @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,
|
||||
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.
|
||||
* @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,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
@@ -1081,7 +1203,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* 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_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
@@ -1108,9 +1231,9 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
break;
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Device_Object_List_Element_Encode, count, apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -1233,8 +1356,9 @@ static int Read_Property_Common(
|
||||
} else if (rpdata->object_property == PROP_PROPERTY_LIST) {
|
||||
Device_Objects_Property_List(
|
||||
rpdata->object_type, rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(rpdata, property_list.Required.pList,
|
||||
property_list.Optional.pList, property_list.Proprietary.pList);
|
||||
apdu_len = property_list_encode(
|
||||
rpdata, property_list.Required.pList, property_list.Optional.pList,
|
||||
property_list.Proprietary.pList);
|
||||
#endif
|
||||
} else if (pObject->Object_Read_Property) {
|
||||
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));
|
||||
if (status) {
|
||||
/* All the object names in a device must be unique */
|
||||
if (Device_Valid_Object_Name(&value.type.Character_String,
|
||||
&object_type, &object_instance)) {
|
||||
if (Device_Valid_Object_Name(
|
||||
&value.type.Character_String, &object_type,
|
||||
&object_instance)) {
|
||||
if ((object_type == wp_data->object_type) &&
|
||||
(object_instance == wp_data->object_instance)) {
|
||||
/* 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
|
||||
* @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,
|
||||
BACNET_PROPERTY_VALUE *value_list)
|
||||
{
|
||||
@@ -1822,7 +1948,8 @@ bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
|
||||
object for some other reason.*/
|
||||
data->error_class = ERROR_CLASS_OBJECT;
|
||||
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)) {
|
||||
/* The object being created already exists */
|
||||
data->error_class = ERROR_CLASS_OBJECT;
|
||||
@@ -1880,7 +2007,8 @@ bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
|
||||
object for some reason.*/
|
||||
data->error_class = ERROR_CLASS_OBJECT;
|
||||
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)) {
|
||||
/* The object being deleted must already exist */
|
||||
status = pObject->Object_Delete(data->object_instance);
|
||||
@@ -1955,7 +2083,8 @@ void Device_Init(object_functions_t *object_table)
|
||||
#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)
|
||||
{ /* Where to put the response */
|
||||
bool status = false; /* return value */
|
||||
|
||||
+21
-12
@@ -100,7 +100,8 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_unconfirmed_handler(
|
||||
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
|
||||
/* 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);
|
||||
/* configure the cyclic timers */
|
||||
mstimer_set(&BACnet_Task_Timer, 1000UL);
|
||||
@@ -141,7 +142,8 @@ static void Lighting_Output_Write_Value_Handler(
|
||||
brightness = 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -165,7 +167,8 @@ static void Color_Temperature_Write_Value_Handler(
|
||||
if (index < blinkt_led_count()) {
|
||||
color_rgb_from_temperature(value, &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);
|
||||
}
|
||||
}
|
||||
@@ -176,7 +179,8 @@ static void Color_Temperature_Write_Value_Handler(
|
||||
* @param old_value - BACnetXYColor value prior to 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 *value)
|
||||
{
|
||||
@@ -189,12 +193,14 @@ static void Color_Write_Value_Handler(uint32_t object_instance,
|
||||
index = object_instance - 1;
|
||||
}
|
||||
if (index < blinkt_led_count()) {
|
||||
color_rgb_from_xy(&red, &green, &blue, value->x_coordinate,
|
||||
value->y_coordinate, brightness_percent);
|
||||
color_rgb_from_xy(
|
||||
&red, &green, &blue, value->x_coordinate, value->y_coordinate,
|
||||
brightness_percent);
|
||||
blinkt_set_pixel(index, red, green, blue);
|
||||
printf("x,y=%0.2f,%0.2f(%.1f%%) RGB[%u]=%u,%u,%u\n",
|
||||
value->x_coordinate, value->y_coordinate, brightness_percent,
|
||||
(unsigned)index, (unsigned)red, (unsigned)green, (unsigned)blue);
|
||||
printf(
|
||||
"x,y=%0.2f,%0.2f(%.1f%%) RGB[%u]=%u,%u,%u\n", value->x_coordinate,
|
||||
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"
|
||||
"Test the Blinkt! RGB LEDs with a cycling pattern.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"%s 9009\n",
|
||||
filename);
|
||||
}
|
||||
@@ -375,12 +382,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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 Device ID: %u\n"
|
||||
"Max APDU: %d\n",
|
||||
|
||||
+44
-33
@@ -63,22 +63,24 @@ static void MyPrintHandler(
|
||||
BACNET_ERROR_CODE error_code,
|
||||
uint32_t first_failed_element_number)
|
||||
{
|
||||
printf("[{\n \"%s\": {\n"
|
||||
printf(
|
||||
"[{\n \"%s\": {\n"
|
||||
" \"object-type\": \"%s\",\n \"object-instance\": %lu,\n"
|
||||
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"",
|
||||
bactext_confirmed_service_name(SERVICE_CONFIRMED_CREATE_OBJECT),
|
||||
bactext_object_type_name(object_type),
|
||||
(unsigned long)object_instance,
|
||||
bactext_object_type_name(object_type), (unsigned long)object_instance,
|
||||
bactext_error_class_name((int)error_class),
|
||||
bactext_error_code_name((int)error_code));
|
||||
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);
|
||||
}
|
||||
printf("\n }\n}]\n");
|
||||
}
|
||||
|
||||
static void MyCreateObjectErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyCreateObjectErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
uint8_t service_choice,
|
||||
uint8_t *service_request,
|
||||
@@ -90,18 +92,19 @@ static void MyCreateObjectErrorHandler(BACNET_ADDRESS *src,
|
||||
(void)service_choice;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
len = create_object_error_ack_service_decode(service_request,
|
||||
service_len, &data);
|
||||
len = create_object_error_ack_service_decode(
|
||||
service_request, service_len, &data);
|
||||
if (len > 0) {
|
||||
MyPrintHandler(data.object_type, data.object_instance,
|
||||
data.error_class, data.error_code,
|
||||
data.first_failed_element_number);
|
||||
MyPrintHandler(
|
||||
data.object_type, data.object_instance, data.error_class,
|
||||
data.error_code, data.first_failed_element_number);
|
||||
}
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyCreateObjectAckHandler(uint8_t *service_request,
|
||||
static void MyCreateObjectAckHandler(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -114,11 +117,13 @@ static void MyCreateObjectAckHandler(uint8_t *service_request,
|
||||
len = create_object_ack_service_decode(
|
||||
service_request, service_len, &data);
|
||||
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);
|
||||
} else {
|
||||
MyPrintHandler(data.object_type, data.object_instance,
|
||||
ERROR_CLASS_SERVICES, ERROR_CODE_SUCCESS, 0);
|
||||
MyPrintHandler(
|
||||
data.object_type, data.object_instance, ERROR_CLASS_SERVICES,
|
||||
ERROR_CODE_SUCCESS, 0);
|
||||
}
|
||||
} else {
|
||||
if (Verbose) {
|
||||
@@ -133,20 +138,21 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
MyPrintHandler(Target_Object_Type, Target_Object_Instance,
|
||||
ERROR_CLASS_SERVICES, abort_convert_to_error_code(abort_reason), 0);
|
||||
MyPrintHandler(
|
||||
Target_Object_Type, Target_Object_Instance, ERROR_CLASS_SERVICES,
|
||||
abort_convert_to_error_code(abort_reason), 0);
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
MyPrintHandler(Target_Object_Type, Target_Object_Instance,
|
||||
ERROR_CLASS_SERVICES,
|
||||
MyPrintHandler(
|
||||
Target_Object_Type, Target_Object_Instance, ERROR_CLASS_SERVICES,
|
||||
reject_convert_to_error_code(reject_reason), 0);
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -207,7 +213,8 @@ static void print_help(const char *filename)
|
||||
"you are creating. For example, if you were writing\n"
|
||||
"Analog Output 2, the object-instance would be 2.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"If you want to CreateObject of an Analog Input 1\n"
|
||||
"send the following command:\n"
|
||||
"%s 123 0 1\n",
|
||||
@@ -275,8 +282,8 @@ int main(int argc, char *argv[])
|
||||
if (target_args == 0) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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",
|
||||
object_instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
@@ -293,8 +300,8 @@ int main(int argc, char *argv[])
|
||||
} else if (target_args == 2) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
@@ -328,7 +335,8 @@ int main(int argc, char *argv[])
|
||||
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||
if (found) {
|
||||
if (Verbose) {
|
||||
printf("Found Device %u in address_cache.\n",
|
||||
printf(
|
||||
"Found Device %u in address_cache.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
} else {
|
||||
@@ -341,16 +349,18 @@ int main(int argc, char *argv[])
|
||||
/* device is bound! */
|
||||
if (Request_Invoke_ID == 0) {
|
||||
if (Verbose) {
|
||||
printf("Sending CreateObject to Device %u.\n",
|
||||
printf(
|
||||
"Sending CreateObject to Device %u.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
Request_Invoke_ID =
|
||||
Send_Create_Object_Request(Target_Device_Object_Instance,
|
||||
Target_Object_Type, Target_Object_Instance);
|
||||
Request_Invoke_ID = Send_Create_Object_Request(
|
||||
Target_Device_Object_Instance, Target_Object_Type,
|
||||
Target_Object_Instance);
|
||||
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||
break;
|
||||
} 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);
|
||||
tsm_free_invoke_id(Request_Invoke_ID);
|
||||
Error_Detected = true;
|
||||
@@ -371,10 +381,11 @@ int main(int argc, char *argv[])
|
||||
mstimer_reset(&maintenance_timer);
|
||||
tsm_timer_milliseconds(mstimer_interval(&maintenance_timer));
|
||||
datalink_maintenance_timer(
|
||||
mstimer_interval(&maintenance_timer)/1000L);
|
||||
mstimer_interval(&maintenance_timer) / 1000L);
|
||||
}
|
||||
if (mstimer_expired(&apdu_timer)) {
|
||||
MyPrintHandler(Target_Object_Type, Target_Object_Instance,
|
||||
MyPrintHandler(
|
||||
Target_Object_Type, Target_Object_Instance,
|
||||
ERROR_CLASS_COMMUNICATION,
|
||||
ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME, 0);
|
||||
Error_Detected = true;
|
||||
|
||||
+10
-6
@@ -46,7 +46,8 @@ static char *Communication_Password = NULL;
|
||||
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -54,7 +55,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
(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));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -70,8 +72,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -103,7 +105,8 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* 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);
|
||||
/* handle the ack coming back */
|
||||
apdu_set_confirmed_simple_ack_handler(
|
||||
@@ -190,7 +193,8 @@ int main(int argc, char *argv[])
|
||||
Communication_Password = argv[4];
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+29
-26
@@ -56,11 +56,11 @@ static bool Error_Detected = false;
|
||||
/* Used for verbose */
|
||||
static bool Verbose = false;
|
||||
|
||||
static void MyPrintHandler(
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
static void
|
||||
MyPrintHandler(BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
printf("[{\n \"%s\": {\n"
|
||||
printf(
|
||||
"[{\n \"%s\": {\n"
|
||||
" \"object-type\": \"%s\",\n \"object-instance\": %lu,\n"
|
||||
" \"error-class\": \"%s\",\n \"error-code\": \"%s\"\n }\n}]\n",
|
||||
bactext_confirmed_service_name(SERVICE_CONFIRMED_DELETE_OBJECT),
|
||||
@@ -70,7 +70,8 @@ static void MyPrintHandler(
|
||||
bactext_error_code_name((int)error_code));
|
||||
}
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -82,8 +83,7 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
}
|
||||
}
|
||||
|
||||
static void MySimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void MySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -97,19 +97,19 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
MyPrintHandler(ERROR_CLASS_SERVICES,
|
||||
abort_convert_to_error_code(abort_reason));
|
||||
MyPrintHandler(
|
||||
ERROR_CLASS_SERVICES, abort_convert_to_error_code(abort_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
MyPrintHandler(ERROR_CLASS_SERVICES,
|
||||
reject_convert_to_error_code(reject_reason));
|
||||
MyPrintHandler(
|
||||
ERROR_CLASS_SERVICES, reject_convert_to_error_code(reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
@@ -138,8 +138,7 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
static void print_usage(const char *filename)
|
||||
{
|
||||
printf("Usage: %s device-instance object-type object-instance\n",
|
||||
filename);
|
||||
printf("Usage: %s device-instance object-type object-instance\n", filename);
|
||||
printf(" [--dnet][--dadr][--mac]\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"
|
||||
"Analog Output 2, the object-instance would be 2.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"If you want to DeleteObject an Analog Input 1\n"
|
||||
"send the following command:\n"
|
||||
"%s 123 0 1\n",
|
||||
@@ -236,8 +236,8 @@ int main(int argc, char *argv[])
|
||||
if (target_args == 0) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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",
|
||||
object_instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
@@ -254,8 +254,8 @@ int main(int argc, char *argv[])
|
||||
} else if (target_args == 2) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
@@ -289,7 +289,8 @@ int main(int argc, char *argv[])
|
||||
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||
if (found) {
|
||||
if (Verbose) {
|
||||
printf("Found Device %u in address_cache.\n",
|
||||
printf(
|
||||
"Found Device %u in address_cache.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
} else {
|
||||
@@ -302,7 +303,8 @@ int main(int argc, char *argv[])
|
||||
/* device is bound! */
|
||||
if (Request_Invoke_ID == 0) {
|
||||
if (Verbose) {
|
||||
printf("Sending DeleteObject to Device %u.\n",
|
||||
printf(
|
||||
"Sending DeleteObject to Device %u.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
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)) {
|
||||
break;
|
||||
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
|
||||
MyPrintHandler(ERROR_CLASS_COMMUNICATION,
|
||||
ERROR_CODE_ABORT_TSM_TIMEOUT);
|
||||
MyPrintHandler(
|
||||
ERROR_CLASS_COMMUNICATION, ERROR_CODE_ABORT_TSM_TIMEOUT);
|
||||
tsm_free_invoke_id(Request_Invoke_ID);
|
||||
Error_Detected = true;
|
||||
/* abort */
|
||||
@@ -332,10 +334,11 @@ int main(int argc, char *argv[])
|
||||
mstimer_reset(&maintenance_timer);
|
||||
tsm_timer_milliseconds(mstimer_interval(&maintenance_timer));
|
||||
datalink_maintenance_timer(
|
||||
mstimer_interval(&maintenance_timer)/1000L);
|
||||
mstimer_interval(&maintenance_timer) / 1000L);
|
||||
}
|
||||
if (mstimer_expired(&apdu_timer)) {
|
||||
MyPrintHandler(ERROR_CLASS_COMMUNICATION,
|
||||
MyPrintHandler(
|
||||
ERROR_CLASS_COMMUNICATION,
|
||||
ERROR_CODE_ABORT_APPLICATION_EXCEEDED_REPLY_TIME);
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
@@ -70,16 +70,20 @@ typedef enum {
|
||||
/** Initial state to establish a binding with the target device. */
|
||||
INITIAL_BINDING,
|
||||
/** 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. */
|
||||
GET_ALL_REQUEST, GET_ALL_RESPONSE,
|
||||
GET_ALL_REQUEST,
|
||||
GET_ALL_RESPONSE,
|
||||
/** 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. */
|
||||
GET_PROPERTY_REQUEST, GET_PROPERTY_RESPONSE,
|
||||
GET_PROPERTY_REQUEST,
|
||||
GET_PROPERTY_RESPONSE,
|
||||
/** Done with this Object; move onto the next. */
|
||||
NEXT_OBJECT
|
||||
} EPICS_STATES;
|
||||
|
||||
|
||||
#endif /* BACEPICS_H_ */
|
||||
|
||||
+84
-53
@@ -11,7 +11,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h> /* for time */
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
@@ -117,10 +117,12 @@ struct property_value_list_t {
|
||||
BACNET_APPLICATION_DATA_VALUE *value;
|
||||
};
|
||||
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_PROTOCOL_SERVICES_SUPPORTED, NULL },
|
||||
{ PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL }, { PROP_DESCRIPTION, NULL },
|
||||
{ PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL },
|
||||
{ PROP_DESCRIPTION, NULL },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
@@ -161,7 +163,8 @@ static bool Optional_Properties = false;
|
||||
#define PRINT_ERRORS 1
|
||||
#endif
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -170,7 +173,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
#if PRINT_ERRORS
|
||||
if (ShowValues) {
|
||||
fprintf(stderr, "-- BACnet Error: %s: %s\n",
|
||||
fprintf(
|
||||
stderr, "-- BACnet Error: %s: %s\n",
|
||||
bactext_error_class_name(error_class),
|
||||
bactext_error_code_name(error_code));
|
||||
}
|
||||
@@ -190,7 +194,8 @@ static void MyAbortHandler(
|
||||
#if PRINT_ERRORS
|
||||
/* It is normal for this to fail, so don't print. */
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
@@ -205,14 +210,15 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
#if PRINT_ERRORS
|
||||
if (ShowValues) {
|
||||
fprintf(stderr, "BACnet Reject: %s\n",
|
||||
fprintf(
|
||||
stderr, "BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name(reject_reason));
|
||||
}
|
||||
#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,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -243,7 +250,8 @@ static void MyReadPropertyAckHandler(uint8_t *service_request,
|
||||
service_request, service_len, rp_data);
|
||||
}
|
||||
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));
|
||||
Read_Property_Multiple_Data.rpm_data = rp_data;
|
||||
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,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -272,7 +281,8 @@ static void MyReadPropertyMultipleAckHandler(uint8_t *service_request,
|
||||
service_request, service_len, rpm_data);
|
||||
}
|
||||
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));
|
||||
Read_Property_Multiple_Data.rpm_data = rpm_data;
|
||||
Read_Property_Multiple_Data.new_data = true;
|
||||
@@ -376,7 +386,8 @@ static bool PrettyPrintPropertyValue(
|
||||
len = bitstring_bits_used(&value->type.Bit_String);
|
||||
fprintf(stream, "( \n ");
|
||||
for (i = 0; i < len; i++) {
|
||||
fprintf(stream, "%s",
|
||||
fprintf(
|
||||
stream, "%s",
|
||||
bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F");
|
||||
if (i < len - 1) {
|
||||
fprintf(stream, ",");
|
||||
@@ -395,7 +406,8 @@ static bool PrettyPrintPropertyValue(
|
||||
stream, " %s,", bactext_object_type_name(j));
|
||||
} else {
|
||||
/* PROP_PROTOCOL_SERVICES_SUPPORTED */
|
||||
fprintf(stream, " %s,",
|
||||
fprintf(
|
||||
stream, " %s,",
|
||||
protocol_services_supported_text(j));
|
||||
}
|
||||
} else { /* not supported */
|
||||
@@ -412,7 +424,8 @@ static bool PrettyPrintPropertyValue(
|
||||
* clearer, international form. */
|
||||
strncpy(short_month, bactext_month_name(value->type.Date.month), 3);
|
||||
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,
|
||||
(unsigned)value->type.Date.wday);
|
||||
} else if (value != NULL) {
|
||||
@@ -436,7 +449,8 @@ static bool PrettyPrintPropertyValue(
|
||||
* @param rpm_property [in] Points to structure holding the Property,
|
||||
* Value, and Error information.
|
||||
*/
|
||||
static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||
static void PrintReadPropertyData(
|
||||
BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_REFERENCE *rpm_property)
|
||||
{
|
||||
@@ -452,7 +466,8 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||
value = rpm_property->value;
|
||||
if (value == NULL) {
|
||||
/* 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_code_name((int)rpm_property->error.error_code));
|
||||
return;
|
||||
@@ -516,7 +531,8 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
assert(Walked_List_Index ==
|
||||
assert(
|
||||
Walked_List_Index ==
|
||||
(uint32_t)rpm_property->propertyArrayIndex);
|
||||
}
|
||||
} else {
|
||||
@@ -553,13 +569,14 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||
}
|
||||
/* Store the object list so we can interrogate
|
||||
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);
|
||||
/* We don't have anything to put in the data pointer
|
||||
* yet, so just leave it null. The key is Key here. */
|
||||
Keylist_Data_Add(Object_List, object_list_element, NULL);
|
||||
} else if (rpm_property->propertyIdentifier ==
|
||||
PROP_STATE_TEXT) {
|
||||
} else if (
|
||||
rpm_property->propertyIdentifier == PROP_STATE_TEXT) {
|
||||
/* Make sure it fits within 31 chars for original VTS3
|
||||
* limitation. If longer, take first 15 dash, and last 15
|
||||
* chars. */
|
||||
@@ -567,14 +584,15 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||
int iLast15idx =
|
||||
value->type.Character_String.length - 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],
|
||||
15);
|
||||
value->type.Character_String.value[31] = 0;
|
||||
value->type.Character_String.length = 31;
|
||||
}
|
||||
} else if (rpm_property->propertyIdentifier ==
|
||||
PROP_SUBORDINATE_LIST) {
|
||||
} else if (
|
||||
rpm_property->propertyIdentifier == PROP_SUBORDINATE_LIST) {
|
||||
if (value->tag !=
|
||||
BACNET_APPLICATION_TAG_DEVICE_OBJECT_REFERENCE) {
|
||||
break;
|
||||
@@ -648,8 +666,8 @@ static void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
|
||||
/* Closing brace for this multi-valued array */
|
||||
fprintf(stdout, " }");
|
||||
}
|
||||
if (property_list_writable_member(object_type,
|
||||
rpm_property->propertyIdentifier)) {
|
||||
if (property_list_writable_member(
|
||||
object_type, rpm_property->propertyIdentifier)) {
|
||||
fprintf(stdout, " Writable");
|
||||
}
|
||||
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
|
||||
* of the property list.
|
||||
*/
|
||||
static uint8_t Read_Properties(
|
||||
uint32_t device_instance, const BACNET_OBJECT_ID *pMyObject)
|
||||
static uint8_t
|
||||
Read_Properties(uint32_t device_instance, const BACNET_OBJECT_ID *pMyObject)
|
||||
{
|
||||
uint8_t invoke_id = 0;
|
||||
struct special_property_list_t PropertyListStruct;
|
||||
@@ -775,8 +793,9 @@ static uint8_t Read_Properties(
|
||||
break;
|
||||
}
|
||||
}
|
||||
invoke_id = Send_Read_Property_Request(device_instance, pMyObject->type,
|
||||
pMyObject->instance, prop, array_index);
|
||||
invoke_id = Send_Read_Property_Request(
|
||||
device_instance, pMyObject->type, pMyObject->instance, prop,
|
||||
array_index);
|
||||
}
|
||||
|
||||
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
|
||||
* singly process the list of Properties.
|
||||
*/
|
||||
static EPICS_STATES ProcessRPMData(
|
||||
BACNET_READ_ACCESS_DATA *rpm_data, EPICS_STATES state)
|
||||
static EPICS_STATES
|
||||
ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data, EPICS_STATES state)
|
||||
{
|
||||
BACNET_READ_ACCESS_DATA *old_rpm_data;
|
||||
BACNET_PROPERTY_REFERENCE *rpm_property;
|
||||
@@ -845,8 +864,9 @@ static EPICS_STATES ProcessRPMData(
|
||||
fprintf(stdout, " ");
|
||||
Print_Property_Identifier(rpm_property->propertyIdentifier);
|
||||
fprintf(stdout, ": ");
|
||||
PrintReadPropertyData(rpm_data->object_type,
|
||||
rpm_data->object_instance, rpm_property);
|
||||
PrintReadPropertyData(
|
||||
rpm_data->object_type, rpm_data->object_instance,
|
||||
rpm_property);
|
||||
}
|
||||
old_rpm_property = rpm_property;
|
||||
rpm_property = rpm_property->next;
|
||||
@@ -886,7 +906,8 @@ static EPICS_STATES ProcessRPMData(
|
||||
|
||||
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",
|
||||
filename);
|
||||
printf(" [--version][--help]\n");
|
||||
@@ -984,8 +1005,8 @@ static int CheckCommandLineArgs(int argc, char *argv[])
|
||||
int count;
|
||||
/* loop counter */
|
||||
unsigned j;
|
||||
count =
|
||||
sscanf(argv[i], "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0],
|
||||
count = sscanf(
|
||||
argv[i], "%2x:%2x:%2x:%2x:%2x:%2x", &mac[0],
|
||||
&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
|
||||
if (count == 6) { /* success */
|
||||
Target_Address.mac_len = count;
|
||||
@@ -1011,8 +1032,8 @@ static int CheckCommandLineArgs(int argc, char *argv[])
|
||||
/* decode the Target Device Instance parameter */
|
||||
Target_Device_Object_Instance = strtol(anArg, NULL, 0);
|
||||
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stdout,
|
||||
"Error: device-instance=%u - not greater than %u\n",
|
||||
fprintf(
|
||||
stdout, "Error: device-instance=%u - not greater than %u\n",
|
||||
Target_Device_Object_Instance, BACNET_MAX_INSTANCE);
|
||||
print_usage(filename);
|
||||
exit(0);
|
||||
@@ -1045,7 +1066,8 @@ static void PrintHeading(void)
|
||||
value = object_property_value(PROP_VENDOR_NAME);
|
||||
if ((value != NULL) &&
|
||||
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||
printf("Vendor Name: \"%s\"\n",
|
||||
printf(
|
||||
"Vendor Name: \"%s\"\n",
|
||||
characterstring_value(&value->type.Character_String));
|
||||
} else {
|
||||
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 */
|
||||
if ((value != NULL) &&
|
||||
(value->tag == BACNET_APPLICATION_TAG_CHARACTER_STRING)) {
|
||||
printf("Product Name: \"%s\"\n",
|
||||
printf(
|
||||
"Product Name: \"%s\"\n",
|
||||
characterstring_value(&value->type.Character_String));
|
||||
printf("Product Model Number: \"%s\"\n",
|
||||
printf(
|
||||
"Product Model Number: \"%s\"\n",
|
||||
characterstring_value(&value->type.Character_String));
|
||||
} else {
|
||||
printf("Product Name: \"your product name here\"\n");
|
||||
@@ -1067,7 +1091,8 @@ static void PrintHeading(void)
|
||||
value = object_property_value(PROP_DESCRIPTION);
|
||||
if ((value != NULL) &&
|
||||
(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));
|
||||
} else {
|
||||
printf("Product Description: "
|
||||
@@ -1093,8 +1118,9 @@ static void PrintHeading(void)
|
||||
printf("-- DM-UTC-B\n");
|
||||
#ifdef BAC_ROUTING
|
||||
/* 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");
|
||||
}
|
||||
#endif
|
||||
printf("}\n\n");
|
||||
printf("BACnet Standard Application Services Supported:\n");
|
||||
@@ -1340,7 +1366,7 @@ int main(int argc, char *argv[])
|
||||
address_init();
|
||||
Init_Service_Handlers();
|
||||
dlenv_init();
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
/* Internationalized programs must call setlocale()
|
||||
* to initiate a specific language operation.
|
||||
* This can be done by calling setlocale() as follows.
|
||||
@@ -1371,8 +1397,8 @@ int main(int argc, char *argv[])
|
||||
if (Target_Address.net > 0) {
|
||||
/* We specified a DNET; call Who-Is to find the full
|
||||
* routed path to this Device */
|
||||
Send_WhoIs_Remote(&Target_Address,
|
||||
Target_Device_Object_Instance,
|
||||
Send_WhoIs_Remote(
|
||||
&Target_Address, Target_Device_Object_Instance,
|
||||
Target_Device_Object_Instance);
|
||||
|
||||
} else {
|
||||
@@ -1418,7 +1444,8 @@ int main(int argc, char *argv[])
|
||||
/* increment timer - exit if timed out */
|
||||
elapsed_seconds += (current_seconds - last_seconds);
|
||||
if (elapsed_seconds > timeout_seconds) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"\rError: Unable to bind to %u"
|
||||
" after waiting %ld seconds.\n",
|
||||
Target_Device_Object_Instance,
|
||||
@@ -1516,7 +1543,8 @@ int main(int argc, char *argv[])
|
||||
/* Was it because the Device can't do RPM? */
|
||||
Has_RPM = false;
|
||||
myState = GET_PROPERTY_REQUEST;
|
||||
} else if (Last_Error_Code ==
|
||||
} else if (
|
||||
Last_Error_Code ==
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) {
|
||||
myState = GET_PROPERTY_REQUEST;
|
||||
StartNextObject(rpm_object, &myObject);
|
||||
@@ -1684,10 +1712,12 @@ int main(int argc, char *argv[])
|
||||
do {
|
||||
Object_List_Index++;
|
||||
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.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) {
|
||||
continue;
|
||||
}
|
||||
@@ -1732,7 +1762,8 @@ int main(int argc, char *argv[])
|
||||
/* increment timer - exit if timed out */
|
||||
elapsed_seconds += (current_seconds - last_seconds);
|
||||
if (elapsed_seconds > timeout_seconds) {
|
||||
fprintf(stderr, "\rError: APDU Timeout! (%lds)\n",
|
||||
fprintf(
|
||||
stderr, "\rError: APDU Timeout! (%lds)\n",
|
||||
(long int)elapsed_seconds);
|
||||
break;
|
||||
}
|
||||
|
||||
+11
-7
@@ -47,8 +47,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
(void)src;
|
||||
(void)invoke_id;
|
||||
@@ -77,7 +77,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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);
|
||||
printf(" [--dnet][--dadr][--mac]\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 Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
|
||||
printf("\n");
|
||||
printf("--dnet N\n"
|
||||
printf(
|
||||
"--dnet N\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"
|
||||
"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 Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
|
||||
printf("\n");
|
||||
printf("error-class:\n"
|
||||
printf(
|
||||
"error-class:\n"
|
||||
" number from 0 to 65535\n"
|
||||
"error-code:\n"
|
||||
" number from 0 to 65535\n"
|
||||
@@ -219,8 +222,9 @@ int main(int argc, char *argv[])
|
||||
dlenv_init();
|
||||
atexit(datalink_cleanup);
|
||||
/* send the request */
|
||||
Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
|
||||
Target_Service, Target_Error_Class, Target_Error_Code);
|
||||
Send_Error_To_Network(
|
||||
&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID, Target_Service,
|
||||
Target_Error_Class, Target_Error_Code);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+32
-24
@@ -50,14 +50,16 @@ static bool Error_Detected = false;
|
||||
* @param error_class [in] the error class
|
||||
* @param error_code [in] the error code
|
||||
*/
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -89,12 +91,13 @@ static void MyAbortHandler(
|
||||
* @param invoke_id [in] the invokeID from the rejected message
|
||||
* @param reject_reason [in] the reason for the rejection
|
||||
*/
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -105,8 +108,8 @@ static void MyRejectHandler(
|
||||
* @param src [in] BACNET_ADDRESS of the source of the message
|
||||
* @param invoke_id [in] the invokeID from the rejected message
|
||||
*/
|
||||
static void MyWritePropertySimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -143,7 +146,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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"
|
||||
" sequence-number notification-class priority message-text\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)
|
||||
{
|
||||
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"
|
||||
"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"
|
||||
@@ -170,7 +175,8 @@ static void print_help(const char *filename)
|
||||
printf("initiating-device-id: the BACnet Device Object Instance number\n"
|
||||
"that initiated the ConfirmedEventNotification service request.\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"
|
||||
"as defined in the BACnet specification, or as the integer value.\n");
|
||||
printf("\n");
|
||||
@@ -462,8 +468,8 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType == EVENT_OUT_OF_RANGE) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_CHANGE_OF_LIFE_SAFETY) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_CHANGE_OF_LIFE_SAFETY) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType == EVENT_EXTENDED) {
|
||||
/* FIXME: add event type parameters */
|
||||
@@ -477,26 +483,27 @@ int main(int argc, char *argv[])
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType == EVENT_SIGNED_OUT_OF_RANGE) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_UNSIGNED_OUT_OF_RANGE) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_UNSIGNED_OUT_OF_RANGE) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_CHANGE_OF_CHARACTERSTRING) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_CHANGE_OF_CHARACTERSTRING) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_CHANGE_OF_STATUS_FLAGS) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_CHANGE_OF_STATUS_FLAGS) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_CHANGE_OF_RELIABILITY) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_CHANGE_OF_RELIABILITY) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType == EVENT_NONE) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_CHANGE_OF_DISCRETE_VALUE) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_CHANGE_OF_DISCRETE_VALUE) {
|
||||
/* FIXME: add event type parameters */
|
||||
} else if (event_data.eventType == EVENT_CHANGE_OF_TIMER) {
|
||||
/* 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)) {
|
||||
/* Enumerated values 64-65535 may
|
||||
be used by others subject to
|
||||
@@ -544,7 +551,8 @@ int main(int argc, char *argv[])
|
||||
dest.len = 0;
|
||||
}
|
||||
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);
|
||||
}
|
||||
/* setup my info */
|
||||
|
||||
+37
-22
@@ -40,50 +40,66 @@
|
||||
|
||||
static void Init_Service_Handlers()
|
||||
{
|
||||
|
||||
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_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_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||
apdu_set_confirmed_handler(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_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||
apdu_set_confirmed_handler(
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FIXME: This is a hack to get things linking correctly
|
||||
*/
|
||||
extern int cov_subscribe(void) {
|
||||
extern int cov_subscribe(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Value_List_Supported(void) {
|
||||
extern int Device_Value_List_Supported(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Encode_RR_payload(void) {
|
||||
extern int Encode_RR_payload(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Objects_RR_Info(void) {
|
||||
extern int Device_Objects_RR_Info(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Write_Property(void) {
|
||||
extern int Device_Write_Property(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Reinitialize(void) {
|
||||
extern int Device_Reinitialize(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
BACNET_ADDRESS src = { 0 };
|
||||
@@ -99,5 +115,4 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
+66
-42
@@ -39,87 +39,111 @@
|
||||
// Pull in all of this...
|
||||
#include "../router-mstp/main.c"
|
||||
|
||||
static void Init_Service_Handlers(void) {
|
||||
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is_unicast);
|
||||
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_HAS, handler_who_has);
|
||||
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_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||
apdu_set_confirmed_handler(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_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_RANGE, handler_read_range);
|
||||
apdu_set_confirmed_handler(
|
||||
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_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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FIXME: This is a hack to get things linking correctly
|
||||
*/
|
||||
extern int cov_subscribe(void) {
|
||||
extern int cov_subscribe(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Value_List_Supported(void) {
|
||||
extern int Device_Value_List_Supported(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Encode_RR_payload(void) {
|
||||
extern int Encode_RR_payload(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Objects_RR_Info(void) {
|
||||
extern int Device_Objects_RR_Info(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Write_Property(void) {
|
||||
extern int Device_Write_Property(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
extern int Device_Reinitialize(void) {
|
||||
extern int Device_Reinitialize(void)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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,
|
||||
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) {
|
||||
BACNET_PROPERTY_VALUE *value_list)
|
||||
{
|
||||
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 };
|
||||
|
||||
Init_Service_Handlers();
|
||||
|
||||
/* process fuzz input*/
|
||||
if (size>0 && size<=0xffff) {
|
||||
if (size > 0 && size <= 0xffff) {
|
||||
my_routing_npdu_handler(BIP_Net, &src, data, (uint16_t)size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
+5
-4
@@ -188,7 +188,8 @@ static void Init_Service_Handlers(uint32_t first_object_instance)
|
||||
apdu_set_unconfirmed_handler(
|
||||
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
@@ -225,12 +226,12 @@ int main(int argc, char *argv[])
|
||||
if ((first_object_instance == 0) ||
|
||||
(first_object_instance > BACNET_MAX_INSTANCE)) {
|
||||
printf("Error: Invalid Object Instance %s \n", argv[1]);
|
||||
printf(
|
||||
"Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE);
|
||||
printf("Provide a number from 1 to %ul \n", BACNET_MAX_INSTANCE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf("BACnet Router Demo\n"
|
||||
printf(
|
||||
"BACnet Router Demo\n"
|
||||
"BACnet Stack Version %s\n"
|
||||
"BACnet Device ID: %u\n"
|
||||
"Max APDU: %d\n"
|
||||
|
||||
+19
-11
@@ -54,14 +54,16 @@ static bool Recieved_Ack = false;
|
||||
static bool More_Events = false;
|
||||
static BACNET_OBJECT_ID LastReceivedObjectIdentifier;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -74,18 +76,20 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Abort: %s\r\n",
|
||||
printf(
|
||||
"BACnet Abort: %s\r\n",
|
||||
bactext_abort_reason_name((int)abort_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\r\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\r\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -101,7 +105,8 @@ static void MyRejectHandler(
|
||||
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||
* 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,
|
||||
BACNET_ADDRESS *src,
|
||||
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];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (service_data->invoke_id == Request_Invoke_ID) {
|
||||
len = getevent_ack_decode_service_request(
|
||||
service_request, service_len, &data[0], &More_Events);
|
||||
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n",
|
||||
len, More_Events);
|
||||
printf(
|
||||
"Decode of Ack returned length %i. MoreEvents flag was %i \n", len,
|
||||
More_Events);
|
||||
if (len > 0) {
|
||||
ge_ack_print_data(&(data[0]), Target_Device_Object_Instance);
|
||||
if (More_Events) {
|
||||
@@ -162,7 +169,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
static int print_help(const char *exe_name)
|
||||
{
|
||||
printf("Usage:\n"
|
||||
printf(
|
||||
"Usage:\n"
|
||||
"\n"
|
||||
"%s device-instance [--help]\n"
|
||||
"\n"
|
||||
|
||||
+11
-7
@@ -50,8 +50,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
(void)src;
|
||||
(void)invoke_id;
|
||||
@@ -80,7 +80,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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);
|
||||
printf(" [--dnet][--dadr][--mac]\n");
|
||||
printf(" [--version][--help]\n");
|
||||
@@ -101,7 +102,8 @@ static void print_help(const char *filename)
|
||||
"and 65535 is network broadcast.\n");
|
||||
printf("\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"
|
||||
"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");
|
||||
@@ -130,7 +132,8 @@ static void print_help(const char *filename)
|
||||
printf("segmentation:\n"
|
||||
"BACnet Segmentation 0=both, 1=transmit, 2=receive, 3=none\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"
|
||||
"%s 1234 260 480\n",
|
||||
filename);
|
||||
@@ -258,8 +261,9 @@ int main(int argc, char *argv[])
|
||||
atexit(datalink_cleanup);
|
||||
/* send the request */
|
||||
do {
|
||||
Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU,
|
||||
Target_Segmentation, Target_Vendor_ID);
|
||||
Send_I_Am_To_Network(
|
||||
&dest, Target_Device_ID, Target_Max_APDU, Target_Segmentation,
|
||||
Target_Vendor_ID);
|
||||
if (repeat_forever || retry_count) {
|
||||
/* returns 0 bytes on timeout */
|
||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||
|
||||
@@ -46,8 +46,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -83,7 +83,8 @@ static void print_usage(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"
|
||||
"\nDNET:\n"
|
||||
"BACnet destination network number 0-65534\n"
|
||||
@@ -136,7 +137,8 @@ int main(int argc, char *argv[])
|
||||
Target_Router_Networks[arg_count] = -1;
|
||||
/* invalid DNET? */
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+19
-13
@@ -59,8 +59,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -69,7 +69,8 @@ static void MyRejectHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void My_Router_Handler(BACNET_ADDRESS *src,
|
||||
static void My_Router_Handler(
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *npdu, /* PDU data */
|
||||
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 */
|
||||
uint16_t pdu_len)
|
||||
{ /* 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);
|
||||
if (npdu_data.network_layer_message) {
|
||||
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));
|
||||
}
|
||||
} 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) {
|
||||
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
|
||||
} else {
|
||||
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
debug_printf(
|
||||
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
npdu_data.protocol_version);
|
||||
}
|
||||
}
|
||||
@@ -219,11 +223,11 @@ static void print_usage(const char *filename)
|
||||
|
||||
static void print_help(const char *filename)
|
||||
{
|
||||
printf(
|
||||
"Send BACnet Initialize-Routing-Table message to a network\n"
|
||||
printf("Send BACnet Initialize-Routing-Table message to a network\n"
|
||||
"and wait for responses. Displays their network information.\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"
|
||||
"DNET ID Len Info:\n"
|
||||
"Port-info data:\n"
|
||||
@@ -247,8 +251,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
int index = 0;
|
||||
|
||||
if (argc > 0) {
|
||||
count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &port);
|
||||
count = sscanf(
|
||||
argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2], &mac[3],
|
||||
&port);
|
||||
if (count == 5) {
|
||||
dst->mac_len = 6;
|
||||
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);
|
||||
} else {
|
||||
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
|
||||
&mac[2], &mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
dst->mac_len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
|
||||
+78
-67
@@ -36,19 +36,19 @@
|
||||
#define DLT_BACNET_MS_TP (165)
|
||||
/* local min/max macros */
|
||||
#ifndef max
|
||||
#define max(a,b) \
|
||||
({ \
|
||||
__typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
#define max(a, b) \
|
||||
({ \
|
||||
__typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a > _b ? _a : _b; \
|
||||
})
|
||||
})
|
||||
|
||||
#define min(a,b) \
|
||||
({ \
|
||||
__typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
#define min(a, b) \
|
||||
({ \
|
||||
__typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a < _b ? _a : _b; \
|
||||
})
|
||||
})
|
||||
#endif
|
||||
|
||||
#define MSTP_HEADER_MAX (2 + 1 + 1 + 1 + 2 + 1)
|
||||
@@ -121,8 +121,8 @@ struct mstp_statistics {
|
||||
static struct mstp_statistics MSTP_Statistics[MAX_MSTP_DEVICES];
|
||||
static uint32_t Invalid_Frame_Count;
|
||||
|
||||
static uint32_t timeval_diff_ms(
|
||||
const struct timeval *old, const struct timeval *now)
|
||||
static uint32_t
|
||||
timeval_diff_ms(const struct timeval *old, const struct timeval *now)
|
||||
{
|
||||
uint32_t ms = 0;
|
||||
|
||||
@@ -133,8 +133,7 @@ static uint32_t timeval_diff_ms(
|
||||
return ms;
|
||||
}
|
||||
|
||||
static void mstp_monitor_i_am(
|
||||
uint8_t mac, const uint8_t *pdu, uint16_t pdu_len)
|
||||
static void mstp_monitor_i_am(uint8_t mac, const uint8_t *pdu, uint16_t pdu_len)
|
||||
{
|
||||
BACNET_ADDRESS src = { 0 };
|
||||
BACNET_ADDRESS dest = { 0 };
|
||||
@@ -173,8 +172,7 @@ static void mstp_monitor_i_am(
|
||||
}
|
||||
|
||||
static void packet_statistics(
|
||||
const struct timeval *tv,
|
||||
const struct mstp_port_struct_t *mstp_port)
|
||||
const struct timeval *tv, const struct mstp_port_struct_t *mstp_port)
|
||||
{
|
||||
static struct timeval old_tv = { 0 };
|
||||
static uint8_t old_frame = 255;
|
||||
@@ -211,8 +209,8 @@ static void packet_statistics(
|
||||
MSTP_Statistics[src].token_reply = delta;
|
||||
}
|
||||
}
|
||||
} else if ((old_frame == FRAME_TYPE_POLL_FOR_MASTER) &&
|
||||
(old_src == src)) {
|
||||
} else if (
|
||||
(old_frame == FRAME_TYPE_POLL_FOR_MASTER) && (old_src == src)) {
|
||||
/* Tusage_timeout */
|
||||
delta = timeval_diff_ms(&old_tv, tv);
|
||||
if (delta > MSTP_Statistics[src].tusage_timeout) {
|
||||
@@ -314,7 +312,8 @@ static void packet_statistics_print(void)
|
||||
|
||||
fprintf(stdout, "\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");
|
||||
fprintf(stdout, "\n");
|
||||
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
|
||||
@@ -324,17 +323,20 @@ static void packet_statistics_print(void)
|
||||
node_count++;
|
||||
fprintf(stdout, "%-8u", i);
|
||||
if (MSTP_Statistics[i].device_id <= 4194303) {
|
||||
fprintf(stdout, "%-8lu",
|
||||
fprintf(
|
||||
stdout, "%-8lu",
|
||||
(long unsigned int)MSTP_Statistics[i].device_id);
|
||||
} else {
|
||||
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].pfm_count,
|
||||
(long unsigned int)MSTP_Statistics[i].rpfm_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].dner_count,
|
||||
(long unsigned int)MSTP_Statistics[i].test_request_count,
|
||||
@@ -346,9 +348,10 @@ static void packet_statistics_print(void)
|
||||
node_count = 0;
|
||||
fprintf(stdout, "\n");
|
||||
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n");
|
||||
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC",
|
||||
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm",
|
||||
"Tder", "Tpostpd");
|
||||
fprintf(
|
||||
stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "MaxMstr",
|
||||
"Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm", "Tder",
|
||||
"Tpostpd");
|
||||
fprintf(stdout, "\n");
|
||||
for (i = 0; i < MAX_MSTP_DEVICES; i++) {
|
||||
/* 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 +
|
||||
MSTP_Statistics[i].ooo_token_count;
|
||||
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].token_retries,
|
||||
(long unsigned int)MSTP_Statistics[i].npoll, self_or_ooo_count,
|
||||
(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].pfm_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, "Invalid Frame Count: %lu\n",
|
||||
fprintf(
|
||||
stdout, "Invalid Frame Count: %lu\n",
|
||||
(long unsigned int)Invalid_Frame_Count);
|
||||
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 */
|
||||
/* Return: amount of PDU data */
|
||||
uint16_t MSTP_Get_Send(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void)mstp_port;
|
||||
(void)timeout;
|
||||
@@ -426,7 +431,7 @@ uint16_t MSTP_Get_Send(
|
||||
*/
|
||||
void MSTP_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port,
|
||||
const uint8_t * buffer,
|
||||
const uint8_t *buffer,
|
||||
uint16_t nbytes)
|
||||
{
|
||||
(void)mstp_port;
|
||||
@@ -434,8 +439,7 @@ void MSTP_Send_Frame(
|
||||
(void)nbytes;
|
||||
}
|
||||
|
||||
uint16_t MSTP_Get_Reply(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void)mstp_port;
|
||||
(void)timeout;
|
||||
@@ -454,8 +458,9 @@ static void named_pipe_create(const char *pipe_name)
|
||||
/* create the pipe */
|
||||
while (Pipe_Handle == INVALID_HANDLE_VALUE) {
|
||||
/* use CreateFile rather than CreateNamedPipe */
|
||||
Pipe_Handle = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
Pipe_Handle = CreateFile(
|
||||
pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0,
|
||||
NULL);
|
||||
if (Pipe_Handle != INVALID_HANDLE_VALUE) {
|
||||
break;
|
||||
}
|
||||
@@ -477,7 +482,8 @@ static size_t data_write(const void *ptr, size_t size, size_t nitems)
|
||||
DWORD cbWritten = 0;
|
||||
|
||||
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 */
|
||||
size * nitems, /* number of bytes to write */
|
||||
&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;
|
||||
}
|
||||
|
||||
static size_t data_write_header(
|
||||
const void *ptr, size_t size, size_t nitems)
|
||||
static size_t data_write_header(const void *ptr, size_t size, size_t nitems)
|
||||
{
|
||||
size_t written = 0;
|
||||
DWORD cbWritten = 0;
|
||||
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 */
|
||||
size * nitems, /* number of bytes to write */
|
||||
&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;
|
||||
}
|
||||
|
||||
static size_t data_write_header(
|
||||
const void *ptr, size_t size, size_t nitems)
|
||||
static size_t data_write_header(const void *ptr, size_t size, size_t nitems)
|
||||
{
|
||||
ssize_t written = 0;
|
||||
|
||||
@@ -573,14 +578,16 @@ static void filename_create_new(void)
|
||||
}
|
||||
File_Handle = 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)btime.min, (int)btime.sec);
|
||||
File_Handle = fopen(filename, "wb");
|
||||
if (File_Handle) {
|
||||
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
|
||||
} else {
|
||||
fprintf(stderr, "mstpcap: failed to open %s: %s\n", filename,
|
||||
fprintf(
|
||||
stderr, "mstpcap: failed to open %s: %s\n", filename,
|
||||
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 */
|
||||
|
||||
/* create a new file. */
|
||||
(void)data_write_header(
|
||||
&magic_number, sizeof(magic_number), 1);
|
||||
(void)data_write_header(
|
||||
&version_major, sizeof(version_major), 1);
|
||||
(void)data_write_header(
|
||||
&version_minor, sizeof(version_minor), 1);
|
||||
(void)data_write_header(&magic_number, sizeof(magic_number), 1);
|
||||
(void)data_write_header(&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(&sigfigs, sizeof(sigfigs), 1);
|
||||
(void)data_write_header(&snaplen, sizeof(snaplen), 1);
|
||||
@@ -610,8 +614,8 @@ static void write_global_header(void)
|
||||
fflush(File_Handle);
|
||||
}
|
||||
|
||||
static void write_received_packet(
|
||||
struct mstp_port_struct_t *mstp_port, size_t header_len)
|
||||
static void
|
||||
write_received_packet(struct mstp_port_struct_t *mstp_port, size_t header_len)
|
||||
{
|
||||
uint32_t ts_sec = 0; /* timestamp seconds */
|
||||
uint32_t ts_usec = 0; /* timestamp microseconds */
|
||||
@@ -646,8 +650,7 @@ static void write_received_packet(
|
||||
}
|
||||
} else {
|
||||
if (mstp_port->DataLength) {
|
||||
max_data =
|
||||
min(mstp_port->InputBufferSize, mstp_port->DataLength);
|
||||
max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength);
|
||||
incl_len = orig_len = header_len + max_data + data_crc_len;
|
||||
} else {
|
||||
/* header only - or at least some bytes of the header */
|
||||
@@ -744,7 +747,8 @@ static bool test_global_header(const char *filename)
|
||||
return false;
|
||||
}
|
||||
} 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));
|
||||
return false;
|
||||
}
|
||||
@@ -819,20 +823,22 @@ static bool read_received_packet(struct mstp_port_struct_t *mstp_port)
|
||||
if (orig_len > 8) {
|
||||
/* packet includes data */
|
||||
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 =
|
||||
fread(mstp_port->InputBuffer, mstp_port->DataLength, 1, File_Handle);
|
||||
fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, File_Handle);
|
||||
if (count != 1) {
|
||||
fclose(File_Handle);
|
||||
File_Handle = NULL;
|
||||
return false;
|
||||
}
|
||||
count = fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, File_Handle);
|
||||
if (count != 1) {
|
||||
fclose(File_Handle);
|
||||
File_Handle = NULL;
|
||||
return false;
|
||||
}
|
||||
count = fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, File_Handle);
|
||||
count =
|
||||
fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, File_Handle);
|
||||
if (count != 1) {
|
||||
fclose(File_Handle);
|
||||
File_Handle = NULL;
|
||||
@@ -930,7 +936,8 @@ static void print_usage(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",
|
||||
filename);
|
||||
printf("\n");
|
||||
@@ -957,7 +964,8 @@ static void print_help(const char *filename)
|
||||
#endif
|
||||
" Use that name as the interface name in Wireshark.\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"
|
||||
"[--extcap-interface iface]\n"
|
||||
"Usage from Wireshark ExtCap interface\n",
|
||||
@@ -1053,7 +1061,8 @@ int main(int argc, char *argv[])
|
||||
printf("An interface must be provided.\n");
|
||||
return 0;
|
||||
}
|
||||
printf("dlt {number=%u}{name=BACnet MS/TP}"
|
||||
printf(
|
||||
"dlt {number=%u}{name=BACnet MS/TP}"
|
||||
"{display=BACnet MS/TP}\n",
|
||||
DLT_BACNET_MS_TP);
|
||||
Exit_Requested = true;
|
||||
@@ -1137,7 +1146,8 @@ int main(int argc, char *argv[])
|
||||
RS485_Initialize();
|
||||
mstimer_init();
|
||||
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());
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
@@ -1194,7 +1204,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (!Wireshark_Capture) {
|
||||
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);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
+6
-3
@@ -135,7 +135,8 @@ static void filename_create(char *filename, size_t filesize)
|
||||
if (filename) {
|
||||
my_time = time(NULL);
|
||||
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,
|
||||
today->tm_hour, today->tm_min, today->tm_sec);
|
||||
}
|
||||
@@ -165,7 +166,8 @@ static void write_global_header(const char *filename)
|
||||
fflush(pFile);
|
||||
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
@@ -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(buffer, length, 1, pFile);
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
|
||||
+26
-15
@@ -63,8 +63,8 @@ static void MyAbortHandler(
|
||||
* @param invoke_id [in] the invokeID from the rejected message
|
||||
* @param reject_reason [in] the reason for the rejection
|
||||
*/
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -79,7 +79,8 @@ static void MyRejectHandler(
|
||||
* @param npdu - NPDU data
|
||||
* @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,
|
||||
uint8_t *npdu,
|
||||
uint16_t npdu_len)
|
||||
@@ -120,7 +121,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
|
||||
that are sent with a local unicast address. */
|
||||
if (npdu_len >= 2) {
|
||||
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);
|
||||
} else {
|
||||
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 */
|
||||
uint16_t pdu_len)
|
||||
{ /* 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);
|
||||
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));
|
||||
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
|
||||
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) {
|
||||
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
|
||||
} else {
|
||||
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
debug_printf(
|
||||
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
npdu_data.protocol_version);
|
||||
}
|
||||
}
|
||||
@@ -202,8 +207,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
int index = 0;
|
||||
|
||||
if (argc > 0) {
|
||||
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3],
|
||||
&mac[4], &mac[5]);
|
||||
dst->mac_len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
@@ -219,8 +225,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
}
|
||||
if (dnet) {
|
||||
if (argc > 2) {
|
||||
count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
|
||||
&mac[2], &mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
dst->len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
@@ -257,7 +264,8 @@ int main(int argc, char *argv[])
|
||||
return 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"
|
||||
"DNET:\r\n"
|
||||
"BACnet destination network number 0-65535\r\n"
|
||||
@@ -281,7 +289,8 @@ int main(int argc, char *argv[])
|
||||
if (argc > 1) {
|
||||
Target_Network_Number = strtol(argv[1], NULL, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -289,7 +298,8 @@ int main(int argc, char *argv[])
|
||||
if (argc > 2) {
|
||||
Target_Network_Number_Status = strtol(argv[2], NULL, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -309,7 +319,8 @@ int main(int argc, char *argv[])
|
||||
last_seconds = time(NULL);
|
||||
timeout_seconds = apdu_timeout() / 1000;
|
||||
/* 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);
|
||||
/* loop forever */
|
||||
for (;;) {
|
||||
|
||||
+58
-35
@@ -66,25 +66,28 @@ static void MyAbortHandler(
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
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));
|
||||
LogError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
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));
|
||||
LogError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void My_Error_Handler(BACNET_ADDRESS *src,
|
||||
static void My_Error_Handler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -92,7 +95,8 @@ static void My_Error_Handler(BACNET_ADDRESS *src,
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
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_code_name((int)error_code));
|
||||
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.array_index = data->array_index;
|
||||
object_value.value = &value;
|
||||
bacapp_snprintf_value(pAckString,
|
||||
MAX_ACK_STRING - (pAckString - ackString), &object_value);
|
||||
bacapp_snprintf_value(
|
||||
pAckString, MAX_ACK_STRING - (pAckString - ackString),
|
||||
&object_value);
|
||||
if (len > 0) {
|
||||
if (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 =
|
||||
listOfProperties->propertyArrayIndex;
|
||||
object_value.value = value;
|
||||
bacapp_snprintf_value(pAckString,
|
||||
MAX_ACK_STRING - (pAckString - ackString),
|
||||
bacapp_snprintf_value(
|
||||
pAckString, MAX_ACK_STRING - (pAckString - ackString),
|
||||
&object_value);
|
||||
if (value->next) {
|
||||
strncat(pAckString, ",", 1);
|
||||
@@ -211,7 +216,8 @@ void rpm_ack_extract_data(BACNET_READ_ACCESS_DATA *rpm_data)
|
||||
}
|
||||
} else {
|
||||
/* AccessError */
|
||||
snprintf(ackString, sizeof(ackString), "BACnet Error: %s: %s",
|
||||
snprintf(
|
||||
ackString, sizeof(ackString), "BACnet Error: %s: %s",
|
||||
bactext_error_class_name(
|
||||
(int)listOfProperties->error.error_class),
|
||||
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,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -251,7 +258,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||
uint8_t *pFileData;
|
||||
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);
|
||||
__LogAnswer(msg, 0);
|
||||
|
||||
@@ -279,7 +287,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||
* 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,
|
||||
BACNET_ADDRESS *src,
|
||||
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
|
||||
* 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,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -447,8 +457,9 @@ static void Wait_For_Answer_Or_Timeout(unsigned timeout_ms, waitAction action)
|
||||
break;
|
||||
}
|
||||
} else if (action == waitBind) {
|
||||
if (address_bind_request(Target_Device_Object_Instance,
|
||||
&Target_Max_APDU, &Target_Address)) {
|
||||
if (address_bind_request(
|
||||
Target_Device_Object_Instance, &Target_Max_APDU,
|
||||
&Target_Address)) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -507,7 +518,8 @@ int BacnetBindToDevice(int deviceInstanceNumber)
|
||||
/****************************************************/
|
||||
/* This is the interface to ReadProperty */
|
||||
/****************************************************/
|
||||
int BacnetReadProperty(int deviceInstanceNumber,
|
||||
int BacnetReadProperty(
|
||||
int deviceInstanceNumber,
|
||||
int objectType,
|
||||
int objectInstanceNumber,
|
||||
int objectProperty,
|
||||
@@ -526,8 +538,9 @@ int BacnetReadProperty(int deviceInstanceNumber,
|
||||
isReadPropertyHandlerRegistered = true;
|
||||
}
|
||||
/* Send the message out */
|
||||
Request_Invoke_ID = Send_Read_Property_Request(deviceInstanceNumber,
|
||||
objectType, objectInstanceNumber, objectProperty, objectIndex);
|
||||
Request_Invoke_ID = Send_Read_Property_Request(
|
||||
deviceInstanceNumber, objectType, objectInstanceNumber, objectProperty,
|
||||
objectIndex);
|
||||
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
||||
|
||||
int isFailure = Error_Detected;
|
||||
@@ -622,7 +635,8 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
|
||||
|
||||
if (!isReadPropertyMultipleHandlerRegistered) {
|
||||
/* 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);
|
||||
|
||||
/* handle any errors coming back */
|
||||
@@ -665,7 +679,8 @@ int BacnetReadPropertyMultiple(int deviceInstanceNumber, ...)
|
||||
/****************************************************/
|
||||
/* This is the interface to WriteProperty */
|
||||
/****************************************************/
|
||||
int BacnetWriteProperty(int deviceInstanceNumber,
|
||||
int BacnetWriteProperty(
|
||||
int deviceInstanceNumber,
|
||||
int objectType,
|
||||
int objectInstanceNumber,
|
||||
int objectProperty,
|
||||
@@ -679,7 +694,8 @@ int BacnetWriteProperty(int deviceInstanceNumber,
|
||||
|
||||
if (!isWritePropertyHandlerRegistered) {
|
||||
/* 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);
|
||||
|
||||
/* handle any errors coming back */
|
||||
@@ -710,7 +726,8 @@ int BacnetWriteProperty(int deviceInstanceNumber,
|
||||
property_tag = strtol(tag, NULL, 0);
|
||||
|
||||
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);
|
||||
LogError(msg);
|
||||
break;
|
||||
@@ -724,9 +741,9 @@ int BacnetWriteProperty(int deviceInstanceNumber,
|
||||
propertyValue.next = NULL;
|
||||
|
||||
/* Send out the message */
|
||||
Request_Invoke_ID = Send_Write_Property_Request(deviceInstanceNumber,
|
||||
objectType, objectInstanceNumber, objectProperty, &propertyValue,
|
||||
objectPriority, objectIndex);
|
||||
Request_Invoke_ID = Send_Write_Property_Request(
|
||||
deviceInstanceNumber, objectType, objectInstanceNumber,
|
||||
objectProperty, &propertyValue, objectPriority, objectIndex);
|
||||
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
||||
|
||||
/* If we get here, then there were no explicit failures. However, there
|
||||
@@ -740,7 +757,8 @@ int BacnetWriteProperty(int deviceInstanceNumber,
|
||||
return isFailure;
|
||||
}
|
||||
|
||||
int BacnetAtomicWriteFile(int deviceInstanceNumber,
|
||||
int BacnetAtomicWriteFile(
|
||||
int deviceInstanceNumber,
|
||||
int fileInstanceNumber,
|
||||
int blockStartAddr,
|
||||
int blockNumBytes,
|
||||
@@ -778,8 +796,9 @@ int BacnetAtomicWriteFile(int deviceInstanceNumber,
|
||||
|
||||
/* Send out the message and wait for answer */
|
||||
if (!Error_Detected) {
|
||||
Request_Invoke_ID = Send_Atomic_Write_File_Stream(deviceInstanceNumber,
|
||||
fileInstanceNumber, blockStartAddr, &fileData);
|
||||
Request_Invoke_ID = Send_Atomic_Write_File_Stream(
|
||||
deviceInstanceNumber, fileInstanceNumber, blockStartAddr,
|
||||
&fileData);
|
||||
Wait_For_Answer_Or_Timeout(100, waitAnswer);
|
||||
}
|
||||
|
||||
@@ -816,7 +835,8 @@ int BacnetGetMaxApdu()
|
||||
return requestedOctetCount;
|
||||
}
|
||||
|
||||
int BacnetTimeSync(int deviceInstanceNumber,
|
||||
int BacnetTimeSync(
|
||||
int deviceInstanceNumber,
|
||||
int year,
|
||||
int month,
|
||||
int day,
|
||||
@@ -871,8 +891,9 @@ int BacnetTimeSync(int deviceInstanceNumber,
|
||||
/* encode the NPDU portion of the packet */
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
datalink_get_my_address(&my_address);
|
||||
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &Target_Address,
|
||||
&my_address, &npdu_data);
|
||||
pdu_len = npdu_encode_pdu(
|
||||
&Handler_Transmit_Buffer[0], &Target_Address, &my_address,
|
||||
&npdu_data);
|
||||
|
||||
/* encode the APDU portion of the packet */
|
||||
len = timesync_encode_apdu(
|
||||
@@ -884,7 +905,8 @@ int BacnetTimeSync(int deviceInstanceNumber,
|
||||
&Target_Address, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||
if (bytes_sent <= 0) {
|
||||
char msg[64];
|
||||
snprintf(msg, sizeof(msg),
|
||||
snprintf(
|
||||
msg, sizeof(msg),
|
||||
"Failed to Send Time-Synchronization Request (%s)!",
|
||||
strerror(errno));
|
||||
LogError(msg);
|
||||
@@ -902,7 +924,8 @@ int BacnetTimeSync(int deviceInstanceNumber,
|
||||
/****************************************************/
|
||||
/* This is the interface to AtomicReadFile */
|
||||
/****************************************************/
|
||||
int BacnetAtomicReadFile(int deviceInstanceNumber,
|
||||
int BacnetAtomicReadFile(
|
||||
int deviceInstanceNumber,
|
||||
int fileInstanceNumber,
|
||||
int startOffset,
|
||||
int numBytes)
|
||||
|
||||
+180
-81
@@ -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 My_Object_Table[] = {
|
||||
{ OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */,
|
||||
Device_Count, Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number, Device_Object_Name,
|
||||
Device_Read_Property_Local, 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 */,
|
||||
{ OBJECT_DEVICE,
|
||||
NULL /* Init - don't init Device or it will recourse! */,
|
||||
Device_Count,
|
||||
Device_Index_To_Instance,
|
||||
Device_Valid_Object_Instance_Number,
|
||||
Device_Object_Name,
|
||||
Device_Read_Property_Local,
|
||||
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 */ },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 17)
|
||||
{ OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
|
||||
Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
|
||||
Network_Port_Object_Name, Network_Port_Read_Property,
|
||||
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 */ },
|
||||
{ OBJECT_NETWORK_PORT,
|
||||
Network_Port_Init,
|
||||
Network_Port_Count,
|
||||
Network_Port_Index_To_Instance,
|
||||
Network_Port_Valid_Instance,
|
||||
Network_Port_Object_Name,
|
||||
Network_Port_Read_Property,
|
||||
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
|
||||
{ OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
|
||||
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
|
||||
Binary_Input_Object_Name, Binary_Input_Read_Property,
|
||||
Binary_Input_Write_Property, Binary_Input_Property_Lists,
|
||||
NULL /* ReadRangeInfo */, 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,
|
||||
{ OBJECT_BINARY_INPUT,
|
||||
Binary_Input_Init,
|
||||
Binary_Input_Count,
|
||||
Binary_Input_Index_To_Instance,
|
||||
Binary_Input_Valid_Instance,
|
||||
Binary_Input_Object_Name,
|
||||
Binary_Input_Read_Property,
|
||||
Binary_Input_Write_Property,
|
||||
Binary_Input_Property_Lists,
|
||||
NULL /* ReadRangeInfo */,
|
||||
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_Object_Name,
|
||||
Binary_Lighting_Output_Read_Property,
|
||||
Binary_Lighting_Output_Write_Property,
|
||||
Binary_Lighting_Output_Property_Lists, NULL /* ReadRangeInfo */,
|
||||
NULL /* Iterator */, NULL /* Value_Lists */, NULL /* COV */,
|
||||
NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Binary_Lighting_Output_Create, Binary_Lighting_Output_Delete,
|
||||
Binary_Lighting_Output_Property_Lists,
|
||||
NULL /* ReadRangeInfo */,
|
||||
NULL /* Iterator */,
|
||||
NULL /* Value_Lists */,
|
||||
NULL /* COV */,
|
||||
NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
Binary_Lighting_Output_Create,
|
||||
Binary_Lighting_Output_Delete,
|
||||
Binary_Lighting_Output_Timer },
|
||||
{ OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
|
||||
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
|
||||
Binary_Output_Object_Name, Binary_Output_Read_Property,
|
||||
Binary_Output_Write_Property, Binary_Output_Property_Lists,
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
Binary_Output_Create, Binary_Output_Delete, NULL /* Timer */ },
|
||||
{ MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
|
||||
NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
|
||||
NULL /* Object_Name */, NULL /* Read_Property */,
|
||||
NULL /* Write_Property */, NULL /* Property_Lists */,
|
||||
NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
|
||||
NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */, NULL /* Remove_List_Element */,
|
||||
NULL /* Create */, NULL /* Delete */, NULL /* Timer */ }
|
||||
{ OBJECT_BINARY_OUTPUT,
|
||||
Binary_Output_Init,
|
||||
Binary_Output_Count,
|
||||
Binary_Output_Index_To_Instance,
|
||||
Binary_Output_Valid_Instance,
|
||||
Binary_Output_Object_Name,
|
||||
Binary_Output_Read_Property,
|
||||
Binary_Output_Write_Property,
|
||||
Binary_Output_Property_Lists,
|
||||
NULL /* ReadRangeInfo */,
|
||||
NULL /* Iterator */,
|
||||
NULL /* Value_Lists */,
|
||||
NULL /* COV */,
|
||||
NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
Binary_Output_Create,
|
||||
Binary_Output_Delete,
|
||||
NULL /* Timer */ },
|
||||
{ MAX_BACNET_OBJECT_TYPE,
|
||||
NULL /* Init */,
|
||||
NULL /* Count */,
|
||||
NULL /* Index_To_Instance */,
|
||||
NULL /* Valid_Instance */,
|
||||
NULL /* Object_Name */,
|
||||
NULL /* Read_Property */,
|
||||
NULL /* Write_Property */,
|
||||
NULL /* Property_Lists */,
|
||||
NULL /* ReadRangeInfo */,
|
||||
NULL /* Iterator */,
|
||||
NULL /* Value_Lists */,
|
||||
NULL /* COV */,
|
||||
NULL /* COV Clear */,
|
||||
NULL /* Intrinsic Reporting */,
|
||||
NULL /* Add_List_Element */,
|
||||
NULL /* Remove_List_Element */,
|
||||
NULL /* Create */,
|
||||
NULL /* Delete */,
|
||||
NULL /* Timer */ }
|
||||
};
|
||||
|
||||
/** Glue function to let the Device object, when called by a handler,
|
||||
@@ -107,8 +173,8 @@ static object_functions_t My_Object_Table[] = {
|
||||
* @return Pointer to the group of object helper functions that implement this
|
||||
* type of Object.
|
||||
*/
|
||||
static struct object_functions *Device_Objects_Find_Functions(
|
||||
BACNET_OBJECT_TYPE Object_Type)
|
||||
static struct object_functions *
|
||||
Device_Objects_Find_Functions(BACNET_OBJECT_TYPE Object_Type)
|
||||
{
|
||||
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
|
||||
* 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,
|
||||
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);
|
||||
if ((pObject != NULL) && (pObject->Object_RPM_List != NULL)) {
|
||||
pObject->Object_RPM_List(&pPropertyList->Required.pList,
|
||||
&pPropertyList->Optional.pList, &pPropertyList->Proprietary.pList);
|
||||
pObject->Object_RPM_List(
|
||||
&pPropertyList->Required.pList, &pPropertyList->Optional.pList,
|
||||
&pPropertyList->Proprietary.pList);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, 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_Required[] = {
|
||||
PROP_OBJECT_IDENTIFIER,
|
||||
PROP_OBJECT_NAME,
|
||||
PROP_OBJECT_TYPE,
|
||||
PROP_SYSTEM_STATUS,
|
||||
PROP_VENDOR_NAME,
|
||||
PROP_VENDOR_IDENTIFIER,
|
||||
PROP_MODEL_NAME,
|
||||
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[] = {
|
||||
#if defined(BACDL_MSTP)
|
||||
PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES,
|
||||
PROP_MAX_MASTER,
|
||||
PROP_MAX_INFO_FRAMES,
|
||||
#endif
|
||||
PROP_DESCRIPTION, PROP_LOCAL_TIME, PROP_UTC_OFFSET, PROP_LOCAL_DATE,
|
||||
PROP_DAYLIGHT_SAVINGS_STATUS, PROP_LOCATION, PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||
PROP_DESCRIPTION,
|
||||
PROP_LOCAL_TIME,
|
||||
PROP_UTC_OFFSET,
|
||||
PROP_LOCAL_DATE,
|
||||
PROP_DAYLIGHT_SAVINGS_STATUS,
|
||||
PROP_LOCATION,
|
||||
PROP_ACTIVE_COV_SUBSCRIPTIONS,
|
||||
#if defined(BACNET_TIME_MASTER)
|
||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||
PROP_ALIGN_INTERVALS, PROP_INTERVAL_OFFSET,
|
||||
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||
PROP_TIME_SYNCHRONIZATION_INTERVAL,
|
||||
PROP_ALIGN_INTERVALS,
|
||||
PROP_INTERVAL_OFFSET,
|
||||
#endif
|
||||
-1
|
||||
};
|
||||
@@ -785,7 +875,8 @@ int Device_Object_List_Element_Encode(
|
||||
* Object.
|
||||
* @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,
|
||||
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.
|
||||
* @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,
|
||||
BACNET_CHARACTER_STRING *object_name)
|
||||
{
|
||||
@@ -1063,7 +1155,8 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* 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_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
@@ -1090,9 +1183,9 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
break;
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
apdu_len = bacnet_array_encode(rpdata->object_instance,
|
||||
rpdata->array_index, Device_Object_List_Element_Encode, count,
|
||||
apdu, apdu_max);
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Device_Object_List_Element_Encode, count, apdu, apdu_max);
|
||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||
rpdata->error_code =
|
||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||
@@ -1215,8 +1308,9 @@ static int Read_Property_Common(
|
||||
} else if (rpdata->object_property == PROP_PROPERTY_LIST) {
|
||||
Device_Objects_Property_List(
|
||||
rpdata->object_type, rpdata->object_instance, &property_list);
|
||||
apdu_len = property_list_encode(rpdata, property_list.Required.pList,
|
||||
property_list.Optional.pList, property_list.Proprietary.pList);
|
||||
apdu_len = property_list_encode(
|
||||
rpdata, property_list.Required.pList, property_list.Optional.pList,
|
||||
property_list.Proprietary.pList);
|
||||
#endif
|
||||
} else if (pObject->Object_Read_Property) {
|
||||
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));
|
||||
if (status) {
|
||||
/* All the object names in a device must be unique */
|
||||
if (Device_Valid_Object_Name(&value.type.Character_String,
|
||||
&object_type, &object_instance)) {
|
||||
if (Device_Valid_Object_Name(
|
||||
&value.type.Character_String, &object_type,
|
||||
&object_instance)) {
|
||||
if ((object_type == wp_data->object_type) &&
|
||||
(object_instance == wp_data->object_instance)) {
|
||||
/* 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
|
||||
* @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,
|
||||
BACNET_PROPERTY_VALUE *value_list)
|
||||
{
|
||||
@@ -1804,7 +1900,8 @@ bool Device_Create_Object(BACNET_CREATE_OBJECT_DATA *data)
|
||||
object for some other reason.*/
|
||||
data->error_class = ERROR_CLASS_OBJECT;
|
||||
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)) {
|
||||
/* The object being created already exists */
|
||||
data->error_class = ERROR_CLASS_OBJECT;
|
||||
@@ -1862,7 +1959,8 @@ bool Device_Delete_Object(BACNET_DELETE_OBJECT_DATA *data)
|
||||
object for some reason.*/
|
||||
data->error_class = ERROR_CLASS_OBJECT;
|
||||
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)) {
|
||||
/* The object being deleted must already exist */
|
||||
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)
|
||||
{ /* Where to put the response */
|
||||
bool status = false; /* return value */
|
||||
|
||||
+14
-10
@@ -85,7 +85,8 @@ static void piface_write_output(int index, BACNET_BINARY_LIGHTING_PV value)
|
||||
* @param old_value - value prior to 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 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);
|
||||
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,
|
||||
(int)Binary_Lighting_Output_Present_Value(object_instance),
|
||||
(int)old_value,
|
||||
@@ -115,12 +117,10 @@ static void Binary_Lighting_Output_Blink_Warn_Handler(uint32_t object_instance)
|
||||
if (index < PIFACE_OUTPUTS_MAX) {
|
||||
/* blink is just toggle on/off every one second */
|
||||
if (PiFace_Output_State[index]) {
|
||||
printf("BLO-BLINK: OUTPUT[%u]=%d\n", index,
|
||||
BINARY_LIGHTING_PV_OFF);
|
||||
printf("BLO-BLINK: OUTPUT[%u]=%d\n", index, BINARY_LIGHTING_PV_OFF);
|
||||
piface_write_output(index, BINARY_LIGHTING_PV_OFF);
|
||||
} else {
|
||||
printf(
|
||||
"BLO-BLINK: OUTPUT[%u]=%d\n", index, BINARY_LIGHTING_PV_ON);
|
||||
printf("BLO-BLINK: OUTPUT[%u]=%d\n", 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(
|
||||
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
|
||||
/* 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);
|
||||
/* configure the cyclic timers */
|
||||
mstimer_set(&BACnet_Task_Timer, 1000UL);
|
||||
@@ -262,13 +263,15 @@ static void piface_task(void)
|
||||
present_value = Binary_Output_Present_Value(object_instance);
|
||||
if (present_value == BINARY_INACTIVE) {
|
||||
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);
|
||||
piface_write_output(i, BINARY_LIGHTING_PV_OFF);
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
piface_write_output(i, BINARY_LIGHTING_PV_ON);
|
||||
}
|
||||
@@ -302,7 +305,8 @@ int main(int argc, char *argv[])
|
||||
if (argc > 1) {
|
||||
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 Device ID: %u\n"
|
||||
"Max APDU: %d\n",
|
||||
|
||||
+15
-10
@@ -122,7 +122,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
||||
data->serviceParametersLen = 0;
|
||||
return;
|
||||
}
|
||||
iLen += decode_real(&data->serviceParameters[iLen],
|
||||
iLen += decode_real(
|
||||
&data->serviceParameters[iLen],
|
||||
&MyData[(int8_t)cBlockNumber].fMyReal);
|
||||
|
||||
tag_len = decode_tag_number_and_value(
|
||||
@@ -135,7 +136,8 @@ static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
|
||||
decode_character_string(
|
||||
&data->serviceParameters[iLen], len_value_type, &bsTemp);
|
||||
/* 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);
|
||||
/* Make sure it is nul terminated */
|
||||
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,
|
||||
BACNET_ADDRESS *src,
|
||||
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);
|
||||
|
||||
if (service_data->segmented_message) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
|
||||
#endif
|
||||
@@ -206,8 +209,9 @@ void handler_conf_private_trans(uint8_t *service_request,
|
||||
len = ptransfer_decode_service_request(service_request, service_len, &data);
|
||||
/* bad decoding - send an abort */
|
||||
if (len < 0) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_OTHER, true);
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
|
||||
#endif
|
||||
@@ -247,8 +251,9 @@ void handler_conf_private_trans(uint8_t *service_request,
|
||||
}
|
||||
|
||||
if (error) {
|
||||
len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, error_class, error_code, &data);
|
||||
len = ptransfer_error_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
error_class, error_code, &data);
|
||||
}
|
||||
CPT_ABORT:
|
||||
pdu_len += len;
|
||||
|
||||
+13
-13
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date October 2019
|
||||
* @brief Header file for a basic ConfirmedPrivateTransfer service handler
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date October 2019
|
||||
* @brief Header file for a basic ConfirmedPrivateTransfer service handler
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_H
|
||||
#define HANDLER_CONFIRMED_PRIVATE_TRANSFER_H
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void handler_conf_private_trans(
|
||||
uint8_t * service_request,
|
||||
void handler_conf_private_trans(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA * service_data);
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+10
-5
@@ -36,8 +36,9 @@ static void DecodeBlock(char cBlockNum, uint8_t *pData)
|
||||
|
||||
iLen = 0;
|
||||
|
||||
if (cBlockNum >= MY_MAX_BLOCK)
|
||||
if (cBlockNum >= MY_MAX_BLOCK) {
|
||||
return;
|
||||
}
|
||||
|
||||
tag_len =
|
||||
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;
|
||||
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
|
||||
} 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);
|
||||
return;
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
@@ -152,7 +155,8 @@ static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
|
||||
* 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,
|
||||
BACNET_ADDRESS *src,
|
||||
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");
|
||||
#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! */
|
||||
if (len < 0) {
|
||||
#if PRINT_ENABLED
|
||||
|
||||
+13
-13
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date October 2019
|
||||
* @brief Header file for a basic ConfirmedPrivateTransfer-Ack service handler
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date October 2019
|
||||
* @brief Header file for a basic ConfirmedPrivateTransfer-Ack service handler
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H
|
||||
#define HANDLER_CONFIRMED_PRIVATE_TRANSFER_ACK_H
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void handler_conf_private_trans_ack(
|
||||
uint8_t * service_request,
|
||||
void handler_conf_private_trans_ack(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS * src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data);
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+16
-10
@@ -68,7 +68,8 @@ static int Target_Mode = 0;
|
||||
static BACNET_ADDRESS Target_Address;
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -76,14 +77,15 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
(void)invoke_id;
|
||||
printf("BACnet Error: %s: %s\r\n",
|
||||
bactext_error_class_name((int)error_class),
|
||||
printf(
|
||||
"BACnet Error: %s: %s\r\n", bactext_error_class_name((int)error_class),
|
||||
bactext_error_code_name((int)error_code));
|
||||
/* Error_Detected = true; */
|
||||
}
|
||||
|
||||
/* complex error reply function */
|
||||
static void MyPrivateTransferErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyPrivateTransferErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
uint8_t service_choice,
|
||||
uint8_t *service_request,
|
||||
@@ -108,13 +110,14 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
(void)invoke_id;
|
||||
printf("BACnet Reject: %s\r\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\r\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -184,7 +187,8 @@ int main(int argc, char *argv[])
|
||||
if (((argc != 2) && (argc != 3)) ||
|
||||
((argc >= 2) && (strcmp(argv[1], "--help") == 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",
|
||||
filename_remove_path(argv[0]), filename_remove_path(argv[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);
|
||||
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -349,7 +354,8 @@ int main(int argc, char *argv[])
|
||||
case 3:
|
||||
case 5:
|
||||
case 7:
|
||||
printf("Requesting block %d with invalid "
|
||||
printf(
|
||||
"Requesting block %d with invalid "
|
||||
"Vendor ID\n",
|
||||
iCount);
|
||||
invoke_id = Send_Private_Transfer_Request(
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
#include "bacnet/datalink/datalink.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,
|
||||
uint32_t service_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. */
|
||||
|
||||
if ((unsigned)pdu_len < max_apdu) {
|
||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len);
|
||||
tsm_set_confirmed_unsegmented_transaction(
|
||||
invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
|
||||
(uint16_t)pdu_len);
|
||||
bytes_sent = datalink_send_pdu(
|
||||
&dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||
#if PRINT_ENABLED
|
||||
if (bytes_sent <= 0)
|
||||
fprintf(stderr,
|
||||
if (bytes_sent <= 0) {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Failed to Send Private Transfer Request (%s)!\n",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
invoke_id = 0;
|
||||
#if PRINT_ENABLED
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Failed to Send Private Transfer Request "
|
||||
"(exceeds destination maximum APDU)!\n");
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date October 2019
|
||||
* @brief Header file for a basic WritePropertyMultiple service send
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date October 2019
|
||||
* @brief Header file for a basic WritePropertyMultiple service send
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef SEND_WRITE_PROPERTY_MULTIPLE_H
|
||||
#define SEND_WRITE_PROPERTY_MULTIPLE_H
|
||||
|
||||
@@ -25,9 +25,12 @@
|
||||
extern "C" {
|
||||
#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,
|
||||
char block_number, DATABLOCK *block);
|
||||
char block_number,
|
||||
DATABLOCK *block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
|
||||
+4
-3
@@ -52,8 +52,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -98,7 +98,8 @@ int main(int argc, char *argv[])
|
||||
return 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"
|
||||
"IP:\r\n"
|
||||
"IP address of the BBMD in dotted decimal notation\r\n"
|
||||
|
||||
+30
-19
@@ -50,14 +50,16 @@ static bool End_Of_File_Detected = false;
|
||||
static bool Error_Detected = false;
|
||||
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,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -76,18 +78,20 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||
static void AtomicReadFileAckHandler(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -128,7 +132,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||
octets_written =
|
||||
fwrite(octet_buffer, 1, octet_count, pFile);
|
||||
if (octets_written != octet_count) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Unable to write data to file \"%s\".\n",
|
||||
Local_File_Name);
|
||||
} else {
|
||||
@@ -140,7 +145,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||
}
|
||||
fflush(pFile);
|
||||
} else {
|
||||
fprintf(stderr, "Unable to seek to %d!\n",
|
||||
fprintf(
|
||||
stderr, "Unable to seek to %d!\n",
|
||||
data.type.stream.fileStartPosition);
|
||||
}
|
||||
}
|
||||
@@ -154,7 +160,8 @@ static void AtomicReadFileAckHandler(uint8_t *service_request,
|
||||
fprintf(stderr, "Decode error! %d bytes decoded.\n", len);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Address & Invoke ID mismatch! Invoke ID=%d\n",
|
||||
fprintf(
|
||||
stderr, "Address & Invoke ID mismatch! Invoke ID=%d\n",
|
||||
Request_Invoke_ID);
|
||||
}
|
||||
}
|
||||
@@ -213,16 +220,17 @@ static void print_usage(const char *filename)
|
||||
|
||||
static void print_help(const char *filename)
|
||||
{
|
||||
printf(
|
||||
"Read a file from a BACnet device and save it locally.\n");
|
||||
printf("Read a file from a BACnet device and save it locally.\n");
|
||||
printf("\n");
|
||||
printf("device-instance:\n"
|
||||
printf(
|
||||
"device-instance:\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"
|
||||
"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");
|
||||
printf("\n");
|
||||
printf("file-instance:\n"
|
||||
printf(
|
||||
"file-instance:\n"
|
||||
"This is the file object instance number that you are reading from.\n"
|
||||
"For example, if you were reading from File 2, \n"
|
||||
"the file-instance would be 2.\n");
|
||||
@@ -230,7 +238,8 @@ static void print_help(const char *filename)
|
||||
printf("local-name:\n"
|
||||
"The name of the file that will be stored locally.\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"
|
||||
"use the following command:\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);
|
||||
Local_File_Name = argv[3];
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -356,9 +367,9 @@ int main(int argc, char *argv[])
|
||||
/* the ACK will increment the start position if OK */
|
||||
/* we'll read the file in chunks
|
||||
less than max_apdu to keep unsegmented */
|
||||
invoke_id =
|
||||
Send_Atomic_Read_File_Stream(Target_Device_Object_Instance,
|
||||
Target_File_Object_Instance, Target_File_Start_Position,
|
||||
invoke_id = Send_Atomic_Read_File_Stream(
|
||||
Target_Device_Object_Instance, Target_File_Object_Instance,
|
||||
Target_File_Start_Position,
|
||||
Target_File_Requested_Octet_Count);
|
||||
Request_Invoke_ID = invoke_id;
|
||||
} else if (tsm_invoke_id_failed(invoke_id)) {
|
||||
|
||||
+26
-26
@@ -13,7 +13,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h> /* for time */
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#define PRINT_ENABLED 1
|
||||
@@ -56,14 +56,16 @@ static uint8_t Request_Invoke_ID = 0;
|
||||
static BACNET_ADDRESS Target_Address;
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -82,12 +84,13 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -104,7 +107,8 @@ static void MyRejectHandler(
|
||||
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||
* 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,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -149,7 +153,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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",
|
||||
filename);
|
||||
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 Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"--dnet N\n"
|
||||
printf("--dnet N\n"
|
||||
"Optional BACnet network number N for directed requests.\n"
|
||||
"Valid range is from 0 to 65535 where 0 is the local connection\n"
|
||||
"and 65535 is network broadcast.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"--dadr A\n"
|
||||
printf("--dadr A\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"
|
||||
@@ -187,8 +190,7 @@ static void print_help(const char *filename)
|
||||
"I-Am services. For example, if you were reading\n"
|
||||
"Device Object 123, the device-instance would be 123.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"object-type:\n"
|
||||
printf("object-type:\n"
|
||||
"The object type is object that you are reading. It\n"
|
||||
"can be defined either as the object-type name string\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"
|
||||
"Output 2, the object-type would be analog-output or 1.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"object-instance:\n"
|
||||
printf("object-instance:\n"
|
||||
"This is the object instance number of the object that\n"
|
||||
"you are reading. For example, if you were reading\n"
|
||||
"Analog Output 2, the object-instance would be 2.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"property:\n"
|
||||
printf("property:\n"
|
||||
"The property of the object that you are reading. It\n"
|
||||
"can be defined either as the property name string as\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"
|
||||
"Value property, use present-value or 85 as the property.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"index:\n"
|
||||
printf("index:\n"
|
||||
"This integer parameter is the index number of an array.\n"
|
||||
"If the property is an array, individual elements can\n"
|
||||
"be read. If this parameter is missing and the property\n"
|
||||
@@ -329,7 +328,8 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -370,7 +370,7 @@ int main(int argc, char *argv[])
|
||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||
Init_Service_Handlers();
|
||||
dlenv_init();
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
/* Internationalized programs must call setlocale()
|
||||
* to initiate a specific language operation.
|
||||
* This can be done by calling setlocale() as follows.
|
||||
@@ -413,10 +413,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (found) {
|
||||
if (Request_Invoke_ID == 0) {
|
||||
Request_Invoke_ID =
|
||||
Send_Read_Property_Request(Target_Device_Object_Instance,
|
||||
Target_Object_Type, Target_Object_Instance,
|
||||
Target_Object_Property, Target_Object_Index);
|
||||
Request_Invoke_ID = Send_Read_Property_Request(
|
||||
Target_Device_Object_Instance, Target_Object_Type,
|
||||
Target_Object_Instance, Target_Object_Property,
|
||||
Target_Object_Index);
|
||||
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||
break;
|
||||
} else if (tsm_invoke_id_failed(Request_Invoke_ID)) {
|
||||
|
||||
+50
-31
@@ -13,7 +13,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h> /* for time */
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#define PRINT_ENABLED 1
|
||||
@@ -43,7 +43,6 @@
|
||||
#error "App requires server-only features disabled! Set BACNET_SVC_SERVER=0"
|
||||
#endif
|
||||
|
||||
|
||||
/* buffer used for receive */
|
||||
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||
|
||||
@@ -56,14 +55,16 @@ static BACNET_ADDRESS Target_Address;
|
||||
/* needed for return value of main application */
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -82,13 +83,14 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -105,7 +107,8 @@ static void MyRejectHandler(
|
||||
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
|
||||
* 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,
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
|
||||
@@ -168,7 +171,8 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* 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);
|
||||
/* handle any errors coming back */
|
||||
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)
|
||||
{
|
||||
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",
|
||||
filename);
|
||||
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"
|
||||
"is an array, the entire array will be read.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"If you want read the PRESENT_VALUE property and various\n"
|
||||
"array elements of the PRIORITY_ARRAY in Device 123\n"
|
||||
"Analog Output object 99, use one of the following commands:\n"
|
||||
"%s 123 analog-output 99 85,87[0],87\n"
|
||||
"%s 123 1 99 85,87[0],87\n", filename, filename);
|
||||
printf("If you want read the PRESENT_VALUE property in objects\n"
|
||||
"%s 123 1 99 85,87[0],87\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"
|
||||
"use one of the following commands:\n"
|
||||
"%s 123 analog-input 77 85 analog-input 78 85\n"
|
||||
"%s 123 0 77 85 0 78 85\n", filename, filename);
|
||||
printf("If you want read the ALL property in\n"
|
||||
"%s 123 0 77 85 0 78 85\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"
|
||||
"%s 123 device 123 8\n"
|
||||
"%s 123 8 123 8\n", filename, filename);
|
||||
printf("If you want read the OPTIONAL property in\n"
|
||||
"%s 123 8 123 8\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"
|
||||
"%s 123 device 123 80\n"
|
||||
"%s 123 8 123 80\n", filename, filename);
|
||||
printf("If you want read the REQUIRED property in\n"
|
||||
"%s 123 8 123 80\n",
|
||||
filename, filename);
|
||||
printf(
|
||||
"If you want read the REQUIRED property in\n"
|
||||
"Device object 123, you would one of use the following commands:\n"
|
||||
"%s 123 device 123 105\n"
|
||||
"%s 123 8 123 105\n", filename, filename);
|
||||
"%s 123 8 123 105\n",
|
||||
filename, filename);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@@ -391,8 +406,8 @@ int main(int argc, char *argv[])
|
||||
if (target_args == 0) {
|
||||
Target_Device_Object_Instance = strtol(argv[argi], NULL, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -413,13 +428,15 @@ int main(int argc, char *argv[])
|
||||
status =
|
||||
bactext_object_type_strtol(argv[argi], &object_type);
|
||||
if (status == false) {
|
||||
fprintf(stderr, "Error: object-type=%s invalid\n",
|
||||
fprintf(
|
||||
stderr, "Error: object-type=%s invalid\n",
|
||||
argv[argi]);
|
||||
return 1;
|
||||
}
|
||||
rpm_object->object_type = 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",
|
||||
rpm_object->object_type, MAX_BACNET_OBJECT_TYPE);
|
||||
return 1;
|
||||
@@ -428,10 +445,10 @@ int main(int argc, char *argv[])
|
||||
} else if (tag_value_arg == 1) {
|
||||
rpm_object->object_instance = strtol(argv[argi], NULL, 0);
|
||||
if (rpm_object->object_instance > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"object-instance=%u - not greater than %u\n",
|
||||
rpm_object->object_instance,
|
||||
BACNET_MAX_INSTANCE);
|
||||
rpm_object->object_instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
tag_value_arg++;
|
||||
@@ -441,13 +458,15 @@ int main(int argc, char *argv[])
|
||||
property_token = strtok(argv[argi], ",");
|
||||
/* add all the properties and optional index to our list */
|
||||
while (rpm_property) {
|
||||
scan_count = sscanf(property_token, "%u[%u]",
|
||||
&property_id, &property_array_index);
|
||||
scan_count = sscanf(
|
||||
property_token, "%u[%u]", &property_id,
|
||||
&property_array_index);
|
||||
if (scan_count > 0) {
|
||||
rpm_property->propertyIdentifier = property_id;
|
||||
if (rpm_property->propertyIdentifier >
|
||||
MAX_BACNET_PROPERTY_ID) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"property=%u - it must be less than %u\n",
|
||||
rpm_property->propertyIdentifier,
|
||||
MAX_BACNET_PROPERTY_ID + 1);
|
||||
@@ -489,7 +508,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
Init_Service_Handlers();
|
||||
dlenv_init();
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
/* Internationalized programs must call setlocale()
|
||||
* to initiate a specific language operation.
|
||||
* This can be done by calling setlocale() as follows.
|
||||
|
||||
+17
-11
@@ -14,7 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h> /* for time */
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
#include <locale.h>
|
||||
#endif
|
||||
/* BACnet Stack defines - first */
|
||||
@@ -60,14 +60,16 @@ static bool Error_Detected = false;
|
||||
/* specific request data */
|
||||
static BACNET_READ_RANGE_DATA RR_Request;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -86,12 +88,13 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -123,7 +126,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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);
|
||||
printf(" range-type <index|<date time>> count\n");
|
||||
printf(" [--version][--help]\n");
|
||||
@@ -238,7 +242,8 @@ int main(int argc, char *argv[])
|
||||
Target_Object_Range_Type = strtol(argv[5], NULL, 0);
|
||||
/* some bounds checking */
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -270,8 +275,9 @@ int main(int argc, char *argv[])
|
||||
RR_Request.RequestType = RR_BY_TIME;
|
||||
count = sscanf(argv[6], "%4d/%3d/%3d:%3d", &year, &month, &day, &wday);
|
||||
if (count == 3) {
|
||||
datetime_set_date(&RR_Request.Range.RefTime.date, (uint16_t)year,
|
||||
(uint8_t)month, (uint8_t)day);
|
||||
datetime_set_date(
|
||||
&RR_Request.Range.RefTime.date, (uint16_t)year, (uint8_t)month,
|
||||
(uint8_t)day);
|
||||
} else if (count == 4) {
|
||||
RR_Request.Range.RefTime.date.year = (uint16_t)year;
|
||||
RR_Request.Range.RefTime.date.month = (uint8_t)month;
|
||||
@@ -320,7 +326,7 @@ int main(int argc, char *argv[])
|
||||
address_init();
|
||||
Init_Service_Handlers();
|
||||
dlenv_init();
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined (__STDC_ISO_10646__)
|
||||
#if (__STDC_VERSION__ >= 199901L) && defined(__STDC_ISO_10646__)
|
||||
/* Internationalized programs must call setlocale()
|
||||
* to initiate a specific language operation.
|
||||
* This can be done by calling setlocale() as follows.
|
||||
|
||||
+14
-9
@@ -44,7 +44,8 @@ static char *Reinitialize_Password = NULL;
|
||||
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -52,7 +53,8 @@ static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
(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));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -68,8 +70,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -78,8 +80,8 @@ static void MyRejectHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyReinitializeDeviceSimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyReinitializeDeviceSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
(void)src;
|
||||
(void)invoke_id;
|
||||
@@ -101,7 +103,8 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* 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);
|
||||
/* handle any errors coming back */
|
||||
apdu_set_error_handler(
|
||||
@@ -125,7 +128,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (argc < 3) {
|
||||
/* 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"
|
||||
"\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) {
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@ static bool Error_Detected = false;
|
||||
/* Used for verbose */
|
||||
static bool Verbose = false;
|
||||
|
||||
static void MyRemoveListElementErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyRemoveListElementErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
uint8_t service_choice,
|
||||
uint8_t *service_request,
|
||||
@@ -72,7 +73,8 @@ static void MyRemoveListElementErrorHandler(BACNET_ADDRESS *src,
|
||||
len = list_element_error_ack_decode(
|
||||
service_request, service_len, &list_element);
|
||||
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_code_name((int)list_element.error_code),
|
||||
(unsigned)list_element.first_failed_element_number);
|
||||
@@ -81,8 +83,8 @@ static void MyRemoveListElementErrorHandler(BACNET_ADDRESS *src,
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRemoveListElementSimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyRemoveListElementSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -102,13 +104,14 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -130,7 +133,8 @@ static void Init_Service_Handlers(void)
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* handle the ack or error coming back from confirmed request */
|
||||
apdu_set_confirmed_simple_ack_handler(
|
||||
SERVICE_CONFIRMED_ADD_LIST_ELEMENT, MyRemoveListElementSimpleAckHandler);
|
||||
SERVICE_CONFIRMED_ADD_LIST_ELEMENT,
|
||||
MyRemoveListElementSimpleAckHandler);
|
||||
apdu_set_complex_error_handler(
|
||||
SERVICE_CONFIRMED_ADD_LIST_ELEMENT, MyRemoveListElementErrorHandler);
|
||||
apdu_set_abort_handler(MyAbortHandler);
|
||||
@@ -139,7 +143,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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",
|
||||
filename);
|
||||
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"
|
||||
"accepting REAL, BOOLEAN, NULL, etc.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"If you want to RemoveListElement to the Recipient-List property in\n"
|
||||
"Notification Class 1 of Device 123, send the following command:\n"
|
||||
"%s 123 15 1 102 -1 4 100\n",
|
||||
@@ -287,8 +293,8 @@ int main(int argc, char *argv[])
|
||||
if (target_args == 0) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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",
|
||||
object_instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
@@ -305,8 +311,8 @@ int main(int argc, char *argv[])
|
||||
} else if (target_args == 2) {
|
||||
object_instance = strtoul(argv[argi], NULL, 0);
|
||||
if (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);
|
||||
return 1;
|
||||
}
|
||||
@@ -330,7 +336,8 @@ int main(int argc, char *argv[])
|
||||
property_array_index = strtol(argv[argi], NULL, 0);
|
||||
Target_Object_Array_Index = property_array_index;
|
||||
if (Verbose) {
|
||||
printf("Array_Index=%i=%s\n", property_array_index,
|
||||
printf(
|
||||
"Array_Index=%i=%s\n", property_array_index,
|
||||
argv[argi]);
|
||||
}
|
||||
target_args++;
|
||||
@@ -357,14 +364,16 @@ int main(int argc, char *argv[])
|
||||
} else if (tag_value_arg == 1) {
|
||||
value_string = argv[argi];
|
||||
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) {
|
||||
/* find the application tag for internal properties */
|
||||
property_tag = bacapp_known_property_tag(
|
||||
Target_Object_Type, Target_Object_Property);
|
||||
} else if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: tag=%ld - it must be less than %u\n",
|
||||
property_tag, MAX_BACNET_APPLICATION_TAG);
|
||||
return 1;
|
||||
@@ -374,13 +383,15 @@ int main(int argc, char *argv[])
|
||||
status = bacapp_parse_application_data(
|
||||
property_tag, value_string, application_value);
|
||||
if (!status) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: unable to parse the tag value\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* FIXME: show the expected entry format for the tag */
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: unable to parse the known property"
|
||||
" \"%s\"\r\n",
|
||||
value_string);
|
||||
@@ -400,8 +411,7 @@ int main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
if (tag_value_arg != 0) {
|
||||
fprintf(
|
||||
stderr, "Error: invalid tag+value pair (%i).\n", tag_value_arg);
|
||||
fprintf(stderr, "Error: invalid tag+value pair (%i).\n", tag_value_arg);
|
||||
return 1;
|
||||
}
|
||||
/* setup my info */
|
||||
@@ -422,7 +432,8 @@ int main(int argc, char *argv[])
|
||||
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||
if (found) {
|
||||
if (Verbose) {
|
||||
printf("Found Device %u in address_cache.\n",
|
||||
printf(
|
||||
"Found Device %u in address_cache.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
} else {
|
||||
@@ -435,7 +446,8 @@ int main(int argc, char *argv[])
|
||||
/* device is bound! */
|
||||
if (Request_Invoke_ID == 0) {
|
||||
if (Verbose) {
|
||||
printf("Sending RemoveListElement to Device %u.\n",
|
||||
printf(
|
||||
"Sending RemoveListElement to Device %u.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
Request_Invoke_ID = Send_Remove_List_Element_Request(
|
||||
|
||||
+40
-27
@@ -303,7 +303,8 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
|
||||
*
|
||||
* @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_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
@@ -347,7 +348,8 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
|
||||
DNET *dnet = NULL;
|
||||
|
||||
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);
|
||||
/* We don't need src information, since a message can't originate from
|
||||
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,
|
||||
* especially when ACKing receipt of this message type.
|
||||
*/
|
||||
static void send_initialize_routing_table_ack(
|
||||
uint8_t snet, const BACNET_ADDRESS *dst)
|
||||
static void
|
||||
send_initialize_routing_table_ack(uint8_t snet, const BACNET_ADDRESS *dst)
|
||||
{
|
||||
BACNET_ADDRESS dest;
|
||||
bool data_expecting_reply = false;
|
||||
@@ -415,8 +417,9 @@ static void send_initialize_routing_table_ack(
|
||||
} else {
|
||||
datalink_get_broadcast_address(&dest);
|
||||
}
|
||||
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
|
||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_encode_npdu_network(
|
||||
&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
|
||||
our downstream BACnet network. */
|
||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
||||
@@ -475,9 +478,9 @@ static void send_reject_message_to_network(
|
||||
} else {
|
||||
datalink_get_broadcast_address(&dest);
|
||||
}
|
||||
npdu_encode_npdu_network(&npdu_data,
|
||||
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, data_expecting_reply,
|
||||
MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_encode_npdu_network(
|
||||
&npdu_data, NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK,
|
||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
||||
/* We don't need src information, since a message can't originate from
|
||||
our downstream BACnet network. */
|
||||
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;
|
||||
|
||||
datalink_get_broadcast_address(&dest);
|
||||
npdu_encode_npdu_network(&npdu_data,
|
||||
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, data_expecting_reply,
|
||||
MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_encode_npdu_network(
|
||||
&npdu_data, NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
|
||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
||||
if (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.
|
||||
* @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_NPDU_DATA *npdu_data,
|
||||
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.
|
||||
* @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_NPDU_DATA *npdu_data,
|
||||
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_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_ADDRESS *src,
|
||||
BACNET_ADDRESS *dest,
|
||||
@@ -842,7 +848,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
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);
|
||||
}
|
||||
port = port->next;
|
||||
@@ -869,7 +876,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
npdu_len =
|
||||
npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu);
|
||||
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);
|
||||
} else {
|
||||
debug_printf(
|
||||
@@ -886,7 +894,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
npdu_len =
|
||||
npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu);
|
||||
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);
|
||||
}
|
||||
} else if (dest->net) {
|
||||
@@ -902,8 +911,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
if (port->net != snet) {
|
||||
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0],
|
||||
npdu_len + apdu_len);
|
||||
datalink_send_pdu(
|
||||
port->net, dest, npdu, &Tx_Buffer[0], npdu_len + apdu_len);
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
@@ -947,8 +956,9 @@ static void my_routing_npdu_handler(
|
||||
fprintf(stderr, "NPDU: Decoding failed; Discarded!\n");
|
||||
} else if (npdu_data.network_layer_message) {
|
||||
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
|
||||
network_control_handler(snet, src, &npdu_data,
|
||||
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||
network_control_handler(
|
||||
snet, src, &npdu_data, &pdu[apdu_offset],
|
||||
(uint16_t)(pdu_len - apdu_offset));
|
||||
} else {
|
||||
/* The DNET is set, but we don't support downstream routers,
|
||||
* so we just silently drop this network layer message,
|
||||
@@ -967,12 +977,14 @@ static void my_routing_npdu_handler(
|
||||
/* ConfirmedBroadcastReceived */
|
||||
/* then enter IDLE - ignore the PDU */
|
||||
} else {
|
||||
routed_apdu_handler(snet, &npdu_data, src, &dest,
|
||||
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||
routed_apdu_handler(
|
||||
snet, &npdu_data, src, &dest, &pdu[apdu_offset],
|
||||
(uint16_t)(pdu_len - apdu_offset));
|
||||
/* add a Device object and application layer */
|
||||
if ((dest.net == 0) ||
|
||||
(dest.net == BACNET_BROADCAST_NETWORK)) {
|
||||
apdu_handler(src, &pdu[apdu_offset],
|
||||
apdu_handler(
|
||||
src, &pdu[apdu_offset],
|
||||
(uint16_t)(pdu_len - apdu_offset));
|
||||
}
|
||||
}
|
||||
@@ -1026,8 +1038,9 @@ static void datalink_init(void)
|
||||
pEnv = getenv("BACNET_BIP6_BROADCAST");
|
||||
if (pEnv) {
|
||||
BACNET_IP6_ADDRESS addr;
|
||||
bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0,
|
||||
0, BIP6_MULTICAST_GROUP_ID);
|
||||
bvlc6_address_set(
|
||||
&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, 0,
|
||||
BIP6_MULTICAST_GROUP_ID);
|
||||
bip6_set_broadcast_addr(&addr);
|
||||
}
|
||||
if (!bip6_init(getenv("BACNET_BIP6_IFACE"))) {
|
||||
|
||||
+37
-26
@@ -324,7 +324,8 @@ static void datalink_get_broadcast_address(BACNET_ADDRESS *dest)
|
||||
*
|
||||
* @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_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
@@ -368,7 +369,8 @@ static void send_i_am_router_to_network(uint16_t snet, uint16_t net)
|
||||
DNET *dnet = NULL;
|
||||
|
||||
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);
|
||||
/* We don't need src information, since a message can't originate from
|
||||
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,
|
||||
* especially when ACKing receipt of this message type.
|
||||
*/
|
||||
static void send_initialize_routing_table_ack(
|
||||
uint8_t snet, const BACNET_ADDRESS *dst)
|
||||
static void
|
||||
send_initialize_routing_table_ack(uint8_t snet, const BACNET_ADDRESS *dst)
|
||||
{
|
||||
BACNET_ADDRESS dest;
|
||||
bool data_expecting_reply = false;
|
||||
@@ -436,8 +438,9 @@ static void send_initialize_routing_table_ack(
|
||||
} else {
|
||||
datalink_get_broadcast_address(&dest);
|
||||
}
|
||||
npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
|
||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_encode_npdu_network(
|
||||
&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
|
||||
our downstream BACnet network. */
|
||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
||||
@@ -496,9 +499,9 @@ static void send_reject_message_to_network(
|
||||
} else {
|
||||
datalink_get_broadcast_address(&dest);
|
||||
}
|
||||
npdu_encode_npdu_network(&npdu_data,
|
||||
NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK, data_expecting_reply,
|
||||
MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_encode_npdu_network(
|
||||
&npdu_data, NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK,
|
||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
||||
/* We don't need src information, since a message can't originate from
|
||||
our downstream BACnet network. */
|
||||
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;
|
||||
|
||||
datalink_get_broadcast_address(&dest);
|
||||
npdu_encode_npdu_network(&npdu_data,
|
||||
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, data_expecting_reply,
|
||||
MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_encode_npdu_network(
|
||||
&npdu_data, NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
|
||||
data_expecting_reply, MESSAGE_PRIORITY_NORMAL);
|
||||
pdu_len = npdu_encode_pdu(&Tx_Buffer[0], &dest, NULL, &npdu_data);
|
||||
if (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.
|
||||
* @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_NPDU_DATA *npdu_data,
|
||||
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.
|
||||
* @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_NPDU_DATA *npdu_data,
|
||||
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_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_ADDRESS *src,
|
||||
BACNET_ADDRESS *dest,
|
||||
@@ -865,7 +871,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
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);
|
||||
}
|
||||
port = port->next;
|
||||
@@ -892,7 +899,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
npdu_len =
|
||||
npdu_encode_pdu(&Tx_Buffer[0], &local_dest, &router_src, npdu);
|
||||
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);
|
||||
} else {
|
||||
log_printf(
|
||||
@@ -909,7 +917,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
npdu_len =
|
||||
npdu_encode_pdu(&Tx_Buffer[0], &remote_dest, &router_src, npdu);
|
||||
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);
|
||||
}
|
||||
} else if (dest->net) {
|
||||
@@ -925,8 +934,8 @@ static void routed_apdu_handler(uint16_t snet,
|
||||
port = Router_Table_Head;
|
||||
while (port != NULL) {
|
||||
if (port->net != snet) {
|
||||
datalink_send_pdu(port->net, dest, npdu, &Tx_Buffer[0],
|
||||
npdu_len + apdu_len);
|
||||
datalink_send_pdu(
|
||||
port->net, dest, npdu, &Tx_Buffer[0], npdu_len + apdu_len);
|
||||
}
|
||||
port = port->next;
|
||||
}
|
||||
@@ -966,8 +975,9 @@ static void my_routing_npdu_handler(
|
||||
fprintf(stderr, "NPDU: Decoding failed; Discarded!\n");
|
||||
} else if (npdu_data.network_layer_message) {
|
||||
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
|
||||
network_control_handler(snet, src, &npdu_data,
|
||||
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||
network_control_handler(
|
||||
snet, src, &npdu_data, &pdu[apdu_offset],
|
||||
(uint16_t)(pdu_len - apdu_offset));
|
||||
} else {
|
||||
/* The DNET is set, but we don't support downstream routers,
|
||||
* so we just silently drop this network layer message,
|
||||
@@ -986,12 +996,14 @@ static void my_routing_npdu_handler(
|
||||
/* ConfirmedBroadcastReceived */
|
||||
/* then enter IDLE - ignore the PDU */
|
||||
} else {
|
||||
routed_apdu_handler(snet, &npdu_data, src, &dest,
|
||||
&pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
||||
routed_apdu_handler(
|
||||
snet, &npdu_data, src, &dest, &pdu[apdu_offset],
|
||||
(uint16_t)(pdu_len - apdu_offset));
|
||||
/* add a Device object and application layer */
|
||||
if ((dest.net == 0) ||
|
||||
(dest.net == BACNET_BROADCAST_NETWORK)) {
|
||||
apdu_handler(src, &pdu[apdu_offset],
|
||||
apdu_handler(
|
||||
src, &pdu[apdu_offset],
|
||||
(uint16_t)(pdu_len - apdu_offset));
|
||||
}
|
||||
}
|
||||
@@ -1151,7 +1163,6 @@ static void control_c_hooks(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef FUZZING
|
||||
/**
|
||||
* Main function of simple router demo.
|
||||
|
||||
+22
-13
@@ -18,8 +18,8 @@
|
||||
#ifdef TEST_PACKET
|
||||
uint8_t test_packet[] = { 0x81, 0x0a, 0x00, 0x16, /* BVLC header */
|
||||
0x01, 0x24, 0x00, 0x01, 0x01, 0x0b, 0xff, /* NPDU */
|
||||
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x19,
|
||||
0x55 }; /* APDU */
|
||||
0x00, 0x03, 0x01, 0x0c, 0x0c, 0x00, 0x00,
|
||||
0x00, 0x02, 0x19, 0x55 }; /* APDU */
|
||||
#endif
|
||||
|
||||
void *dl_ip_thread(void *pArgs)
|
||||
@@ -146,14 +146,16 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
|
||||
/* setup socket options */
|
||||
|
||||
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));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
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));
|
||||
if (status < 0) {
|
||||
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
|
||||
different ports. */
|
||||
status = setsockopt(ip_data->socket, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
port->iface, strlen(port->iface));
|
||||
status = setsockopt(
|
||||
ip_data->socket, SOL_SOCKET, SO_BINDTODEVICE, port->iface,
|
||||
strlen(port->iface));
|
||||
if (status < 0) {
|
||||
close(ip_data->socket);
|
||||
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_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));
|
||||
if (status < 0) {
|
||||
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 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));
|
||||
|
||||
return true;
|
||||
@@ -235,7 +240,8 @@ int dl_ip_send(
|
||||
buff_len += pdu_len;
|
||||
|
||||
/* 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));
|
||||
|
||||
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);
|
||||
/* see if there is a packet for us */
|
||||
if (ret > 0) {
|
||||
received_bytes = recvfrom(data->socket, (char *)&data->buff[0],
|
||||
data->max_buff, 0, (struct sockaddr *)&sin, &sin_len);
|
||||
received_bytes = recvfrom(
|
||||
data->socket, (char *)&data->buff[0], data->max_buff, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -319,7 +326,8 @@ int dl_ip_recv(
|
||||
(*msg_data)->pdu_len = buff_len;
|
||||
(*msg_data)->pdu = (uint8_t *)malloc((*msg_data)->pdu_len);
|
||||
/* 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);
|
||||
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 = (uint8_t *)malloc((*msg_data)->pdu_len);
|
||||
/* 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);
|
||||
memmove(&(*msg_data)->src, src, sizeof(BACNET_ADDRESS));
|
||||
} else {
|
||||
|
||||
+18
-23
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Datalink IP module
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Datalink IP module
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef UDPMODULE_H
|
||||
#define UDPMODULE_H
|
||||
|
||||
@@ -35,27 +35,22 @@ typedef struct ip_data {
|
||||
uint16_t max_buff;
|
||||
} IP_DATA;
|
||||
|
||||
void *dl_ip_thread(void *pArgs);
|
||||
|
||||
void *dl_ip_thread(
|
||||
void *pArgs);
|
||||
|
||||
bool dl_ip_init(
|
||||
ROUTER_PORT * port,
|
||||
IP_DATA * data);
|
||||
bool dl_ip_init(ROUTER_PORT *port, IP_DATA *data);
|
||||
|
||||
int dl_ip_send(
|
||||
IP_DATA * data,
|
||||
const BACNET_ADDRESS * dest,
|
||||
const uint8_t * pdu,
|
||||
IP_DATA *data,
|
||||
const BACNET_ADDRESS *dest,
|
||||
const uint8_t *pdu,
|
||||
unsigned pdu_len);
|
||||
|
||||
int dl_ip_recv(
|
||||
IP_DATA * data,
|
||||
MSG_DATA ** msg, /* on recieve fill up message */
|
||||
BACNET_ADDRESS * src,
|
||||
IP_DATA *data,
|
||||
MSG_DATA **msg, /* on recieve fill up message */
|
||||
BACNET_ADDRESS *src,
|
||||
unsigned timeout);
|
||||
|
||||
void dl_ip_cleanup(
|
||||
IP_DATA * data);
|
||||
void dl_ip_cleanup(IP_DATA *data);
|
||||
|
||||
#endif /* end of UDPMODULE_H */
|
||||
|
||||
+20
-12
@@ -140,8 +140,8 @@ int main(int argc, char *argv[])
|
||||
if (is_network_msg(bacmsg)) {
|
||||
msg_data->ref_count = 1;
|
||||
send_to_msgbox(msg_src, &msg_storage);
|
||||
} else if (msg_data->dest.net !=
|
||||
BACNET_BROADCAST_NETWORK) {
|
||||
} else if (
|
||||
msg_data->dest.net != BACNET_BROADCAST_NETWORK) {
|
||||
msg_data->ref_count = 1;
|
||||
port =
|
||||
find_dnet(msg_data->dest.net, &msg_data->dest);
|
||||
@@ -212,7 +212,8 @@ bool read_config(const char *filepath)
|
||||
|
||||
/* open configuration file */
|
||||
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_destroy(&cfg);
|
||||
return false;
|
||||
@@ -261,13 +262,15 @@ bool read_config(const char *filepath)
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, current->iface,
|
||||
strncpy(
|
||||
ifr.ifr_name, current->iface,
|
||||
sizeof(ifr.ifr_name) - 1);
|
||||
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
||||
if (result != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
PRINT(
|
||||
ERROR,
|
||||
"Error: Invalid interface for BIP device\n");
|
||||
return false;
|
||||
}
|
||||
@@ -304,7 +307,8 @@ bool read_config(const char *filepath)
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
PRINT(
|
||||
ERROR,
|
||||
"Error: Invalid interface for MSTP device\n");
|
||||
return false;
|
||||
}
|
||||
@@ -465,13 +469,15 @@ bool parse_cmd(int argc, char *argv[])
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, current->iface,
|
||||
strncpy(
|
||||
ifr.ifr_name, current->iface,
|
||||
sizeof(ifr.ifr_name) - 1);
|
||||
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
||||
if (result != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
PRINT(
|
||||
ERROR,
|
||||
"Error: Invalid interface for BIP device \n");
|
||||
return false;
|
||||
}
|
||||
@@ -520,7 +526,8 @@ bool parse_cmd(int argc, char *argv[])
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
PRINT(
|
||||
ERROR,
|
||||
"Error: Invalid interface for MSTP device\n");
|
||||
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));
|
||||
|
||||
apdu_offset = bacnet_npdu_decode(data->pdu, data->pdu_len, &data->dest,
|
||||
&addr, &npdu_data);
|
||||
apdu_offset = bacnet_npdu_decode(
|
||||
data->pdu, data->pdu_len, &data->dest, &addr, &npdu_data);
|
||||
apdu_len = data->pdu_len - apdu_offset;
|
||||
|
||||
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);
|
||||
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 */
|
||||
|
||||
} else {
|
||||
|
||||
+16
-31
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Message queue module
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Message queue module
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef MSGQUEUE_H
|
||||
#define MSGQUEUE_H
|
||||
|
||||
@@ -27,16 +27,9 @@ extern pthread_mutex_t msg_lock;
|
||||
|
||||
typedef int MSGBOX_ID;
|
||||
|
||||
typedef enum {
|
||||
DATA = 1,
|
||||
SERVICE
|
||||
} MSGTYPE;
|
||||
typedef enum { DATA = 1, SERVICE } MSGTYPE;
|
||||
|
||||
typedef enum {
|
||||
SHUTDOWN,
|
||||
CHG_IP,
|
||||
CHG_MAC
|
||||
} MSGSUBTYPE;
|
||||
typedef enum { SHUTDOWN, CHG_IP, CHG_MAC } MSGSUBTYPE;
|
||||
|
||||
typedef struct _message {
|
||||
MSGTYPE type;
|
||||
@@ -58,25 +51,17 @@ typedef struct _msg_data {
|
||||
MSGBOX_ID create_msgbox(void);
|
||||
|
||||
/* returns sent byte count */
|
||||
bool send_to_msgbox(
|
||||
MSGBOX_ID dest,
|
||||
BACMSG * msg);
|
||||
bool send_to_msgbox(MSGBOX_ID dest, BACMSG *msg);
|
||||
|
||||
/* returns received message */
|
||||
BACMSG *recv_from_msgbox(
|
||||
MSGBOX_ID src,
|
||||
BACMSG * msg,
|
||||
int flags);
|
||||
BACMSG *recv_from_msgbox(MSGBOX_ID src, BACMSG *msg, int flags);
|
||||
|
||||
void del_msgbox(
|
||||
MSGBOX_ID msgboxid);
|
||||
void del_msgbox(MSGBOX_ID msgboxid);
|
||||
|
||||
/* free message data structure */
|
||||
void free_data(
|
||||
MSG_DATA * data);
|
||||
void free_data(MSG_DATA *data);
|
||||
|
||||
/* check message reference counter and delete data if needed */
|
||||
void check_data(
|
||||
MSG_DATA * data);
|
||||
void check_data(MSG_DATA *data);
|
||||
|
||||
#endif /* end of MSGQUEUE_H */
|
||||
|
||||
@@ -105,8 +105,9 @@ void *dl_mstp_thread(void *pArgs)
|
||||
msg_data->dest.mac_len = 1;
|
||||
}
|
||||
|
||||
dlmstp_send_pdu(&mstp_port, &(msg_data->dest),
|
||||
msg_data->pdu, msg_data->pdu_len);
|
||||
dlmstp_send_pdu(
|
||||
&mstp_port, &(msg_data->dest), msg_data->pdu,
|
||||
msg_data->pdu_len);
|
||||
|
||||
check_data(msg_data);
|
||||
|
||||
@@ -129,13 +130,15 @@ void *dl_mstp_thread(void *pArgs)
|
||||
|
||||
if (pdu_len > 0) {
|
||||
msg_data = (MSG_DATA *)malloc(sizeof(MSG_DATA));
|
||||
memmove(&(msg_data->src),
|
||||
memmove(
|
||||
&(msg_data->src),
|
||||
(const void *)&(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.len = 1;
|
||||
msg_data->pdu = (uint8_t *)malloc(pdu_len);
|
||||
memmove(msg_data->pdu,
|
||||
memmove(
|
||||
msg_data->pdu,
|
||||
(const void *)&(shared_port_data.Receive_Packet.pdu),
|
||||
pdu_len);
|
||||
msg_data->pdu_len = pdu_len;
|
||||
|
||||
+10
-11
@@ -1,19 +1,18 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Datalink for MS/TP module
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Datalink for MS/TP module
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef MSTPMODULE_H
|
||||
#define MSTPMODULE_H
|
||||
|
||||
#include "portthread.h"
|
||||
|
||||
void *dl_mstp_thread(
|
||||
void *pArgs);
|
||||
void *dl_mstp_thread(void *pArgs);
|
||||
|
||||
#endif /* end of MSTPMODULE_H */
|
||||
|
||||
+20
-12
@@ -14,8 +14,8 @@
|
||||
#include "network_layer.h"
|
||||
#include "bacnet/bacint.h"
|
||||
|
||||
uint16_t process_network_message(
|
||||
const BACMSG *msg, MSG_DATA *data, uint8_t **buff)
|
||||
uint16_t
|
||||
process_network_message(const BACMSG *msg, MSG_DATA *data, uint8_t **buff)
|
||||
{
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
ROUTER_PORT *srcport;
|
||||
@@ -28,8 +28,8 @@ uint16_t process_network_message(
|
||||
|
||||
memmove(data, msg->data, sizeof(MSG_DATA));
|
||||
|
||||
apdu_offset = bacnet_npdu_decode(data->pdu, data->pdu_len, &data->dest,
|
||||
NULL, &npdu_data);
|
||||
apdu_offset = bacnet_npdu_decode(
|
||||
data->pdu, data->pdu_len, &data->dest, NULL, &npdu_data);
|
||||
apdu_len = data->pdu_len - apdu_offset;
|
||||
|
||||
srcport = find_snet(msg->origin);
|
||||
@@ -71,9 +71,11 @@ uint16_t process_network_message(
|
||||
int net_count = apdu_len / 2;
|
||||
int 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 */
|
||||
add_dnet(&srcport->route_info, net,
|
||||
add_dnet(
|
||||
&srcport->route_info, net,
|
||||
data->src); /* and update routing table */
|
||||
}
|
||||
break;
|
||||
@@ -110,9 +112,11 @@ uint16_t process_network_message(
|
||||
int net_count = data->pdu[apdu_offset];
|
||||
while (net_count--) {
|
||||
int i = 1;
|
||||
decode_unsigned16(&data->pdu[apdu_offset + i],
|
||||
decode_unsigned16(
|
||||
&data->pdu[apdu_offset + i],
|
||||
&net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net,
|
||||
add_dnet(
|
||||
&srcport->route_info, net,
|
||||
data->src); /* and update routing table */
|
||||
if (data->pdu[apdu_offset + i + 3] >
|
||||
0) { /* find next NET value */
|
||||
@@ -135,9 +139,11 @@ uint16_t process_network_message(
|
||||
int net_count = data->pdu[apdu_offset];
|
||||
while (net_count--) {
|
||||
int i = 1;
|
||||
decode_unsigned16(&data->pdu[apdu_offset + i],
|
||||
decode_unsigned16(
|
||||
&data->pdu[apdu_offset + i],
|
||||
&net); /* decode received NET values */
|
||||
add_dnet(&srcport->route_info, net,
|
||||
add_dnet(
|
||||
&srcport->route_info, net,
|
||||
data->src); /* and update routing table */
|
||||
if (data->pdu[apdu_offset + i + 3] >
|
||||
0) { /* find next NET value */
|
||||
@@ -299,7 +305,8 @@ uint16_t create_network_message(
|
||||
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,
|
||||
uint8_t **buff,
|
||||
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,
|
||||
bool data_expecting_reply)
|
||||
{
|
||||
|
||||
+16
-18
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Network layer for BACnet routing
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Network layer for BACnet routing
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef NETWORK_LAYER_H
|
||||
#define NETWORK_LAYER_H
|
||||
|
||||
@@ -24,25 +24,23 @@
|
||||
#include "bacport.h"
|
||||
#include "portthread.h"
|
||||
|
||||
uint16_t process_network_message(
|
||||
const BACMSG * msg,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff);
|
||||
uint16_t
|
||||
process_network_message(const BACMSG *msg, MSG_DATA *data, uint8_t **buff);
|
||||
|
||||
uint16_t create_network_message(
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff,
|
||||
void *val);
|
||||
|
||||
void send_network_message(
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff,
|
||||
MSG_DATA *data,
|
||||
uint8_t **buff,
|
||||
void *val);
|
||||
|
||||
void init_npdu(
|
||||
BACNET_NPDU_DATA * npdu_data,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
BACNET_NETWORK_MESSAGE_TYPE network_message_type,
|
||||
bool data_expecting_reply);
|
||||
|
||||
|
||||
+20
-39
@@ -1,13 +1,13 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Network port storage and handling
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief Network port storage and handling
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef PORTTHREAD_H
|
||||
#define PORTTHREAD_H
|
||||
|
||||
@@ -27,33 +27,21 @@
|
||||
|
||||
#define DEBUG_LEVEL 3
|
||||
#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
|
||||
#define PRINT(...)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
BIP = 1,
|
||||
MSTP = 2
|
||||
} DL_TYPE;
|
||||
typedef enum { BIP = 1, MSTP = 2 } DL_TYPE;
|
||||
|
||||
typedef enum {
|
||||
INIT,
|
||||
INIT_FAILED,
|
||||
RUNNING,
|
||||
FINISHED
|
||||
} PORT_STATE;
|
||||
typedef enum { INIT, INIT_FAILED, RUNNING, FINISHED } PORT_STATE;
|
||||
|
||||
/* router port thread function */
|
||||
typedef void *(
|
||||
*PORT_FUNC) (
|
||||
void *);
|
||||
typedef void *(*PORT_FUNC)(void *);
|
||||
|
||||
typedef enum {
|
||||
PARITY_NONE,
|
||||
PARITY_EVEN,
|
||||
PARITY_ODD
|
||||
} PARITY;
|
||||
typedef enum { PARITY_NONE, PARITY_EVEN, PARITY_ODD } PARITY;
|
||||
|
||||
/* port specific parameters */
|
||||
typedef union _port_params {
|
||||
@@ -103,21 +91,14 @@ extern ROUTER_PORT *head;
|
||||
extern int port_count;
|
||||
|
||||
/* get recieving router port */
|
||||
ROUTER_PORT *find_snet(
|
||||
MSGBOX_ID id);
|
||||
ROUTER_PORT *find_snet(MSGBOX_ID id);
|
||||
|
||||
/* get sending router port */
|
||||
ROUTER_PORT *find_dnet(
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS * addr);
|
||||
ROUTER_PORT *find_dnet(uint16_t net, BACNET_ADDRESS *addr);
|
||||
|
||||
/* add reacheble network for specified router port */
|
||||
void add_dnet(
|
||||
RT_ENTRY * route_info,
|
||||
uint16_t net,
|
||||
BACNET_ADDRESS addr);
|
||||
void add_dnet(RT_ENTRY *route_info, uint16_t net, BACNET_ADDRESS addr);
|
||||
|
||||
void cleanup_dnets(
|
||||
DNET * dnets);
|
||||
void cleanup_dnets(DNET *dnets);
|
||||
|
||||
#endif /* end of PORTTHREAD_H */
|
||||
|
||||
+40
-23
@@ -59,14 +59,16 @@ BACNET_SUBSCRIBE_COV_DATA *COV_Subscribe_Data = NULL;
|
||||
static bool Simple_Ack_Detected = false;
|
||||
static bool Cancel_Requested = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -79,18 +81,19 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Abort: %s\n",
|
||||
bactext_abort_reason_name((int)abort_reason));
|
||||
printf(
|
||||
"BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -102,7 +105,8 @@ static void My_Unconfirmed_COV_Notification_Handler(
|
||||
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,
|
||||
BACNET_ADDRESS *src,
|
||||
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);
|
||||
}
|
||||
|
||||
static void MyWritePropertySimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -135,9 +139,11 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* 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);
|
||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
|
||||
apdu_set_unconfirmed_handler(
|
||||
SERVICE_UNCONFIRMED_COV_NOTIFICATION,
|
||||
My_Unconfirmed_COV_Notification_Handler);
|
||||
/* handle the Simple ack coming back from SubscribeCOV */
|
||||
apdu_set_confirmed_simple_ack_handler(
|
||||
@@ -163,7 +169,8 @@ static void cleanup(void)
|
||||
|
||||
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",
|
||||
filename);
|
||||
}
|
||||
@@ -202,16 +209,22 @@ static void print_help(const char *filename)
|
||||
"This shall indicate a cancellation request.\n");
|
||||
printf("\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"
|
||||
"you could send the following command:\n"
|
||||
"%s 123 0 9 1 confirmed 600\n", filename);
|
||||
printf("To send the same COV subscription request for unconfirmed\n"
|
||||
"%s 123 0 9 1 confirmed 600\n",
|
||||
filename);
|
||||
printf(
|
||||
"To send the same COV subscription request for unconfirmed\n"
|
||||
"notifications, send the following command:\n"
|
||||
"%s 123 0 9 1 unconfirmed 600\n", filename);
|
||||
printf("To cancel the same COV subscription request,\n"
|
||||
"%s 123 0 9 1 unconfirmed 600\n",
|
||||
filename);
|
||||
printf(
|
||||
"To cancel the same COV subscription request,\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[])
|
||||
@@ -255,7 +268,8 @@ int main(int argc, char *argv[])
|
||||
/* decode the command line parameters */
|
||||
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -271,7 +285,8 @@ int main(int argc, char *argv[])
|
||||
cov_data->monitoredObjectIdentifier.type = (uint16_t)uint;
|
||||
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);
|
||||
return 1;
|
||||
@@ -281,7 +296,8 @@ int main(int argc, char *argv[])
|
||||
strtol(argv[argi], NULL, 0);
|
||||
if (cov_data->monitoredObjectIdentifier.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,
|
||||
BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
@@ -376,7 +392,8 @@ int main(int argc, char *argv[])
|
||||
/* increase the timeout to the longest lifetime */
|
||||
timeout_seconds = cov_data->lifetime;
|
||||
}
|
||||
printf("Sent SubscribeCOV request. "
|
||||
printf(
|
||||
"Sent SubscribeCOV request. "
|
||||
" Waiting up to %u seconds....\n",
|
||||
(unsigned)(timeout_seconds - elapsed_seconds));
|
||||
} else if (tsm_invoke_id_free(Request_Invoke_ID)) {
|
||||
|
||||
+18
-10
@@ -68,7 +68,8 @@ static void print_help(const char *filename)
|
||||
"you are reading. For example, if you were reading\n"
|
||||
"Analog Output 2, the object-instance would be 2.\n");
|
||||
PRINTF("\n");
|
||||
PRINTF("Example:\n"
|
||||
PRINTF(
|
||||
"Example:\n"
|
||||
"If you want read the Present-Value of Analog Output 101\n"
|
||||
"in Device 123, you could send either of the following\n"
|
||||
"commands:\n"
|
||||
@@ -125,8 +126,9 @@ int main(int argc, char *argv[])
|
||||
if (++argi < argc) {
|
||||
device_id = strtol(argv[argi], NULL, 0);
|
||||
if (device_id > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr, "device=%u - not greater than %u\n",
|
||||
device_id, BACNET_MAX_INSTANCE);
|
||||
fprintf(
|
||||
stderr, "device=%u - not greater than %u\n", device_id,
|
||||
BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -161,11 +163,13 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
Device_Set_Object_Instance_Number(device_id);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
PRINTF("BACnet Server-Client Demo\n"
|
||||
PRINTF(
|
||||
"BACnet Server-Client Demo\n"
|
||||
"BACnet Stack Version %s\n"
|
||||
"BACnet Device ID: %u\n"
|
||||
"Max APDU: %d\n",
|
||||
@@ -175,8 +179,9 @@ int main(int argc, char *argv[])
|
||||
atexit(datalink_cleanup);
|
||||
bacnet_task_init();
|
||||
bacnet_data_poll_seconds_set(print_seconds);
|
||||
if (!bacnet_data_object_add(target_device_object_instance,
|
||||
target_object_type, target_object_instance)) {
|
||||
if (!bacnet_data_object_add(
|
||||
target_device_object_instance, target_object_type,
|
||||
target_object_instance)) {
|
||||
return 1;
|
||||
}
|
||||
mstimer_set(&print_value_timer, print_seconds * 1000);
|
||||
@@ -192,7 +197,8 @@ int main(int argc, char *argv[])
|
||||
if (bacnet_data_analog_present_value(
|
||||
target_device_object_instance, target_object_type,
|
||||
target_object_instance, &float_value)) {
|
||||
PRINTF("Device %u %s-%u=%f\n",
|
||||
PRINTF(
|
||||
"Device %u %s-%u=%f\n",
|
||||
(unsigned)target_device_object_instance,
|
||||
bactext_object_type_name(target_object_type),
|
||||
(unsigned)target_object_instance, float_value);
|
||||
@@ -204,7 +210,8 @@ int main(int argc, char *argv[])
|
||||
if (bacnet_data_binary_present_value(
|
||||
target_device_object_instance, target_object_type,
|
||||
target_object_instance, &bool_value)) {
|
||||
PRINTF("Device %u %s-%u=%s\n",
|
||||
PRINTF(
|
||||
"Device %u %s-%u=%s\n",
|
||||
(unsigned)target_device_object_instance,
|
||||
bactext_object_type_name(target_object_type),
|
||||
(unsigned)target_object_instance,
|
||||
@@ -217,7 +224,8 @@ int main(int argc, char *argv[])
|
||||
if (bacnet_data_multistate_present_value(
|
||||
target_device_object_instance, target_object_type,
|
||||
target_object_instance, &unsigned_value)) {
|
||||
PRINTF("Device %u %s-%u=%u\n",
|
||||
PRINTF(
|
||||
"Device %u %s-%u=%u\n",
|
||||
(unsigned)target_device_object_instance,
|
||||
bactext_object_type_name(target_object_type),
|
||||
(unsigned)target_object_instance,
|
||||
|
||||
+15
-10
@@ -80,8 +80,9 @@ static void print_discovered_devices(void)
|
||||
milliseconds = bacnet_discover_device_elapsed_milliseconds(device_id);
|
||||
heap_ram = bacnet_discover_device_memory(device_id);
|
||||
/* convert to KB next highest value */
|
||||
bacnet_discover_property_name(device_id, OBJECT_DEVICE, device_id,
|
||||
PROP_MODEL_NAME, model_name, sizeof(model_name), "");
|
||||
bacnet_discover_property_name(
|
||||
device_id, OBJECT_DEVICE, device_id, PROP_MODEL_NAME, model_name,
|
||||
sizeof(model_name), "");
|
||||
printf(
|
||||
"device[%u] %7u \"%s\" object_list[%d] in %lums using %lu bytes\n",
|
||||
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)) {
|
||||
property_count = bacnet_discover_object_property_count(
|
||||
device_id, object_id.type, object_id.instance);
|
||||
bacnet_discover_property_name(device_id, object_id.type,
|
||||
object_id.instance, PROP_OBJECT_NAME, object_name,
|
||||
sizeof(object_name), "");
|
||||
printf(" object_list[%d] %s %u \"%s\" has %u properties\n",
|
||||
bacnet_discover_property_name(
|
||||
device_id, object_id.type, object_id.instance,
|
||||
PROP_OBJECT_NAME, object_name, sizeof(object_name), "");
|
||||
printf(
|
||||
" object_list[%d] %s %u \"%s\" has %u properties\n",
|
||||
object_index, bactext_object_type_name(object_id.type),
|
||||
object_id.instance, object_name, property_count);
|
||||
}
|
||||
@@ -160,7 +162,8 @@ static void bacnet_server_init(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
|
||||
/* 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);
|
||||
mstimer_set(&BACnet_Task_Timer, 1000);
|
||||
mstimer_set(&BACnet_TSM_Timer, 50);
|
||||
@@ -254,12 +257,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
if (device_id > BACNET_MAX_INSTANCE) {
|
||||
debug_perror("device-instance=%u - not greater than %u\n",
|
||||
device_id, BACNET_MAX_INSTANCE);
|
||||
debug_perror(
|
||||
"device-instance=%u - not greater than %u\n", device_id,
|
||||
BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
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 Device ID: %u\n"
|
||||
"DNET: %u every %lu seconds\n"
|
||||
|
||||
+30
-23
@@ -106,16 +106,15 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||
#define LIGHTING_OBJECT_RELAY OBJECT_BINARY_OUTPUT
|
||||
#endif
|
||||
|
||||
static BACNET_SUBORDINATE_DATA Lighting_Subordinate[] =
|
||||
{
|
||||
{0, LIGHTING_OBJECT_WATTS, 1, "watt-hours", 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_LIGHT, 1, "light", 0, 0, NULL},
|
||||
{0, LIGHTING_OBJECT_RELAY, 1, "relay", 0, 0, NULL},
|
||||
static BACNET_SUBORDINATE_DATA Lighting_Subordinate[] = {
|
||||
{ 0, LIGHTING_OBJECT_WATTS, 1, "watt-hours", 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_LIGHT, 1, "light", 0, 0, NULL },
|
||||
{ 0, LIGHTING_OBJECT_RELAY, 1, "relay", 0, 0, NULL },
|
||||
#if (BACNET_PROTOCOL_REVISION >= 24)
|
||||
{0, OBJECT_COLOR, 1, "color", 0, 0, NULL},
|
||||
{0, OBJECT_COLOR_TEMPERATURE, 1, "color-temperature", 0, 0, NULL},
|
||||
{ 0, OBJECT_COLOR, 1, "color", 0, 0, NULL },
|
||||
{ 0, OBJECT_COLOR_TEMPERATURE, 1, "color-temperature", 0, 0, NULL },
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -132,8 +131,8 @@ static void Structured_View_Update(void)
|
||||
device_id = Device_Object_Instance_Number();
|
||||
for (i = 0; i < ARRAY_SIZE(Lighting_Subordinate); i++) {
|
||||
/* link the lists */
|
||||
if (i < (ARRAY_SIZE(Lighting_Subordinate)-1)) {
|
||||
Lighting_Subordinate[i].next = &Lighting_Subordinate[i+1];
|
||||
if (i < (ARRAY_SIZE(Lighting_Subordinate) - 1)) {
|
||||
Lighting_Subordinate[i].next = &Lighting_Subordinate[i + 1];
|
||||
}
|
||||
/* update the device instance to internal */
|
||||
Lighting_Subordinate[i].Device_Instance = device_id;
|
||||
@@ -168,7 +167,8 @@ static void Init_Service_Handlers(void)
|
||||
for (i = 0; i <= BACNET_OBJECT_TYPE_LAST; i++) {
|
||||
object_data.object_type = i;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -224,10 +224,12 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_unconfirmed_handler(
|
||||
SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification);
|
||||
/* 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);
|
||||
/* 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);
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
apdu_set_confirmed_handler(
|
||||
@@ -247,10 +249,10 @@ static void Init_Service_Handlers(void)
|
||||
/* configure the cyclic timers */
|
||||
mstimer_set(&BACnet_Task_Timer, 1000UL);
|
||||
mstimer_set(&BACnet_TSM_Timer, 50UL);
|
||||
mstimer_set(&BACnet_Address_Timer, 60UL*1000UL);
|
||||
mstimer_set(&BACnet_Address_Timer, 60UL * 1000UL);
|
||||
mstimer_set(&BACnet_Object_Timer, 100UL);
|
||||
#if defined(INTRINSIC_REPORTING)
|
||||
mstimer_set(&BACnet_Notification_Timer, NC_RESCAN_RECIPIENTS_SECS*1000UL);
|
||||
mstimer_set(&BACnet_Notification_Timer, NC_RESCAN_RECIPIENTS_SECS * 1000UL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -269,10 +271,12 @@ static void print_help(const char *filename)
|
||||
"device-name:\n"
|
||||
"The Device object-name is the text name for the device.\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",
|
||||
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",
|
||||
filename);
|
||||
}
|
||||
@@ -325,8 +329,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#if defined(BAC_UCI)
|
||||
ctx = ucix_init("bacnet_dev");
|
||||
if (!ctx)
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Failed to load config file bacnet_dev\n");
|
||||
}
|
||||
uciId = ucix_get_option_int(ctx, "bacnet_dev", "0", "Id", 0);
|
||||
if (uciId != 0) {
|
||||
Device_Set_Object_Instance_Number(uciId);
|
||||
@@ -342,7 +347,8 @@ int main(int argc, char *argv[])
|
||||
ucix_cleanup(ctx);
|
||||
#endif /* defined(BAC_UCI) */
|
||||
|
||||
printf("BACnet Server Demo\n"
|
||||
printf(
|
||||
"BACnet Server Demo\n"
|
||||
"BACnet Stack Version %s\n"
|
||||
"BACnet Device ID: %u\n"
|
||||
"Max APDU: %d\n",
|
||||
@@ -357,8 +363,9 @@ int main(int argc, char *argv[])
|
||||
#if defined(BAC_UCI)
|
||||
const char *uciname;
|
||||
ctx = ucix_init("bacnet_dev");
|
||||
if (!ctx)
|
||||
if (!ctx) {
|
||||
fprintf(stderr, "Failed to load config file bacnet_dev\n");
|
||||
}
|
||||
uciname = ucix_get_option(ctx, "bacnet_dev", "0", "Name");
|
||||
if (uciname != 0) {
|
||||
Device_Object_Name_ANSI_Init(uciname);
|
||||
@@ -390,7 +397,7 @@ int main(int argc, char *argv[])
|
||||
if (mstimer_expired(&BACnet_Task_Timer)) {
|
||||
mstimer_reset(&BACnet_Task_Timer);
|
||||
elapsed_milliseconds = mstimer_interval(&BACnet_Task_Timer);
|
||||
elapsed_seconds = elapsed_milliseconds/1000;
|
||||
elapsed_seconds = elapsed_milliseconds / 1000;
|
||||
/* 1 second tasks */
|
||||
dcc_timer_seconds(elapsed_seconds);
|
||||
datalink_maintenance_timer(elapsed_seconds);
|
||||
@@ -413,7 +420,7 @@ int main(int argc, char *argv[])
|
||||
if (mstimer_expired(&BACnet_Address_Timer)) {
|
||||
mstimer_reset(&BACnet_Address_Timer);
|
||||
elapsed_milliseconds = mstimer_interval(&BACnet_Address_Timer);
|
||||
elapsed_seconds = elapsed_milliseconds/1000;
|
||||
elapsed_seconds = elapsed_milliseconds / 1000;
|
||||
address_cache_timer(elapsed_seconds);
|
||||
}
|
||||
handler_cov_task();
|
||||
|
||||
+10
-7
@@ -50,8 +50,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(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 Ethernet MAC in hex like 00:21:70:7e:32:bb\n");
|
||||
printf("\n");
|
||||
printf("Examples:\n"
|
||||
printf(
|
||||
"Examples:\n"
|
||||
"Send a TimeSynchronization request to DNET 123:\n"
|
||||
"%s --dnet 123\n",
|
||||
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"
|
||||
"%s --mac 10.0.0.1 --dnet 123 --dadr 5\n",
|
||||
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",
|
||||
filename);
|
||||
}
|
||||
@@ -255,7 +257,8 @@ int main(int argc, char *argv[])
|
||||
atexit(datalink_cleanup);
|
||||
mstimer_init();
|
||||
/* 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);
|
||||
if (use_utc) {
|
||||
/* convert to UTC */
|
||||
@@ -263,8 +266,8 @@ int main(int argc, char *argv[])
|
||||
dst_adjust_minutes = -60;
|
||||
}
|
||||
datetime_set(&local_time, &bdate, &btime);
|
||||
datetime_local_to_utc(&utc_time, &local_time, utc_offset_minutes,
|
||||
dst_adjust_minutes);
|
||||
datetime_local_to_utc(
|
||||
&utc_time, &local_time, utc_offset_minutes, dst_adjust_minutes);
|
||||
Send_TimeSyncUTC_Remote(&dest, &utc_time.date, &utc_time.time);
|
||||
} else {
|
||||
Send_TimeSync_Remote(&dest, &bdate, &btime);
|
||||
|
||||
+27
-17
@@ -52,8 +52,10 @@ static void print_usage(const char *filename)
|
||||
printf("Sends a BACnet Unconfirmed Change-of-Value Notification\n"
|
||||
"to the network.\n");
|
||||
printf("\n");
|
||||
printf("Usage: %s pid device-id object-type object-instance "
|
||||
"time property tag value [priority] [index]\n", filename);
|
||||
printf(
|
||||
"Usage: %s pid device-id object-type object-instance "
|
||||
"time property tag value [priority] [index]\n",
|
||||
filename);
|
||||
printf("\n");
|
||||
printf("pid:\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"
|
||||
"Value property, use present-value or 85 as the property.\n");
|
||||
printf("\n");
|
||||
printf("tag:\n"
|
||||
printf(
|
||||
"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"
|
||||
"monitoring. For example, if you were monitoring a REAL value,\n"
|
||||
"you would use a tag of 4.\n");
|
||||
printf("\n");
|
||||
printf("value:\n"
|
||||
printf(
|
||||
"value:\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"
|
||||
"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"
|
||||
"priority (16) if the object property supports priorities.\n");
|
||||
printf("\n");
|
||||
printf("[index]\n"
|
||||
printf(
|
||||
"[index]\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");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\n"
|
||||
"If you want generate an unconfirmed COV,\n"
|
||||
"you could send one of the following command:\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) {
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
if (cov_data.monitoredObjectIdentifier.instance > BACNET_MAX_INSTANCE) {
|
||||
fprintf(stderr, "object-instance=%u - not greater than %u\n",
|
||||
cov_data.monitoredObjectIdentifier.instance,
|
||||
BACNET_MAX_INSTANCE);
|
||||
fprintf(
|
||||
stderr, "object-instance=%u - not greater than %u\n",
|
||||
cov_data.monitoredObjectIdentifier.instance, BACNET_MAX_INSTANCE);
|
||||
return 1;
|
||||
}
|
||||
if (cov_data.listOfValues->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
|
||||
fprintf(stderr, "property-identifier=%u - not greater than %u\n",
|
||||
cov_data.listOfValues->propertyIdentifier,
|
||||
MAX_BACNET_PROPERTY_ID);
|
||||
fprintf(
|
||||
stderr, "property-identifier=%u - not greater than %u\n",
|
||||
cov_data.listOfValues->propertyIdentifier, MAX_BACNET_PROPERTY_ID);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -200,8 +209,9 @@ int main(int argc, char *argv[])
|
||||
Init_Service_Handlers();
|
||||
dlenv_init();
|
||||
atexit(datalink_cleanup);
|
||||
Send_UCOV_Notify(&Handler_Transmit_Buffer[0],
|
||||
sizeof(Handler_Transmit_Buffer), &cov_data);
|
||||
Send_UCOV_Notify(
|
||||
&Handler_Transmit_Buffer[0], sizeof(Handler_Transmit_Buffer),
|
||||
&cov_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+4
-3
@@ -51,7 +51,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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"
|
||||
" sequence-number notification-class priority event-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_FLOATING_LIMIT) {
|
||||
} else if (event_data.eventType == EVENT_OUT_OF_RANGE) {
|
||||
} else if (event_data.eventType ==
|
||||
EVENT_CHANGE_OF_LIFE_SAFETY) {
|
||||
} else if (
|
||||
event_data.eventType == EVENT_CHANGE_OF_LIFE_SAFETY) {
|
||||
} else if (event_data.eventType == EVENT_EXTENDED) {
|
||||
} else if (event_data.eventType == EVENT_BUFFER_READY) {
|
||||
} else if (event_data.eventType == EVENT_UNSIGNED_RANGE) {
|
||||
|
||||
+24
-14
@@ -57,14 +57,16 @@ static uint8_t Request_Invoke_ID = 0;
|
||||
static BACNET_ADDRESS Target_Address;
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -77,18 +79,19 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Abort: %s\n",
|
||||
bactext_abort_reason_name((int)abort_reason));
|
||||
printf(
|
||||
"BACnet Abort: %s\n", bactext_abort_reason_name((int)abort_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -109,7 +112,8 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* 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);
|
||||
/* handle any errors coming back */
|
||||
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)
|
||||
{
|
||||
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",
|
||||
filename);
|
||||
}
|
||||
@@ -162,7 +167,8 @@ static void print_help(const char *filename)
|
||||
"If you were transferring an object identifier for Device 123,\n"
|
||||
"you would use 8:123 as the value.\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"
|
||||
"vendor 260 in Device 99, you could send the following command:\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);
|
||||
if ((!Target_Broadcast) &&
|
||||
(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);
|
||||
return 1;
|
||||
}
|
||||
@@ -241,7 +248,8 @@ int main(int argc, char *argv[])
|
||||
/* printf("tag[%d]=%u value[%d]=%s\n",
|
||||
i, property_tag, i, value_string); */
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -262,7 +270,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -320,7 +329,8 @@ int main(int argc, char *argv[])
|
||||
Send_UnconfirmedPrivateTransfer(&Target_Address, &private_data);
|
||||
printf("Sent PrivateTransfer.");
|
||||
if (timeout_seconds) {
|
||||
printf(" Waiting %u seconds.\n",
|
||||
printf(
|
||||
" Waiting %u seconds.\n",
|
||||
(unsigned)(timeout_seconds - elapsed_seconds));
|
||||
} else {
|
||||
printf("\n");
|
||||
|
||||
+20
-12
@@ -61,8 +61,8 @@ static void MyAbortHandler(
|
||||
* @param invoke_id [in] the invokeID from the rejected message
|
||||
* @param reject_reason [in] the reason for the rejection
|
||||
*/
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -71,7 +71,8 @@ static void MyRejectHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void My_Router_Handler(BACNET_ADDRESS *src,
|
||||
static void My_Router_Handler(
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *npdu,
|
||||
uint16_t npdu_len)
|
||||
@@ -104,7 +105,8 @@ static void My_Router_Handler(BACNET_ADDRESS *src,
|
||||
that are sent with a local unicast address. */
|
||||
if (npdu_len >= 2) {
|
||||
(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);
|
||||
} else {
|
||||
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 */
|
||||
uint16_t pdu_len)
|
||||
{ /* 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);
|
||||
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));
|
||||
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
|
||||
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) {
|
||||
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
|
||||
} else {
|
||||
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
debug_printf(
|
||||
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
npdu_data.protocol_version);
|
||||
}
|
||||
}
|
||||
@@ -186,8 +191,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
int index = 0;
|
||||
|
||||
if (argc > 0) {
|
||||
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3],
|
||||
&mac[4], &mac[5]);
|
||||
dst->mac_len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
@@ -203,8 +209,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
}
|
||||
if (dnet) {
|
||||
if (argc > 2) {
|
||||
count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
|
||||
&mac[2], &mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
dst->len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
@@ -236,7 +243,8 @@ int main(int argc, char *argv[])
|
||||
time_t timeout_seconds = 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"
|
||||
"MAC:\r\n"
|
||||
"Optional MAC address of router for unicast message\r\n"
|
||||
|
||||
+19
-12
@@ -56,8 +56,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -87,7 +87,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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",
|
||||
filename);
|
||||
}
|
||||
@@ -95,7 +96,8 @@ static void print_usage(const char *filename)
|
||||
static void print_help(const char *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"
|
||||
"The device-instance-min or max can be 0 to %d.\r\n"
|
||||
"\r\n"
|
||||
@@ -180,23 +182,27 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -210,12 +216,13 @@ int main(int argc, char *argv[])
|
||||
timeout_seconds = apdu_timeout() / 1000;
|
||||
/* send the request */
|
||||
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);
|
||||
} else {
|
||||
Send_WhoHas_Object(Target_Object_Instance_Min,
|
||||
Target_Object_Instance_Max, Target_Object_Type,
|
||||
Target_Object_Instance);
|
||||
Send_WhoHas_Object(
|
||||
Target_Object_Instance_Min, Target_Object_Instance_Max,
|
||||
Target_Object_Type, Target_Object_Instance);
|
||||
}
|
||||
/* loop forever */
|
||||
for (;;) {
|
||||
|
||||
+28
-15
@@ -120,7 +120,8 @@ static void my_i_am_handler(
|
||||
if (BACnet_Debug_Enabled) {
|
||||
fprintf(stderr, " from %lu, MAC = ", (unsigned long)device_id);
|
||||
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[3], (unsigned)src->mac[4],
|
||||
(unsigned)src->mac[5]);
|
||||
@@ -156,13 +157,14 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
(void)invoke_id;
|
||||
fprintf(stderr, "BACnet Reject: %s\n",
|
||||
fprintf(
|
||||
stderr, "BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name(reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -213,7 +215,8 @@ static void print_address_cache(void)
|
||||
/* NOTE: this string format is parsed by src/address.c,
|
||||
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");
|
||||
printf(";-------- -------------------- ----- -------------------- ----\n");
|
||||
|
||||
@@ -300,25 +303,32 @@ static void print_help(const char *filename)
|
||||
"Default delay is 100ms.\n");
|
||||
printf("\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",
|
||||
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",
|
||||
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",
|
||||
filename);
|
||||
printf("Send a WhoIs request to Device 123:\n"
|
||||
printf(
|
||||
"Send a WhoIs request to Device 123:\n"
|
||||
"%s 123\n",
|
||||
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",
|
||||
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",
|
||||
filename);
|
||||
printf("Send a WhoIs request to all devices:\n"
|
||||
printf(
|
||||
"Send a WhoIs request to all devices:\n"
|
||||
"%s\n",
|
||||
filename);
|
||||
}
|
||||
@@ -446,12 +456,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -491,7 +503,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
if (mstimer_expired(&apdu_timer)) {
|
||||
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);
|
||||
retry_count--;
|
||||
} else {
|
||||
|
||||
+20
-12
@@ -50,8 +50,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -60,7 +60,8 @@ static void MyRejectHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void My_Router_Handler(BACNET_ADDRESS *src,
|
||||
static void My_Router_Handler(
|
||||
BACNET_ADDRESS *src,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *npdu, /* PDU data */
|
||||
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 */
|
||||
uint16_t pdu_len)
|
||||
{ /* 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);
|
||||
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));
|
||||
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
|
||||
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) {
|
||||
debug_printf("NPDU: DNET=%d. Discarded!\n", dest.net);
|
||||
} else {
|
||||
debug_printf("NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
debug_printf(
|
||||
"NPDU: BACnet Protocol Version=%d. Discarded!\n",
|
||||
npdu_data.protocol_version);
|
||||
}
|
||||
}
|
||||
@@ -168,8 +172,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
int index = 0;
|
||||
|
||||
if (argc > 0) {
|
||||
count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3],
|
||||
&mac[4], &mac[5]);
|
||||
dst->mac_len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
@@ -185,8 +190,9 @@ static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
|
||||
}
|
||||
if (dnet) {
|
||||
if (argc > 2) {
|
||||
count = sscanf(argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
|
||||
&mac[2], &mac[3], &mac[4], &mac[5]);
|
||||
count = sscanf(
|
||||
argv[2], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2],
|
||||
&mac[3], &mac[4], &mac[5]);
|
||||
dst->len = count;
|
||||
for (index = 0; index < MAX_MAC_LEN; index++) {
|
||||
if (index < count) {
|
||||
@@ -222,7 +228,8 @@ int main(int argc, char *argv[])
|
||||
return 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"
|
||||
"DNET:\r\n"
|
||||
"BACnet destination network number 0-65535\r\n"
|
||||
@@ -243,7 +250,8 @@ int main(int argc, char *argv[])
|
||||
if (argc > 1) {
|
||||
Target_Router_Network = strtol(argv[1], NULL, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ static void MyAbortHandler(
|
||||
Error_Detected = true;
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
(void)src;
|
||||
@@ -106,7 +106,8 @@ int main(int argc, char *argv[])
|
||||
uint16_t result_code = 0;
|
||||
|
||||
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]));
|
||||
return 0;
|
||||
}
|
||||
@@ -153,8 +154,9 @@ int main(int argc, char *argv[])
|
||||
argi = 3;
|
||||
while (argc > argi) {
|
||||
bdt_entry = &BBMD_Table_Entry[bdti];
|
||||
c = sscanf(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]);
|
||||
c = sscanf(
|
||||
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)) {
|
||||
bvlc_address_set(&bdt_entry->dest_address, a[0], a[1], a[2], a[3]);
|
||||
if ((c == 5) || (c == 9)) {
|
||||
|
||||
+19
-11
@@ -46,7 +46,8 @@ static bool End_Of_File_Detected = false;
|
||||
static bool Error_Detected = false;
|
||||
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,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
@@ -66,18 +67,20 @@ static void MyAbortHandler(
|
||||
(void)server;
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Current_Invoke_ID)) {
|
||||
printf("BACnet Abort: %s\r\n",
|
||||
printf(
|
||||
"BACnet Abort: %s\r\n",
|
||||
bactext_abort_reason_name((int)abort_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Current_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\r\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\r\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
@@ -148,7 +151,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (argc < 4) {
|
||||
/* 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",
|
||||
filename_remove_path(argv[0]));
|
||||
return 0;
|
||||
@@ -158,12 +162,14 @@ int main(int argc, char *argv[])
|
||||
Target_File_Object_Instance = strtol(argv[2], NULL, 0);
|
||||
Local_File_Name = argv[3];
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -251,12 +257,14 @@ int main(int argc, char *argv[])
|
||||
pFile = fopen(Local_File_Name, "rb");
|
||||
if (pFile) {
|
||||
(void)fseek(pFile, fileStartPosition, SEEK_SET);
|
||||
len = fread(octetstring_value(&fileData), 1,
|
||||
requestedOctetCount, pFile);
|
||||
len = fread(
|
||||
octetstring_value(&fileData), 1, requestedOctetCount,
|
||||
pFile);
|
||||
if (len < requestedOctetCount) {
|
||||
End_Of_File_Detected = true;
|
||||
if (pad_byte) {
|
||||
memset(octetstring_value(&fileData) + len + 1,
|
||||
memset(
|
||||
octetstring_value(&fileData) + len + 1,
|
||||
(int)Target_File_Requested_Octet_Pad_Byte,
|
||||
requestedOctetCount - len);
|
||||
len = requestedOctetCount;
|
||||
|
||||
+31
-26
@@ -67,14 +67,16 @@ static BACNET_ADDRESS Target_Address;
|
||||
/* needed for return value of main application */
|
||||
static bool Error_Detected = false;
|
||||
|
||||
static void MyErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ERROR_CLASS error_class,
|
||||
BACNET_ERROR_CODE error_code)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(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_code_name((int)error_code));
|
||||
Error_Detected = true;
|
||||
@@ -93,19 +95,20 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyWritePropertySimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyWritePropertySimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -138,7 +141,8 @@ static void Init_Service_Handlers(void)
|
||||
|
||||
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",
|
||||
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"
|
||||
"writing to Device Object 123, the device-instance would be 123.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"object-type:\n"
|
||||
printf("object-type:\n"
|
||||
"The object type is object that you are writing. It\n"
|
||||
"can be defined either as the object-type name string\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"
|
||||
"the object-instance would be 2.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"property:\n"
|
||||
printf("property:\n"
|
||||
"The property of the object that you are writing. It\n"
|
||||
"can be defined either as the property name string as\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"
|
||||
"Value property, use present-value or 85 as the property.\n");
|
||||
printf("\n");
|
||||
printf(
|
||||
"priority:\n"
|
||||
printf("priority:\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"
|
||||
"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"
|
||||
"is preceded by a C, and followed by the application tag.\n"
|
||||
"Ctag atag. C2 4 creates a context 2 tagged REAL.\n");
|
||||
printf(
|
||||
"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"
|
||||
"The complex data value argument varies in its construction.\n");
|
||||
printf("\n");
|
||||
@@ -283,8 +283,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
Target_Object_Property = object_property;
|
||||
priority = strtol(argv[5], NULL, 0);
|
||||
if ((priority < BACNET_MIN_PRIORITY) ||
|
||||
(priority > BACNET_MAX_PRIORITY)) {
|
||||
if ((priority < BACNET_MIN_PRIORITY) || (priority > BACNET_MAX_PRIORITY)) {
|
||||
priority = BACNET_NO_PRIORITY;
|
||||
}
|
||||
Target_Object_Property_Priority = priority;
|
||||
@@ -293,22 +292,26 @@ int main(int argc, char *argv[])
|
||||
Target_Object_Property_Index = BACNET_ARRAY_ALL;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -340,7 +343,8 @@ int main(int argc, char *argv[])
|
||||
property_tag = bacapp_known_property_tag(
|
||||
Target_Object_Type, Target_Object_Property);
|
||||
} 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);
|
||||
return 1;
|
||||
}
|
||||
@@ -353,8 +357,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Error: parser for property %s is not implemented\n",
|
||||
fprintf(
|
||||
stderr, "Error: parser for property %s is not implemented\n",
|
||||
bactext_property_name(Target_Object_Property));
|
||||
return 1;
|
||||
}
|
||||
@@ -387,7 +391,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+55
-34
@@ -57,7 +57,8 @@ static bool Error_Detected = false;
|
||||
/* Used for verbose */
|
||||
static bool Verbose = false;
|
||||
|
||||
static void MyWritePropertyMultipleErrorHandler(BACNET_ADDRESS *src,
|
||||
static void MyWritePropertyMultipleErrorHandler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t invoke_id,
|
||||
uint8_t service_choice,
|
||||
uint8_t *service_request,
|
||||
@@ -71,10 +72,12 @@ static void MyWritePropertyMultipleErrorHandler(BACNET_ADDRESS *src,
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
len = wpm_error_ack_decode_apdu(service_request, service_len, &wp_data);
|
||||
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_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),
|
||||
(unsigned)wp_data.object_instance,
|
||||
bactext_property_name((int)wp_data.object_property));
|
||||
@@ -95,20 +98,21 @@ static void MyAbortHandler(
|
||||
}
|
||||
}
|
||||
|
||||
static void MyRejectHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
static void
|
||||
MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id, uint8_t reject_reason)
|
||||
{
|
||||
/* FIXME: verify src and invoke id */
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
printf("BACnet Reject: %s\n",
|
||||
printf(
|
||||
"BACnet Reject: %s\n",
|
||||
bactext_reject_reason_name((int)reject_reason));
|
||||
Error_Detected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void MyWritePropertyMultipleSimpleAckHandler(
|
||||
BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
static void
|
||||
MyWritePropertyMultipleSimpleAckHandler(BACNET_ADDRESS *src, uint8_t invoke_id)
|
||||
{
|
||||
if (address_match(&Target_Address, src) &&
|
||||
(invoke_id == Request_Invoke_ID)) {
|
||||
@@ -131,10 +135,12 @@ static void Init_Service_Handlers(void)
|
||||
apdu_set_confirmed_handler(
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
|
||||
/* 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);
|
||||
/* 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);
|
||||
apdu_set_abort_handler(MyAbortHandler);
|
||||
apdu_set_reject_handler(MyRejectHandler);
|
||||
@@ -164,7 +170,8 @@ static void cleanup(void)
|
||||
|
||||
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 "
|
||||
"value]\n",
|
||||
filename);
|
||||
@@ -209,30 +216,34 @@ static void print_help(const char *filename)
|
||||
"priority (16) if the object property supports priorities\n"
|
||||
"when no priority is sent.\n");
|
||||
printf("\n");
|
||||
printf("index:\n"
|
||||
printf(
|
||||
"index:\n"
|
||||
"This integer parameter is the index number of an array.\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");
|
||||
printf("\n");
|
||||
printf("tag:\n"
|
||||
printf(
|
||||
"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"
|
||||
"writing. For example, if you were writing a REAL value, you would \n"
|
||||
"use a tag of 4.\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");
|
||||
printf(
|
||||
"Complex data use the property argument and a tag number -1 to\n"
|
||||
"is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged "
|
||||
"REAL.\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"
|
||||
"The complex data value argument varies in its construction.\n");
|
||||
printf("\n");
|
||||
printf("value:\n"
|
||||
printf(
|
||||
"value:\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"
|
||||
"example, if you were writing a REAL value of 100.0, you would use \n"
|
||||
"100.0 as the value.\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"
|
||||
"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"
|
||||
@@ -245,7 +256,8 @@ static void print_help(const char *filename)
|
||||
"testing by passing the wrong tag to validate that the server\n"
|
||||
"returns an error, reject, or abort message.\n");
|
||||
printf("\n");
|
||||
printf("Example:\n"
|
||||
printf(
|
||||
"Example:\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"
|
||||
"send the following command:\n"
|
||||
@@ -304,7 +316,8 @@ int main(int argc, char *argv[])
|
||||
/* decode the command line parameters */
|
||||
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -332,7 +345,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -347,7 +361,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@@ -356,20 +371,22 @@ int main(int argc, char *argv[])
|
||||
wpm_object->listOfProperties = wpm_property;
|
||||
if (wpm_property) {
|
||||
/* 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);
|
||||
tag_value_arg++;
|
||||
args_remaining--;
|
||||
if (scan_count > 0) {
|
||||
wpm_property->propertyIdentifier = property_id;
|
||||
if (Verbose) {
|
||||
printf("property-identifier=%u, array-index=%u\n",
|
||||
printf(
|
||||
"property-identifier=%u, array-index=%u\n",
|
||||
property_id, property_array_index);
|
||||
}
|
||||
if (wpm_property->propertyIdentifier >
|
||||
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",
|
||||
wpm_property->propertyIdentifier,
|
||||
MAX_BACNET_PROPERTY_ID + 1);
|
||||
return 1;
|
||||
@@ -381,7 +398,8 @@ int main(int argc, char *argv[])
|
||||
wpm_property->propertyArrayIndex = BACNET_ARRAY_ALL;
|
||||
}
|
||||
if (args_remaining <= 0) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: missing priority and tag value pair.\n");
|
||||
return 1;
|
||||
}
|
||||
@@ -428,12 +446,12 @@ int main(int argc, char *argv[])
|
||||
printf("tag=%ld value=%s\n", property_tag, value_string);
|
||||
}
|
||||
if (property_tag < 0) {
|
||||
property_tag =
|
||||
bacapp_known_property_tag(wpm_object->object_type,
|
||||
property_tag = bacapp_known_property_tag(
|
||||
wpm_object->object_type,
|
||||
wpm_property->propertyIdentifier);
|
||||
} 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);
|
||||
return 1;
|
||||
}
|
||||
@@ -447,7 +465,8 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"Error: parser for property %s is not implemented\n",
|
||||
bactext_property_name(
|
||||
wpm_property->propertyIdentifier));
|
||||
@@ -480,7 +499,8 @@ int main(int argc, char *argv[])
|
||||
Target_Device_Object_Instance, &max_apdu, &Target_Address);
|
||||
if (found) {
|
||||
if (Verbose) {
|
||||
printf("Found Device %u in address_cache.\n",
|
||||
printf(
|
||||
"Found Device %u in address_cache.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
} else {
|
||||
@@ -508,7 +528,8 @@ int main(int argc, char *argv[])
|
||||
if (found) {
|
||||
if (Request_Invoke_ID == 0) {
|
||||
if (Verbose) {
|
||||
printf("Sending WritePropertyMultiple to Device %u.\n",
|
||||
printf(
|
||||
"Sending WritePropertyMultiple to Device %u.\n",
|
||||
Target_Device_Object_Instance);
|
||||
}
|
||||
Request_Invoke_ID = Send_Write_Property_Multiple_Request(
|
||||
|
||||
@@ -34,7 +34,8 @@ bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
|
||||
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,
|
||||
BACNET_CONFIRMED_SERVICE_DATA *service_data,
|
||||
@@ -63,7 +64,8 @@ uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
|
||||
return len;
|
||||
}
|
||||
|
||||
void apdu_handler(BACNET_ADDRESS *src,
|
||||
void apdu_handler(
|
||||
BACNET_ADDRESS *src,
|
||||
uint8_t *apdu, /* APDU data */
|
||||
|
||||
uint16_t apdu_len)
|
||||
@@ -87,18 +89,21 @@ void apdu_handler(BACNET_ADDRESS *src,
|
||||
break;
|
||||
}
|
||||
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
|
||||
handler_read_property(service_request, service_request_len,
|
||||
src, &service_data);
|
||||
handler_read_property(
|
||||
service_request, service_request_len, src,
|
||||
&service_data);
|
||||
}
|
||||
#ifdef WRITE_PROPERTY
|
||||
else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
|
||||
handler_write_property(service_request, service_request_len,
|
||||
src, &service_data);
|
||||
handler_write_property(
|
||||
service_request, service_request_len, src,
|
||||
&service_data);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
handler_unrecognized_service(service_request,
|
||||
service_request_len, src, &service_data);
|
||||
handler_unrecognized_service(
|
||||
service_request, service_request_len, src,
|
||||
&service_data);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
|
||||
|
||||
@@ -29,8 +29,9 @@ float AV_Present_Value[MAX_ANALOG_VALUES];
|
||||
/* given instance exists */
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_ANALOG_VALUES)
|
||||
if (object_instance < MAX_ANALOG_VALUES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -69,7 +70,8 @@ char *Analog_Value_Name(uint32_t object_instance)
|
||||
}
|
||||
|
||||
/* 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,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
@@ -136,7 +138,8 @@ int Analog_Value_Encode_Property_APDU(uint8_t *apdu,
|
||||
}
|
||||
|
||||
/* 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_CODE *error_code)
|
||||
{
|
||||
|
||||
+24
-24
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef AV_H
|
||||
#define AV_H
|
||||
|
||||
@@ -21,31 +21,31 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
void Analog_Value_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Analog_Value_Count(void);
|
||||
uint32_t Analog_Value_Index_To_Instance(unsigned index);
|
||||
char *Analog_Value_Name(uint32_t object_instance);
|
||||
void Analog_Value_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
bool Analog_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Analog_Value_Count(void);
|
||||
uint32_t Analog_Value_Index_To_Instance(unsigned index);
|
||||
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,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
bool Analog_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Analog_Value_Present_Value_Set(uint32_t object_instance,
|
||||
float value,
|
||||
uint8_t priority);
|
||||
float Analog_Value_Present_Value(uint32_t object_instance);
|
||||
bool Analog_Value_Present_Value_Set(
|
||||
uint32_t object_instance, float value, uint8_t priority);
|
||||
float Analog_Value_Present_Value(uint32_t object_instance);
|
||||
|
||||
void Analog_Value_Init(void);
|
||||
void Analog_Value_Init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "socketWrapper.h"
|
||||
#include "w5100Wrapper.h"
|
||||
//#include "bacport.h"
|
||||
// #include "bacport.h"
|
||||
|
||||
/** @file linux/bip-init.c Initializes BACnet/IP interface (Linux). */
|
||||
|
||||
@@ -61,7 +61,8 @@ void bip_set_interface(const char *ifname)
|
||||
bip_set_addr(local_address);
|
||||
if (BIP_Debug) {
|
||||
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]);
|
||||
}
|
||||
|
||||
@@ -74,9 +75,9 @@ void bip_set_interface(const char *ifname)
|
||||
|
||||
bip_set_broadcast_addr(broadcast_address);
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "IP Broadcast Address: %d.%d.%d.%d\n",
|
||||
broadcast_address[0], broadcast_address[1], broadcast_address[2],
|
||||
broadcast_address[3]);
|
||||
fprintf(
|
||||
stderr, "IP Broadcast Address: %d.%d.%d.%d\n", broadcast_address[0],
|
||||
broadcast_address[1], broadcast_address[2], broadcast_address[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,10 +103,11 @@ bool bip_init(char *ifname)
|
||||
uint8_t sock_fd = 0;
|
||||
bool isOpen = false;
|
||||
|
||||
if (ifname)
|
||||
if (ifname) {
|
||||
bip_set_interface(ifname);
|
||||
else
|
||||
} else {
|
||||
bip_set_interface("eth0");
|
||||
}
|
||||
|
||||
/* assumes that the driver has already been initialized */
|
||||
for (sock_fd = 0; sock_fd < MAX_SOCK_NUM; sock_fd++) {
|
||||
|
||||
+24
-12
@@ -76,8 +76,9 @@ bool bip_valid(void)
|
||||
|
||||
void bip_set_addr(const uint8_t *net_address)
|
||||
{ /* 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];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns network byte order */
|
||||
@@ -88,8 +89,9 @@ uint8_t *bip_get_addr(void)
|
||||
|
||||
void bip_set_broadcast_addr(const uint8_t *net_address)
|
||||
{ /* 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];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns network byte order */
|
||||
@@ -109,7 +111,8 @@ uint16_t bip_get_port(void)
|
||||
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 */
|
||||
uint16_t *port)
|
||||
{ /* 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.
|
||||
* @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 */
|
||||
|
||||
@@ -159,19 +163,22 @@ int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
if ((dest->net == BACNET_BROADCAST_NETWORK) ||
|
||||
((dest->net > 0) && (dest->len == 0)) || (dest->mac_len == 0)) {
|
||||
/* broadcast */
|
||||
for (uint8_t i = 0; i < 4; i++)
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
address[i] = BIP_Broadcast_Address[i];
|
||||
}
|
||||
port = BIP_Port;
|
||||
mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU;
|
||||
#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);
|
||||
#endif
|
||||
} else if (dest->mac_len == 6) {
|
||||
bip_decode_bip_address(dest, address, &port);
|
||||
mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU;
|
||||
#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);
|
||||
#endif
|
||||
} 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.
|
||||
* @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 */
|
||||
|
||||
@@ -224,8 +232,9 @@ uint16_t bip_receive(BACNET_ADDRESS *src, /* source address */
|
||||
int function = 0;
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (BIP_Socket < 0)
|
||||
if (BIP_Socket < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) {
|
||||
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 */
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of a BACnet/IP packet */
|
||||
if (pdu[0] != BVLL_TYPE_BACNET_IP)
|
||||
if (pdu[0] != BVLL_TYPE_BACNET_IP) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Erase up to 16 bytes after the received bytes as safety margin to
|
||||
* 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[4], &src_port, 2);
|
||||
#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]);
|
||||
#endif
|
||||
/* FIXME: check destination address */
|
||||
|
||||
+48
-47
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BIP_H
|
||||
#define BIP_H
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
/* specific defines for BACnet/IP over Ethernet */
|
||||
#define BIP_HEADER_MAX (1 + 1 + 2)
|
||||
#define BIP_MPDU_MAX (BIP_HEADER_MAX+MAX_PDU)
|
||||
#define BIP_MPDU_MAX (BIP_HEADER_MAX + MAX_PDU)
|
||||
|
||||
#define BVLL_TYPE_BACNET_IP (0x81)
|
||||
|
||||
@@ -24,69 +24,70 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* note: define init, set_interface, and cleanup in your port */
|
||||
/* on Linux, ifname is eth0, ath0, arc0, and others.
|
||||
/* note: define init, set_interface, and cleanup in your port */
|
||||
/* on Linux, ifname is eth0, ath0, arc0, and others.
|
||||
on Windows, ifname is the dotted ip address of the interface */
|
||||
bool bip_init(char *ifname);
|
||||
void bip_set_interface(const char *ifname);
|
||||
void bip_cleanup(void);
|
||||
bool bip_init(char *ifname);
|
||||
void bip_set_interface(const char *ifname);
|
||||
void bip_cleanup(void);
|
||||
|
||||
/* Convert uint8_t IPv4 to uint32 */
|
||||
uint32_t convertBIP_Address2uint32(const uint8_t * bip_address);
|
||||
void convertUint32Address_2_uint8Address(uint32_t ip,
|
||||
uint8_t * address);
|
||||
/* common BACnet/IP functions */
|
||||
void bip_set_socket(uint8_t sock_fd);
|
||||
uint8_t bip_socket(void);
|
||||
bool bip_valid(void);
|
||||
void bip_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
|
||||
void bip_get_my_address(BACNET_ADDRESS * my_address);
|
||||
/* Convert uint8_t IPv4 to uint32 */
|
||||
uint32_t convertBIP_Address2uint32(const uint8_t *bip_address);
|
||||
void convertUint32Address_2_uint8Address(uint32_t ip, uint8_t *address);
|
||||
/* common BACnet/IP functions */
|
||||
void bip_set_socket(uint8_t sock_fd);
|
||||
uint8_t bip_socket(void);
|
||||
bool bip_valid(void);
|
||||
void bip_get_broadcast_address(BACNET_ADDRESS *dest); /* destination address */
|
||||
void bip_get_my_address(BACNET_ADDRESS *my_address);
|
||||
|
||||
/* function to send a packet out the BACnet/IP socket */
|
||||
/* returns zero on success, non-zero on failure */
|
||||
int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||
/* function to send a packet out the BACnet/IP socket */
|
||||
/* returns zero on success, non-zero on failure */
|
||||
int bip_send_pdu(
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
|
||||
BACNET_NPDU_DATA * npdu_data, /* network information */
|
||||
BACNET_NPDU_DATA *npdu_data, /* network information */
|
||||
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
|
||||
unsigned pdu_len); /* number of bytes of data */
|
||||
|
||||
/* receives a BACnet/IP packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */
|
||||
/* receives a BACnet/IP packet */
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
uint16_t bip_receive(
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
|
||||
uint8_t * pdu, /* PDU data */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
|
||||
unsigned timeout); /* milliseconds to wait for a packet */
|
||||
|
||||
/* use host byte order for setting */
|
||||
void bip_set_port(uint16_t port);
|
||||
/* returns host byte order */
|
||||
uint16_t bip_get_port(void);
|
||||
/* use host byte order for setting */
|
||||
void bip_set_port(uint16_t port);
|
||||
/* returns host byte order */
|
||||
uint16_t bip_get_port(void);
|
||||
|
||||
/* use network byte order for setting */
|
||||
void bip_set_addr(const uint8_t * net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_addr(void);
|
||||
/* use network byte order for setting */
|
||||
void bip_set_addr(const uint8_t *net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_addr(void);
|
||||
|
||||
/* use network byte order for setting */
|
||||
void bip_set_broadcast_addr(const uint8_t * net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_broadcast_addr(void);
|
||||
/* use network byte order for setting */
|
||||
void bip_set_broadcast_addr(const uint8_t *net_address);
|
||||
/* returns network byte order */
|
||||
uint8_t *bip_get_broadcast_addr(void);
|
||||
|
||||
/* gets an IP address by name, where name can be a
|
||||
/* gets an IP address by name, where name can be a
|
||||
string that is an IP address in dotted form, or
|
||||
a name that is a domain name
|
||||
returns 0 if not found, or
|
||||
an IP address in network byte order */
|
||||
long bip_getaddrbyname(const char *host_name);
|
||||
long bip_getaddrbyname(const char *host_name);
|
||||
|
||||
void bip_debug_enable(void);
|
||||
void bip_debug_enable(void);
|
||||
|
||||
void bip_debug_disable(void);
|
||||
void bip_debug_disable(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -27,8 +27,9 @@ static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
|
||||
/* we simply have 0-n object instances. */
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance)
|
||||
{
|
||||
if (object_instance < MAX_BINARY_VALUES)
|
||||
if (object_instance < MAX_BINARY_VALUES) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -50,8 +51,9 @@ unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
|
||||
{
|
||||
unsigned index = MAX_BINARY_VALUES;
|
||||
|
||||
if (object_instance < MAX_BINARY_VALUES)
|
||||
if (object_instance < MAX_BINARY_VALUES) {
|
||||
index = object_instance;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
@@ -81,7 +83,8 @@ char *Binary_Value_Name(uint32_t object_instance)
|
||||
}
|
||||
|
||||
/* 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,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
@@ -153,7 +156,8 @@ int Binary_Value_Encode_Property_APDU(uint8_t *apdu,
|
||||
}
|
||||
|
||||
/* 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_CODE *error_code)
|
||||
{
|
||||
|
||||
+21
-21
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef BV_H
|
||||
#define BV_H
|
||||
|
||||
@@ -18,31 +18,31 @@
|
||||
#define MAX_BINARY_VALUES 10
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void Binary_Value_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Binary_Value_Count(void);
|
||||
uint32_t Binary_Value_Index_To_Instance(unsigned index);
|
||||
char *Binary_Value_Name(uint32_t object_instance);
|
||||
void Binary_Value_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
bool Binary_Value_Valid_Instance(uint32_t object_instance);
|
||||
unsigned Binary_Value_Count(void);
|
||||
uint32_t Binary_Value_Index_To_Instance(unsigned index);
|
||||
char *Binary_Value_Name(uint32_t object_instance);
|
||||
|
||||
void Binary_Value_Init(void);
|
||||
void Binary_Value_Init(void);
|
||||
|
||||
int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
|
||||
int Binary_Value_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
bool Binary_Value_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
* 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 */
|
||||
uint8_t *mtu, /* the data */
|
||||
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_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 */
|
||||
BACNET_BVLC_RESULT result_code)
|
||||
{
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
uint16_t bvlc_for_non_bbmd(uint8_t * addr,
|
||||
uint16_t * port,
|
||||
uint8_t * npdu,
|
||||
uint16_t received_bytes);
|
||||
uint16_t bvlc_for_non_bbmd(
|
||||
uint8_t *addr, uint16_t *port, uint8_t *npdu, uint16_t received_bytes);
|
||||
|
||||
BACNET_BVLC_FUNCTION bvlc_get_function_code(void);
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef DATALINK_H
|
||||
#define DATALINK_H
|
||||
|
||||
@@ -46,17 +46,17 @@
|
||||
#include "bvlc-arduino.h"
|
||||
|
||||
#define datalink_init bip_init
|
||||
//#if defined(BBMD_ENABLED) && BBMD_ENABLED
|
||||
//#define datalink_send_pdu bvlc_send_pdu
|
||||
//#define datalink_receive bvlc_receive
|
||||
//#else
|
||||
// #if defined(BBMD_ENABLED) && BBMD_ENABLED
|
||||
// #define datalink_send_pdu bvlc_send_pdu
|
||||
// #define datalink_receive bvlc_receive
|
||||
// #else
|
||||
#define datalink_send_pdu bip_send_pdu
|
||||
#define datalink_receive bip_receive
|
||||
//#endif
|
||||
// #endif
|
||||
#define datalink_cleanup bip_cleanup
|
||||
#define datalink_get_broadcast_address bip_get_broadcast_address
|
||||
#ifdef BAC_ROUTING
|
||||
extern void routed_get_my_address(BACNET_ADDRESS * my_address);
|
||||
extern void routed_get_my_address(BACNET_ADDRESS *my_address);
|
||||
#define datalink_get_my_address routed_get_my_address
|
||||
#else
|
||||
#define datalink_get_my_address bip_get_my_address
|
||||
@@ -66,25 +66,24 @@ extern void routed_get_my_address(BACNET_ADDRESS * my_address);
|
||||
#include "bacnet/npdu.h"
|
||||
|
||||
#define MAX_HEADER (8)
|
||||
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
|
||||
#define MAX_MPDU (MAX_HEADER + MAX_PDU)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int datalink_send_pdu(BACNET_ADDRESS * dest,
|
||||
BACNET_NPDU_DATA * npdu_data,
|
||||
uint8_t * pdu,
|
||||
int datalink_send_pdu(
|
||||
BACNET_ADDRESS *dest,
|
||||
BACNET_NPDU_DATA *npdu_data,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len);
|
||||
extern uint16_t datalink_receive(BACNET_ADDRESS * src,
|
||||
uint8_t * pdu,
|
||||
uint16_t max_pdu,
|
||||
unsigned timeout);
|
||||
extern void datalink_cleanup(void);
|
||||
extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest);
|
||||
extern void datalink_get_my_address(BACNET_ADDRESS * my_address);
|
||||
extern void datalink_set_interface(char *ifname);
|
||||
extern void datalink_set(char *datalink_string);
|
||||
extern uint16_t datalink_receive(
|
||||
BACNET_ADDRESS *src, uint8_t *pdu, uint16_t max_pdu, unsigned timeout);
|
||||
extern void datalink_cleanup(void);
|
||||
extern void datalink_get_broadcast_address(BACNET_ADDRESS *dest);
|
||||
extern void datalink_get_my_address(BACNET_ADDRESS *my_address);
|
||||
extern void datalink_set_interface(char *ifname);
|
||||
extern void datalink_set(char *datalink_string);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -111,7 +110,8 @@ extern "C" {
|
||||
* chosen at runtime from among these choices.
|
||||
* - Clause 10 POINT-TO-POINT (PTP) and Clause 11 EIA/CEA-709.1 ("LonTalk") LAN
|
||||
* are not currently supported by this project.
|
||||
*//** @defgroup DLTemplates DataLink Template Functions
|
||||
*/
|
||||
/** @defgroup DLTemplates DataLink Template Functions
|
||||
* @ingroup DataLink
|
||||
* 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
|
||||
|
||||
+16
-10
@@ -60,8 +60,9 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||
(char *)&Object_Instance_Number,
|
||||
sizeof(Object_Instance_Number),
|
||||
EEPROM_BACNET_ID_ADDR); */
|
||||
} else
|
||||
} else {
|
||||
status = false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/* BACnet allows for a wildcard instance number */
|
||||
return ((Object_Instance_Number == object_id) ||
|
||||
return (
|
||||
(Object_Instance_Number == object_id) ||
|
||||
(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 */
|
||||
int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
int Device_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
@@ -207,7 +210,8 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
bitstring_init(&bit_string);
|
||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||
/* 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_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||
@@ -230,8 +234,9 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
case PROP_OBJECT_LIST:
|
||||
count = Device_Object_List_Count();
|
||||
/* 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);
|
||||
}
|
||||
/* if no index was specified, then try to encode the entire list */
|
||||
/* into one packet. Note that more than likely you will have */
|
||||
/* to return an error if the number of encoded objects exceeds */
|
||||
@@ -254,10 +259,10 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
}
|
||||
} else {
|
||||
if (Device_Object_List_Identifier(
|
||||
array_index, &object_type, &instance))
|
||||
array_index, &object_type, &instance)) {
|
||||
apdu_len = encode_application_object_id(
|
||||
&apdu[0], object_type, instance);
|
||||
else {
|
||||
} else {
|
||||
*error_class = ERROR_CLASS_PROPERTY;
|
||||
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
apdu_len = BACNET_STATUS_ERROR;
|
||||
@@ -321,7 +326,8 @@ int Device_Encode_Property_APDU(uint8_t *apdu,
|
||||
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_CODE *error_code)
|
||||
{
|
||||
@@ -399,8 +405,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
encoding =
|
||||
characterstring_encoding(&value.type.Character_String);
|
||||
if (encoding == CHARACTER_ANSI_X34) {
|
||||
if (characterstring_ansi_copy(&Object_Name[0],
|
||||
sizeof(Object_Name),
|
||||
if (characterstring_ansi_copy(
|
||||
&Object_Name[0], sizeof(Object_Name),
|
||||
&value.type.Character_String)) {
|
||||
status = true;
|
||||
} else {
|
||||
|
||||
+66
-70
@@ -15,98 +15,94 @@
|
||||
#include "bacnet/wp.h"
|
||||
#include "bacnet/readrange.h"
|
||||
|
||||
typedef unsigned (*object_count_function) (void);
|
||||
typedef uint32_t(*object_index_to_instance_function)
|
||||
(unsigned index);
|
||||
typedef char *(*object_name_function)
|
||||
(uint32_t object_instance);
|
||||
typedef unsigned (*object_count_function)(void);
|
||||
typedef uint32_t (*object_index_to_instance_function)(unsigned index);
|
||||
typedef char *(*object_name_function)(uint32_t object_instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#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_index_to_instance_function index_function,
|
||||
object_name_function name_function);
|
||||
|
||||
void Device_Init(void);
|
||||
void Device_Init(void);
|
||||
|
||||
void Device_Property_Lists(const int **pRequired,
|
||||
const int **pOptional,
|
||||
const int **pProprietary);
|
||||
void Device_Property_Lists(
|
||||
const int **pRequired, const int **pOptional, const int **pProprietary);
|
||||
|
||||
uint32_t Device_Object_Instance_Number(void);
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id);
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id);
|
||||
unsigned Device_Object_List_Count(void);
|
||||
bool Device_Object_List_Identifier(uint32_t array_index,
|
||||
uint32_t Device_Object_Instance_Number(void);
|
||||
bool Device_Set_Object_Instance_Number(uint32_t object_id);
|
||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id);
|
||||
unsigned Device_Object_List_Count(void);
|
||||
bool Device_Object_List_Identifier(
|
||||
uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance);
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(void);
|
||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
|
||||
|
||||
const char *Device_Vendor_Name(void);
|
||||
|
||||
uint16_t Device_Vendor_Identifier(void);
|
||||
|
||||
const char *Device_Model_Name(void);
|
||||
bool Device_Set_Model_Name(const char *name, size_t length);
|
||||
|
||||
const char *Device_Firmware_Revision(void);
|
||||
|
||||
const char *Device_Application_Software_Version(void);
|
||||
bool Device_Set_Application_Software_Version(const char *name, size_t length);
|
||||
|
||||
bool Device_Set_Object_Name(const char *name, size_t length);
|
||||
const char *Device_Object_Name(void);
|
||||
|
||||
const char *Device_Description(void);
|
||||
bool Device_Set_Description(const char *name, size_t length);
|
||||
|
||||
const char *Device_Location(void);
|
||||
bool Device_Set_Location(const char *name, size_t length);
|
||||
|
||||
/* some stack-centric constant values - no set methods */
|
||||
uint8_t Device_Protocol_Version(void);
|
||||
uint8_t Device_Protocol_Revision(void);
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(void);
|
||||
|
||||
uint8_t Device_Database_Revision(void);
|
||||
void Device_Set_Database_Revision(uint8_t revision);
|
||||
|
||||
bool Device_Valid_Object_Name(
|
||||
const char *object_name,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * instance);
|
||||
uint32_t *object_instance);
|
||||
char *Device_Valid_Object_Id(
|
||||
BACNET_OBJECT_TYPE object_type, uint32_t object_instance);
|
||||
|
||||
BACNET_DEVICE_STATUS Device_System_Status(void);
|
||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
|
||||
|
||||
const char *Device_Vendor_Name(void);
|
||||
|
||||
uint16_t Device_Vendor_Identifier(void);
|
||||
|
||||
const char *Device_Model_Name(void);
|
||||
bool Device_Set_Model_Name(const char *name,
|
||||
size_t length);
|
||||
|
||||
const char *Device_Firmware_Revision(void);
|
||||
|
||||
const char *Device_Application_Software_Version(void);
|
||||
bool Device_Set_Application_Software_Version(const char *name,
|
||||
size_t length);
|
||||
|
||||
bool Device_Set_Object_Name(const char *name,
|
||||
size_t length);
|
||||
const char *Device_Object_Name(void);
|
||||
|
||||
const char *Device_Description(void);
|
||||
bool Device_Set_Description(const char *name,
|
||||
size_t length);
|
||||
|
||||
const char *Device_Location(void);
|
||||
bool Device_Set_Location(const char *name,
|
||||
size_t length);
|
||||
|
||||
/* some stack-centric constant values - no set methods */
|
||||
uint8_t Device_Protocol_Version(void);
|
||||
uint8_t Device_Protocol_Revision(void);
|
||||
BACNET_SEGMENTATION Device_Segmentation_Supported(void);
|
||||
|
||||
uint8_t Device_Database_Revision(void);
|
||||
void Device_Set_Database_Revision(uint8_t revision);
|
||||
|
||||
bool Device_Valid_Object_Name(const char *object_name,
|
||||
BACNET_OBJECT_TYPE *object_type,
|
||||
uint32_t * object_instance);
|
||||
char *Device_Valid_Object_Id(BACNET_OBJECT_TYPE object_type,
|
||||
uint32_t object_instance);
|
||||
|
||||
int Device_Encode_Property_APDU(uint8_t * apdu,
|
||||
int Device_Encode_Property_APDU(
|
||||
uint8_t *apdu,
|
||||
uint32_t object_instance,
|
||||
BACNET_PROPERTY_ID property,
|
||||
uint32_t array_index,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
bool Device_Write_Property(
|
||||
BACNET_WRITE_PROPERTY_DATA *wp_data,
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
bool DeviceGetRRInfo(uint32_t Object, /* Which particular object - obviously not important for device object */
|
||||
bool DeviceGetRRInfo(
|
||||
uint32_t Object, /* Which particular object - obviously not important for
|
||||
device object */
|
||||
|
||||
BACNET_PROPERTY_ID Property, /* Which property */
|
||||
|
||||
RR_PROP_INFO * pInfo, /* Where to put the information */
|
||||
|
||||
BACNET_ERROR_CLASS * error_class,
|
||||
BACNET_ERROR_CODE * error_code);
|
||||
RR_PROP_INFO *pInfo, /* Where to put the information */
|
||||
|
||||
BACNET_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+30
-24
@@ -26,7 +26,8 @@
|
||||
|
||||
/* Encodes the property APDU and returns the length,
|
||||
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_ERROR_CLASS *error_class,
|
||||
BACNET_ERROR_CODE *error_code)
|
||||
@@ -37,23 +38,26 @@ int Encode_Property_APDU(uint8_t *apdu,
|
||||
switch (rp_data->object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
||||
apdu_len = Device_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
apdu_len = Device_Encode_Property_APDU(
|
||||
&apdu[0], rp_data->object_instance,
|
||||
rp_data->object_property, rp_data->array_index, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
|
||||
apdu_len = Analog_Value_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
apdu_len = Analog_Value_Encode_Property_APDU(
|
||||
&apdu[0], rp_data->object_instance,
|
||||
rp_data->object_property, rp_data->array_index, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
|
||||
apdu_len = Binary_Value_Encode_Property_APDU(&apdu[0],
|
||||
rp_data->object_instance, rp_data->object_property,
|
||||
rp_data->array_index, error_class, error_code);
|
||||
apdu_len = Binary_Value_Encode_Property_APDU(
|
||||
&apdu[0], rp_data->object_instance,
|
||||
rp_data->object_property, rp_data->array_index, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -65,7 +69,8 @@ int Encode_Property_APDU(uint8_t *apdu,
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
void handler_read_property(uint8_t *service_request,
|
||||
void handler_read_property(
|
||||
uint8_t *service_request,
|
||||
uint16_t service_len,
|
||||
BACNET_ADDRESS *src,
|
||||
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);
|
||||
if (service_data->segmented_message) {
|
||||
/* we don't support segmentation - send an abort */
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
goto RP_ABORT;
|
||||
}
|
||||
len = rp_decode_service_request(service_request, service_len, &data);
|
||||
if (len < 0) {
|
||||
/* bad decoding - send an abort */
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_OTHER, true);
|
||||
goto RP_ABORT;
|
||||
}
|
||||
/* most cases will be error */
|
||||
ack_len = rp_ack_encode_apdu_init(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
|
||||
/* FIXME: add buffer len as passed into function or use smart buffer */
|
||||
property_len =
|
||||
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], &data,
|
||||
&error_class, &error_code);
|
||||
property_len = Encode_Property_APDU(
|
||||
&Handler_Transmit_Buffer[pdu_len + ack_len], &data, &error_class,
|
||||
&error_code);
|
||||
if (property_len >= 0) {
|
||||
len = rp_ack_encode_apdu_object_property_end(
|
||||
&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
|
||||
* Abort */
|
||||
case BACNET_STATUS_ABORT:
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
break;
|
||||
default:
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
||||
error_class, error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ void sendIamUnicast(uint8_t *buffer, BACNET_ADDRESS *src)
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_len = npdu_encode_pdu(&buffer[0], &dest, &my_address, &npdu_data);
|
||||
/* encode the APDU portion of the packet */
|
||||
apdu_len =
|
||||
iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(),
|
||||
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier());
|
||||
apdu_len = iam_encode_apdu(
|
||||
&buffer[npdu_len], Device_Object_Instance_Number(), MAX_APDU,
|
||||
SEGMENTATION_NONE, Device_Vendor_Identifier());
|
||||
/* send data */
|
||||
pdu_len = npdu_len + apdu_len;
|
||||
int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
|
||||
|
||||
+23
-18
@@ -27,7 +27,8 @@
|
||||
/* too big to reside on stack frame for PIC */
|
||||
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,
|
||||
BACNET_ADDRESS *src,
|
||||
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);
|
||||
/* bad decoding or something we didn't understand - send an abort */
|
||||
if (len <= 0) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_OTHER, true);
|
||||
} else if (service_data->segmented_message) {
|
||||
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||
true);
|
||||
len = abort_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||
} else {
|
||||
switch (wp_data.object_type) {
|
||||
case OBJECT_DEVICE:
|
||||
if (Device_Write_Property(
|
||||
&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_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
@@ -73,12 +76,13 @@ void handler_write_property(uint8_t *service_request,
|
||||
case OBJECT_ANALOG_VALUE:
|
||||
if (Analog_Value_Write_Property(
|
||||
&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_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
@@ -87,21 +91,22 @@ void handler_write_property(uint8_t *service_request,
|
||||
case OBJECT_BINARY_VALUE:
|
||||
if (Binary_Value_Write_Property(
|
||||
&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_CONFIRMED_WRITE_PROPERTY);
|
||||
} else {
|
||||
len =
|
||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||
error_code);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||
error_class, error_code);
|
||||
len = bacerror_encode_apdu(
|
||||
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
|
||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
extern bool Send_I_Am_Flag;
|
||||
/* local version override */
|
||||
const char *BACnet_Version = "1.0";
|
||||
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE, 0xEF,
|
||||
0xFE, 0xED };
|
||||
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE,
|
||||
0xEF, 0xFE, 0xED };
|
||||
uint8_t ipAddress[] = { 192, 168, 0, 185 };
|
||||
uint8_t gateway[] = { 192, 168, 0, 1 };
|
||||
uint8_t netmask[] = { 255, 255, 255, 0 };
|
||||
@@ -70,14 +70,17 @@ void setup()
|
||||
#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
|
||||
* would be filled up to MAX_MPDU and some
|
||||
* decoding functions would overrun, these
|
||||
* decoding functions will just end up in
|
||||
* a safe field of static zeros. */];
|
||||
* a safe field of static zeros. */
|
||||
];
|
||||
|
||||
/** Main */
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef TXBUF_H
|
||||
#define TXBUF_H
|
||||
|
||||
|
||||
@@ -17,9 +17,8 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
void uart_init(void);
|
||||
void uart_putchar(char c,
|
||||
FILE * stream);
|
||||
char uart_getchar(FILE * stream);
|
||||
void uart_putchar(char c, FILE *stream);
|
||||
char uart_getchar(FILE *stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -437,11 +437,13 @@ extern "C" {
|
||||
* - The interface between the implemented Objects and the BAC-stack services,
|
||||
* specifically the handlers, which are mediated through function calls to
|
||||
* the Device object.
|
||||
*//** @defgroup ObjHelpers Object Helper Functions
|
||||
*/
|
||||
/** @defgroup ObjHelpers Object Helper Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* This section describes the function templates for the helper functions that
|
||||
* provide common object support.
|
||||
*//** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
*/
|
||||
/** @defgroup ObjIntf Handler-to-Object Interface Functions
|
||||
* @ingroup ObjFrmwk
|
||||
* 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
|
||||
|
||||
+54
-30
@@ -62,8 +62,9 @@ bool arcnet_valid(void)
|
||||
|
||||
void arcnet_cleanup(void)
|
||||
{
|
||||
if (arcnet_valid())
|
||||
if (arcnet_valid()) {
|
||||
close(ARCNET_Sock_FD);
|
||||
}
|
||||
ARCNET_Sock_FD = -1;
|
||||
|
||||
return;
|
||||
@@ -79,7 +80,8 @@ static int arcnet_bind(const char *interface_name)
|
||||
/* check to see if we are being run as root */
|
||||
uid = getuid();
|
||||
if (uid != 0) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"arcnet: Unable to open an af_packet socket. "
|
||||
"Try running with root priveleges.\n");
|
||||
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) {
|
||||
/* Error occured */
|
||||
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"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\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 = PF_INET; */
|
||||
/* 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));
|
||||
/* 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);
|
||||
fprintf(
|
||||
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) {
|
||||
/* 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));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\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));
|
||||
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];
|
||||
}
|
||||
/* copy this info into the local copy since bind wiped it out */
|
||||
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
|
||||
/*ARCNET_Socket_Address.sa_family = PF_INET; */
|
||||
/* 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));
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
atexit(arcnet_cleanup);
|
||||
@@ -155,17 +167,19 @@ static int arcnet_bind(const char *interface_name)
|
||||
|
||||
bool arcnet_init(char *interface_name)
|
||||
{
|
||||
if (interface_name)
|
||||
if (interface_name) {
|
||||
ARCNET_Sock_FD = arcnet_bind(interface_name);
|
||||
else
|
||||
} else {
|
||||
ARCNET_Sock_FD = arcnet_bind("arc0");
|
||||
}
|
||||
|
||||
return arcnet_valid();
|
||||
}
|
||||
|
||||
/* function to send a PDU out the socket */
|
||||
/* 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 */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -186,15 +200,15 @@ int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
return -1;
|
||||
}
|
||||
/* load destination MAC address */
|
||||
if (dest->mac_len == 1)
|
||||
if (dest->mac_len == 1) {
|
||||
pkt->hard.dest = dest->mac[0];
|
||||
else {
|
||||
} else {
|
||||
fprintf(stderr, "arcnet: invalid destination MAC address!\n");
|
||||
return -2;
|
||||
}
|
||||
if (src.mac_len == 1)
|
||||
if (src.mac_len == 1) {
|
||||
pkt->hard.source = src.mac[0];
|
||||
else {
|
||||
} else {
|
||||
fprintf(stderr, "arcnet: invalid source MAC address!\n");
|
||||
return -3;
|
||||
}
|
||||
@@ -211,19 +225,22 @@ int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
}
|
||||
memcpy(&pkt->soft.raw[4], pdu, pdu_len);
|
||||
/* 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,
|
||||
sizeof(ARCNET_Socket_Address));
|
||||
/* did it get sent? */
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
fprintf(stderr, "arcnet: Error sending packet: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* receives an framed packet */
|
||||
/* 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 */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -237,8 +254,9 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
struct archdr *pkt = (struct archdr *)buf;
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (ARCNET_Sock_FD <= 0)
|
||||
if (ARCNET_Sock_FD <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -255,24 +273,28 @@ uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
FD_SET(ARCNET_Sock_FD, &read_fds);
|
||||
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));
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See if there is a problem */
|
||||
if (received_bytes < 0) {
|
||||
/* EAGAIN Non-blocking I/O has been selected */
|
||||
/* using O_NONBLOCK and no data */
|
||||
/* was immediately available for reading. */
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
if (errno != EAGAIN) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) "
|
||||
"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 -= 4 /* SC, DSAP, SSAP, LLC Control */;
|
||||
/* 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);
|
||||
}
|
||||
/* silently ignore packets that are too large */
|
||||
else
|
||||
else {
|
||||
pdu_len = 0;
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
|
||||
+12
-16
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef BACPORT_H
|
||||
#define BACPORT_H
|
||||
@@ -84,24 +84,20 @@
|
||||
#include <netdb.h>
|
||||
#include "bacnet/basic/sys/bacnet_stack_exports.h"
|
||||
|
||||
#define BACNET_OBJECT_TABLE(table_name, _type, _init, _count, \
|
||||
_index_to_instance, _valid_instance, _object_name, \
|
||||
_read_property, _write_property, _RPM_list, \
|
||||
_RR_info, _iterator, _value_list, _COV, \
|
||||
_COV_clear, _intrinsic_reporting) \
|
||||
#define BACNET_OBJECT_TABLE( \
|
||||
table_name, _type, _init, _count, _index_to_instance, _valid_instance, \
|
||||
_object_name, _read_property, _write_property, _RPM_list, _RR_info, \
|
||||
_iterator, _value_list, _COV, _COV_clear, _intrinsic_reporting) \
|
||||
static_assert(false, "Unsupported BACNET_OBJECT_TABLE for this platform")
|
||||
|
||||
/** @file linux/bacport.h Includes Linux network headers. */
|
||||
|
||||
/* Local helper functions for this port */
|
||||
BACNET_STACK_EXPORT
|
||||
extern int bip_get_local_netmask(
|
||||
struct in_addr *netmask);
|
||||
extern int bip_get_local_netmask(struct in_addr *netmask);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
extern int bip_get_local_address_ioctl(
|
||||
const char *ifname,
|
||||
struct in_addr *addr,
|
||||
int request);
|
||||
const char *ifname, struct in_addr *addr, int request);
|
||||
|
||||
#endif
|
||||
|
||||
+40
-26
@@ -60,13 +60,15 @@ static char BIP_Interface_Name[IF_NAMESIZE] = { 0 };
|
||||
* @param str - debug info string
|
||||
* @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 unsigned int port,
|
||||
const unsigned int count)
|
||||
{
|
||||
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);
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -293,8 +295,9 @@ int bip_send_mpdu(
|
||||
/* Send the packet */
|
||||
debug_print_ipv4(
|
||||
"Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
|
||||
return sendto(BIP_Socket, (const char *)mtu, mtu_len, 0,
|
||||
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
|
||||
return sendto(
|
||||
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 */
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
socket = FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket :
|
||||
BIP_Broadcast_Socket;
|
||||
received_bytes = recvfrom(socket, (char *)&npdu[0], max_npdu, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
socket =
|
||||
FD_ISSET(BIP_Socket, &read_fds) ? BIP_Socket : BIP_Broadcast_Socket;
|
||||
received_bytes = recvfrom(
|
||||
socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
|
||||
&sin_len);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -423,7 +427,8 @@ uint16_t bip_receive(
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* 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,
|
||||
uint8_t *pdu,
|
||||
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
|
||||
* @return 0 on success, else the error from the ioctl() call.
|
||||
*/
|
||||
static int get_local_ifr_ioctl(
|
||||
const char *ifname, struct ifreq *ifr, int request)
|
||||
static int
|
||||
get_local_ifr_ioctl(const char *ifname, struct ifreq *ifr, int request)
|
||||
{
|
||||
int fd;
|
||||
int rv; /* return value */
|
||||
@@ -526,8 +531,8 @@ struct route_info {
|
||||
* @param pId - process identifier of our specific request response
|
||||
* @return number of bytes placed into the buffer
|
||||
*/
|
||||
static int readNlSock(
|
||||
int sockFd, char *bufPtr, size_t buf_size, int seqNum, int pId)
|
||||
static int
|
||||
readNlSock(int sockFd, char *bufPtr, size_t buf_size, int seqNum, int pId)
|
||||
{
|
||||
struct nlmsghdr *nlHdr;
|
||||
int readLen = 0, msgLen = 0;
|
||||
@@ -574,7 +579,8 @@ static char *ntoa(uint32_t addr)
|
||||
{
|
||||
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 & 0xFF000000) >> 24);
|
||||
|
||||
@@ -589,18 +595,21 @@ static void printRoute(struct route_info *rtInfo)
|
||||
{
|
||||
if (BIP_Debug) {
|
||||
/* Print Destination address */
|
||||
fprintf(stderr, "%s\t",
|
||||
fprintf(
|
||||
stderr, "%s\t",
|
||||
rtInfo->dstAddr ? ntoa(rtInfo->dstAddr) : "0.0.0.0 ");
|
||||
|
||||
/* Print Gateway address */
|
||||
fprintf(stderr, "%s\t",
|
||||
fprintf(
|
||||
stderr, "%s\t",
|
||||
rtInfo->gateWay ? ntoa(rtInfo->gateWay) : "*.*.*.*");
|
||||
|
||||
/* Print Interface Name */
|
||||
fprintf(stderr, "%s\t", rtInfo->ifName);
|
||||
|
||||
/* Print Source address */
|
||||
fprintf(stderr, "%s\n",
|
||||
fprintf(
|
||||
stderr, "%s\n",
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
/* get the rtattr field */
|
||||
rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
|
||||
@@ -700,7 +710,8 @@ static char *ifname_default(void)
|
||||
if (BIP_Interface_Name[0] == 0) {
|
||||
if ((rtInfo->dstAddr == 0) && (rtInfo->ifName[0] != 0)) {
|
||||
/* default route */
|
||||
memcpy(BIP_Interface_Name, rtInfo->ifName,
|
||||
memcpy(
|
||||
BIP_Interface_Name, rtInfo->ifName,
|
||||
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.
|
||||
* @return 0 on success
|
||||
*/
|
||||
int bip_set_broadcast_binding(
|
||||
const char *ip4_broadcast)
|
||||
int bip_set_broadcast_binding(const char *ip4_broadcast)
|
||||
{
|
||||
BIP_Broadcast_Binding_Address.s_addr = inet_addr(ip4_broadcast);
|
||||
BIP_Broadcast_Binding_Address_Override = true;
|
||||
@@ -799,9 +809,11 @@ void bip_set_interface(const char *ifname)
|
||||
}
|
||||
#endif
|
||||
if (BIP_Debug) {
|
||||
fprintf(stderr, "BIP: Broadcast Address: %s\n",
|
||||
fprintf(
|
||||
stderr, "BIP: Broadcast Address: %s\n",
|
||||
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));
|
||||
fflush(stderr);
|
||||
}
|
||||
@@ -835,8 +847,9 @@ static int createSocket(const struct sockaddr_in *sin)
|
||||
return status;
|
||||
}
|
||||
/* Bind to the proper interface to send without default gateway */
|
||||
status = setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
BIP_Interface_Name, strlen(BIP_Interface_Name));
|
||||
status = setsockopt(
|
||||
sock_fd, SOL_SOCKET, SO_BINDTODEVICE, BIP_Interface_Name,
|
||||
strlen(BIP_Interface_Name));
|
||||
if (status < 0) {
|
||||
if (BIP_Debug) {
|
||||
perror("SO_BINDTODEVICE: ");
|
||||
@@ -882,7 +895,8 @@ bool bip_init(char *ifname)
|
||||
bip_set_interface(ifname_default());
|
||||
}
|
||||
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);
|
||||
fflush(stderr);
|
||||
return false;
|
||||
|
||||
+36
-24
@@ -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)
|
||||
{
|
||||
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\n",
|
||||
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[4], (int)addr->s6_addr[5],
|
||||
(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[11],
|
||||
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
|
||||
(int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[4],
|
||||
(int)addr->s6_addr[5], (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[11], (int)addr->s6_addr[12], (int)addr->s6_addr[13],
|
||||
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
|
||||
}
|
||||
|
||||
@@ -106,12 +106,13 @@ void bip6_set_interface(char *ifname)
|
||||
while (ifa_tmp) {
|
||||
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
|
||||
debug_fprintf_bip6(
|
||||
stdout, "BIP6: found interface: %s\n",ifa_tmp->ifa_name);
|
||||
stdout, "BIP6: found interface: %s\n", ifa_tmp->ifa_name);
|
||||
}
|
||||
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
|
||||
(strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) {
|
||||
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[2]),
|
||||
ntohs(sin->sin6_addr.s6_addr16[3]),
|
||||
@@ -127,7 +128,8 @@ void bip6_set_interface(char *ifname)
|
||||
ifa_tmp = ifa_tmp->ifa_next;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -246,8 +248,9 @@ int bip6_send_mpdu(
|
||||
}
|
||||
/* load destination IP address */
|
||||
bvlc_dest.sin6_family = AF_INET6;
|
||||
bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3],
|
||||
&addr16[4], &addr16[5], &addr16[6], &addr16[7]);
|
||||
bvlc6_address_get(
|
||||
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[1] = htons(addr16[1]);
|
||||
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;
|
||||
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
|
||||
/* 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));
|
||||
}
|
||||
|
||||
@@ -276,7 +280,8 @@ int bip6_send_mpdu(
|
||||
* @return Upon successful completion, returns the number of bytes sent.
|
||||
* 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,
|
||||
uint8_t *pdu,
|
||||
unsigned pdu_len)
|
||||
@@ -328,8 +333,9 @@ uint16_t bip6_receive(
|
||||
max = BIP6_Socket;
|
||||
/* see if there is a packet for us */
|
||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||
received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0,
|
||||
(struct sockaddr *)&sin, &sin_len);
|
||||
received_bytes = recvfrom(
|
||||
BIP6_Socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
|
||||
&sin_len);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -347,7 +353,8 @@ uint16_t bip6_receive(
|
||||
}
|
||||
/* pass the packet into the BBMD handler */
|
||||
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[3]), ntohs(sin.sin6_addr.s6_addr16[4]),
|
||||
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);
|
||||
if (BIP6_Broadcast_Addr.address[0] == 0) {
|
||||
bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0,
|
||||
0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID);
|
||||
bvlc6_address_set(
|
||||
&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 */
|
||||
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (BIP6_Socket < 0)
|
||||
if (BIP6_Socket < 0) {
|
||||
return false;
|
||||
}
|
||||
/* Allow us to use the same socket for sending and receiving */
|
||||
/* This makes sure that the src port is correct when sending */
|
||||
sockopt = 1;
|
||||
@@ -444,14 +453,17 @@ bool bip6_init(char *ifname)
|
||||
return false;
|
||||
}
|
||||
/* 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);
|
||||
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address,
|
||||
memcpy(
|
||||
&join_request.ipv6mr_multiaddr, &broadcast_address,
|
||||
sizeof(struct in6_addr));
|
||||
/* Let system not choose the interface */
|
||||
join_request.ipv6mr_interface = BIP6_Socket_Scope_Id;
|
||||
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||
&join_request, sizeof(join_request));
|
||||
status = setsockopt(
|
||||
BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, &join_request,
|
||||
sizeof(join_request));
|
||||
if (status < 0) {
|
||||
perror("BIP: setsockopt(IPV6_JOIN_GROUP)");
|
||||
}
|
||||
|
||||
+10
-5
@@ -267,16 +267,19 @@ static void *dlmstp_master_fsm_task(void *pArg)
|
||||
silence = MSTP_Port.SilenceTimer(&MSTP_Port);
|
||||
switch (MSTP_Port.master_state) {
|
||||
case MSTP_MASTER_STATE_IDLE:
|
||||
if (silence >= Tno_token)
|
||||
if (silence >= Tno_token) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||
if (silence >= Treply_timeout)
|
||||
if (silence >= Treply_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
if (silence >= Tusage_timeout)
|
||||
if (silence >= Tusage_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
run_master = true;
|
||||
@@ -290,8 +293,9 @@ static void *dlmstp_master_fsm_task(void *pArg)
|
||||
/* do nothing while immediate transitioning */
|
||||
run_loop = MSTP_Master_Node_FSM(&MSTP_Port);
|
||||
pthread_mutex_lock(&Thread_Mutex);
|
||||
if (!run_thread)
|
||||
if (!run_thread) {
|
||||
run_loop = false;
|
||||
}
|
||||
pthread_mutex_unlock(&Thread_Mutex);
|
||||
}
|
||||
} 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 */
|
||||
if (mac_address <= 127) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -258,16 +258,19 @@ static void *dlmstp_master_fsm_task(void *pArg)
|
||||
silence = mstp_port->SilenceTimer(NULL);
|
||||
switch (mstp_port->master_state) {
|
||||
case MSTP_MASTER_STATE_IDLE:
|
||||
if (silence >= Tno_token)
|
||||
if (silence >= Tno_token) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_WAIT_FOR_REPLY:
|
||||
if (silence >= mstp_port->Treply_timeout)
|
||||
if (silence >= mstp_port->Treply_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
case MSTP_MASTER_STATE_POLL_FOR_MASTER:
|
||||
if (silence >= mstp_port->Tusage_timeout)
|
||||
if (silence >= mstp_port->Tusage_timeout) {
|
||||
run_master = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
run_master = true;
|
||||
@@ -324,8 +327,9 @@ uint16_t MSTP_Put_Receive(struct mstp_port_struct_t *mstp_port)
|
||||
if (!poSharedData->Receive_Packet.ready) {
|
||||
/* bounds check - maybe this should send an abort? */
|
||||
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);
|
||||
}
|
||||
memmove(
|
||||
(void *)&poSharedData->Receive_Packet.pdu[0],
|
||||
(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 */
|
||||
if (mac_address <= 127) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
+63
-84
@@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
*
|
||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*********************************************************************/
|
||||
#ifndef DLMSTP_LINUX_H
|
||||
#define DLMSTP_LINUX_H
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
#include "bacnet/basic/sys/ringbuf.h"
|
||||
/* defines specific to MS/TP */
|
||||
/* preamble+type+dest+src+len+crc8+crc16 */
|
||||
#define DLMSTP_HEADER_MAX (2+1+1+1+2+1+2)
|
||||
#define DLMSTP_MPDU_MAX (DLMSTP_HEADER_MAX+MAX_PDU)
|
||||
#define DLMSTP_HEADER_MAX (2 + 1 + 1 + 1 + 2 + 1 + 2)
|
||||
#define DLMSTP_MPDU_MAX (DLMSTP_HEADER_MAX + MAX_PDU)
|
||||
|
||||
/* count must be a power of 2 for ringbuf library */
|
||||
#ifndef MSTP_PDU_PACKET_COUNT
|
||||
@@ -103,96 +103,75 @@ typedef struct shared_mstp_data {
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_init(
|
||||
void *poShared,
|
||||
char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_reset(
|
||||
void *poShared);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_cleanup(
|
||||
void *poShared);
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_init(void *poShared, char *ifname);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_reset(void *poShared);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_cleanup(void *poShared);
|
||||
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
int dlmstp_send_pdu(
|
||||
/* returns number of bytes sent on success, negative on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
int dlmstp_send_pdu(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS * dest, /* destination address */
|
||||
uint8_t * pdu, /* any data to be sent - may be null */
|
||||
BACNET_ADDRESS *dest, /* destination address */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len); /* number of bytes of data */
|
||||
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t dlmstp_receive(
|
||||
/* returns the number of octets in the PDU, or zero on failure */
|
||||
BACNET_STACK_EXPORT
|
||||
uint16_t dlmstp_receive(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS * src, /* source address */
|
||||
uint8_t * pdu, /* PDU data */
|
||||
BACNET_ADDRESS *src, /* source address */
|
||||
uint8_t *pdu, /* PDU data */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout); /* milliseconds to wait for a packet */
|
||||
|
||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||
/* maximum number of information frames the node may send before it must */
|
||||
/* pass the token. Max_Info_Frames may have different values on different */
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_info_frames(
|
||||
void *poShared,
|
||||
uint8_t max_info_frames);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_info_frames(
|
||||
void *poShared);
|
||||
/* This parameter represents the value of the Max_Info_Frames property of */
|
||||
/* the node's Device object. The value of Max_Info_Frames specifies the */
|
||||
/* maximum number of information frames the node may send before it must */
|
||||
/* pass the token. Max_Info_Frames may have different values on different */
|
||||
/* nodes. This may be used to allocate more or less of the available link */
|
||||
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
|
||||
/* node, its value shall be 1. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_info_frames(void *poShared, uint8_t max_info_frames);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_info_frames(void *poShared);
|
||||
|
||||
/* This parameter represents the value of the Max_Master property of the */
|
||||
/* node's Device object. The value of Max_Master specifies the highest */
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_master(
|
||||
void *poShared,
|
||||
uint8_t max_master);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_master(
|
||||
void *poShared);
|
||||
/* This parameter represents the value of the Max_Master property of the */
|
||||
/* node's Device object. The value of Max_Master specifies the highest */
|
||||
/* allowable address for master nodes. The value of Max_Master shall be */
|
||||
/* less than or equal to 127. If Max_Master is not writable in a node, */
|
||||
/* its value shall be 127. */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_max_master(void *poShared, uint8_t max_master);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_max_master(void *poShared);
|
||||
|
||||
/* MAC address 0-127 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_mac_address(
|
||||
void *poShared,
|
||||
uint8_t my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_mac_address(
|
||||
void *poShared);
|
||||
/* MAC address 0-127 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_mac_address(void *poShared, uint8_t my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
uint8_t dlmstp_mac_address(void *poShared);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_my_address(
|
||||
void *poShared,
|
||||
BACNET_ADDRESS * my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_broadcast_address(
|
||||
BACNET_ADDRESS * dest); /* destination address */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_my_address(void *poShared, BACNET_ADDRESS *my_address);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_get_broadcast_address(
|
||||
BACNET_ADDRESS *dest); /* destination address */
|
||||
|
||||
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_baud_rate(
|
||||
void *poShared,
|
||||
uint32_t baud);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t dlmstp_baud_rate(
|
||||
void *poShared);
|
||||
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_set_baud_rate(void *poShared, uint32_t baud);
|
||||
BACNET_STACK_EXPORT
|
||||
uint32_t dlmstp_baud_rate(void *poShared);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_fill_bacnet_address(
|
||||
BACNET_ADDRESS * src,
|
||||
uint8_t mstp_address);
|
||||
BACNET_STACK_EXPORT
|
||||
void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_sole_master(
|
||||
void);
|
||||
BACNET_STACK_EXPORT
|
||||
bool dlmstp_sole_master(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+48
-27
@@ -17,8 +17,9 @@
|
||||
* BACnet/Ethernet. */
|
||||
|
||||
/* commonly used comparison address for ethernet */
|
||||
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF };
|
||||
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
/* commonly used empty address for ethernet quick compare */
|
||||
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)
|
||||
{
|
||||
if (ethernet_valid())
|
||||
if (ethernet_valid()) {
|
||||
close(eth802_sockfd);
|
||||
}
|
||||
eth802_sockfd = -1;
|
||||
|
||||
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 */
|
||||
uid = getuid();
|
||||
if (uid != 0) {
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"ethernet: Unable to open an 802.2 socket. "
|
||||
"Try running with root priveleges.\n");
|
||||
return sock_fd;
|
||||
@@ -93,7 +96,8 @@ static int ethernet_bind(struct sockaddr *eth_addr, const char *interface_name)
|
||||
/* Error occured */
|
||||
fprintf(
|
||||
stderr, "ethernet: Error opening socket: %s\n", strerror(errno));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\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 */
|
||||
if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0) {
|
||||
/* 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));
|
||||
fprintf(stderr,
|
||||
fprintf(
|
||||
stderr,
|
||||
"You might need to add the following to modules.conf\n"
|
||||
"(or in /etc/modutils/alias on Debian with update-modules):\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 */
|
||||
strcpy(ifr.ifr_name, ifname);
|
||||
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
rv = fd;
|
||||
else {
|
||||
} else {
|
||||
rv = ioctl(fd, SIOCGIFHWADDR, &ifr);
|
||||
if (rv >= 0) /* worked okay */
|
||||
if (rv >= 0) { /* worked okay */
|
||||
memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -179,19 +186,22 @@ int ethernet_send(uint8_t *mtu, int mtu_len)
|
||||
int bytes = 0;
|
||||
|
||||
/* Send the packet */
|
||||
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
|
||||
(struct sockaddr *)ð_addr, sizeof(struct sockaddr));
|
||||
bytes = sendto(
|
||||
eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *)ð_addr,
|
||||
sizeof(struct sockaddr));
|
||||
/* did it get sent? */
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* function to send a packet out the 802.2 socket */
|
||||
/* 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 */
|
||||
uint8_t *pdu, /* any data to be sent - may be null */
|
||||
unsigned pdu_len)
|
||||
@@ -248,19 +258,22 @@ int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
|
||||
encode_unsigned16(&mtu[12], 3 + pdu_len);
|
||||
|
||||
/* Send the packet */
|
||||
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
|
||||
(struct sockaddr *)ð_addr, sizeof(struct sockaddr));
|
||||
bytes = sendto(
|
||||
eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *)ð_addr,
|
||||
sizeof(struct sockaddr));
|
||||
/* did it get sent? */
|
||||
if (bytes < 0)
|
||||
if (bytes < 0) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/* receives an 802.2 framed packet */
|
||||
/* 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 */
|
||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||
unsigned timeout)
|
||||
@@ -273,8 +286,9 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
struct timeval select_timeout;
|
||||
|
||||
/* Make sure the socket is open */
|
||||
if (eth802_sockfd <= 0)
|
||||
if (eth802_sockfd <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
@@ -291,24 +305,28 @@ uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
|
||||
FD_SET(eth802_sockfd, &read_fds);
|
||||
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));
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See if there is a problem */
|
||||
if (received_bytes < 0) {
|
||||
/* EAGAIN Non-blocking I/O has been selected */
|
||||
/* using O_NONBLOCK and no data */
|
||||
/* was immediately available for reading. */
|
||||
if (errno != EAGAIN)
|
||||
fprintf(stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
if (errno != EAGAIN) {
|
||||
fprintf(
|
||||
stderr, "ethernet: Read error in receiving packet: %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (received_bytes == 0)
|
||||
if (received_bytes == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the signature of an 802.2 BACnet packet */
|
||||
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);
|
||||
pdu_len -= 3 /* DSAP, SSAP, LLC Control */;
|
||||
/* copy the buffer into the PDU */
|
||||
if (pdu_len < max_pdu)
|
||||
if (pdu_len < max_pdu) {
|
||||
memmove(&pdu[0], &buf[17], pdu_len);
|
||||
}
|
||||
/* ignore packets that are too large */
|
||||
else
|
||||
else {
|
||||
pdu_len = 0;
|
||||
}
|
||||
|
||||
return pdu_len;
|
||||
}
|
||||
@@ -391,8 +411,9 @@ void ethernet_debug_address(const char *info, const BACNET_ADDRESS *dest)
|
||||
{
|
||||
int i = 0; /* counter */
|
||||
|
||||
if (info)
|
||||
if (info) {
|
||||
fprintf(stderr, "%s", info);
|
||||
}
|
||||
if (dest) {
|
||||
fprintf(stderr, "Address:\n");
|
||||
fprintf(stderr, " MAC Length=%d\n", dest->mac_len);
|
||||
|
||||
@@ -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 */
|
||||
/* Return: amount of PDU data */
|
||||
uint16_t MSTP_Get_Send(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Send(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void)mstp_port;
|
||||
(void)timeout;
|
||||
@@ -84,7 +83,7 @@ uint16_t MSTP_Get_Send(
|
||||
*/
|
||||
void MSTP_Send_Frame(
|
||||
struct mstp_port_struct_t *mstp_port,
|
||||
const uint8_t * buffer,
|
||||
const uint8_t *buffer,
|
||||
uint16_t nbytes)
|
||||
{
|
||||
(void)mstp_port;
|
||||
@@ -92,8 +91,7 @@ void MSTP_Send_Frame(
|
||||
(void)nbytes;
|
||||
}
|
||||
|
||||
uint16_t MSTP_Get_Reply(
|
||||
struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
uint16_t MSTP_Get_Reply(struct mstp_port_struct_t *mstp_port, unsigned timeout)
|
||||
{ /* milliseconds to wait for a packet */
|
||||
(void)mstp_port;
|
||||
(void)timeout;
|
||||
@@ -140,8 +138,8 @@ static int network_init(const char *name, int protocol)
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static void snap_received_packet(
|
||||
const struct mstp_port_struct_t *mstp_port, int sockfd)
|
||||
static void
|
||||
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 */
|
||||
unsigned i = 0; /* counter */
|
||||
@@ -267,7 +265,8 @@ int main(int argc, char *argv[])
|
||||
MSTP_Port.SilenceTimer = Timer_Silence;
|
||||
MSTP_Port.SilenceTimerReset = Timer_Silence_Reset;
|
||||
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());
|
||||
atexit(cleanup);
|
||||
#if defined(_WIN32)
|
||||
|
||||
+13
-7
@@ -569,12 +569,14 @@ void RS485_Initialize(void)
|
||||
newserial.custom_divisor = round(((float)newserial.baud_base) / 76800);
|
||||
/* we must check that we calculated some sane value;
|
||||
small baud bases yield bad custom divisor values */
|
||||
baud_error = fabs(1 -
|
||||
baud_error = fabs(
|
||||
1 -
|
||||
((float)newserial.baud_base) / ((float)newserial.custom_divisor) /
|
||||
76800);
|
||||
if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) {
|
||||
/* 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);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -617,19 +619,22 @@ void RS485_Print_Ports(void)
|
||||
while (n--) {
|
||||
if (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);
|
||||
/* Stat the devicedir and handle it if it is a symlink */
|
||||
if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) {
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
snprintf(device_dir, sizeof(device_dir),
|
||||
"%s%s/device/driver", sysdir, namelist[n]->d_name);
|
||||
snprintf(
|
||||
device_dir, sizeof(device_dir), "%s%s/device/driver",
|
||||
sysdir, namelist[n]->d_name);
|
||||
if (readlink(device_dir, buffer, sizeof(buffer)) > 0) {
|
||||
valid_port = false;
|
||||
driver_name = basename(buffer);
|
||||
if (strcmp(driver_name, "serial8250") == 0) {
|
||||
/* 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);
|
||||
fd = open(
|
||||
device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY);
|
||||
@@ -649,7 +654,8 @@ void RS485_Print_Ports(void)
|
||||
}
|
||||
if (valid_port) {
|
||||
/* print full absolute file path */
|
||||
printf("interface {value=/dev/%s}"
|
||||
printf(
|
||||
"interface {value=/dev/%s}"
|
||||
"{display=MS/TP Capture on /dev/%s}\n",
|
||||
namelist[n]->d_name, namelist[n]->d_name);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user