Added BACnetRecipient and BACnetAddressBinding codecs for EPICS application (#1163)

* Added BACnetRecipient and BACnetAddressBinding encoding, decoding, ASCII conversion, comparison, and copy functions.

*  Added library specific string manipulation utilities including strcmp, strncmp, stptok, and snprintf with offset functions.

* Added test/README about verification and validation testing.
This commit is contained in:
Steve Karg
2025-11-27 23:12:39 -06:00
committed by GitHub
parent 21626d1ac5
commit ca9836b099
28 changed files with 1875 additions and 207 deletions
+75 -7
View File
@@ -535,6 +535,18 @@ int bacapp_encode_application_data(
apdu, &value->type.Timer_Value);
break;
#endif
#if defined(BACAPP_RECIPIENT)
case BACNET_APPLICATION_TAG_RECIPIENT:
apdu_len =
bacnet_recipient_encode(apdu, &value->type.Recipient);
break;
#endif
#if defined(BACAPP_ADDRESS_BINDING)
case BACNET_APPLICATION_TAG_ADDRESS_BINDING:
apdu_len = bacnet_address_binding_type_encode(
apdu, &value->type.Address_Binding);
break;
#endif
#if defined(BACAPP_NO_VALUE)
case BACNET_APPLICATION_TAG_NO_VALUE:
apdu_len = bacnet_timer_value_no_value_encode(apdu);
@@ -1308,14 +1320,14 @@ int bacapp_known_property_tag(
case PROP_TIME_SYNCHRONIZATION_RECIPIENTS:
case PROP_RESTART_NOTIFICATION_RECIPIENTS:
case PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS:
/* FIXME: Properties using BACnetRecipient */
return -1;
/* Properties using BACnetRecipient */
return BACNET_APPLICATION_TAG_RECIPIENT;
case PROP_DEVICE_ADDRESS_BINDING:
case PROP_MANUAL_SLAVE_ADDRESS_BINDING:
case PROP_SLAVE_ADDRESS_BINDING:
/* FIXME: BACnetAddressBinding */
return -1;
/* BACnetAddressBinding */
return BACNET_APPLICATION_TAG_ADDRESS_BINDING;
case PROP_LOG_BUFFER:
/* BACnetLogRecord */
@@ -1684,6 +1696,18 @@ int bacapp_decode_application_tag_value(
apdu, apdu_size, &value->type.Timer_Value);
break;
#endif
#if defined(BACAPP_RECIPIENT)
case BACNET_APPLICATION_TAG_RECIPIENT:
apdu_len = bacnet_recipient_decode(
apdu, apdu_size, &value->type.Recipient);
break;
#endif
#if defined(BACAPP_ADDRESS_BINDING)
case BACNET_APPLICATION_TAG_ADDRESS_BINDING:
apdu_len = bacnet_address_binding_decode(
apdu, apdu_size, &value->type.Address_Binding);
break;
#endif
#if defined(BACAPP_LOG_RECORD)
case BACNET_APPLICATION_TAG_LOG_RECORD:
/* BACnetLogRecord */
@@ -2196,10 +2220,12 @@ int bacapp_snprintf_octet_string(
int len = 0;
int slen = 0;
int i = 0;
const uint8_t *octet_str;
slen = bacapp_snprintf(str, str_len, "X'");
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
len = octetstring_length(value);
if (len > 0) {
const uint8_t *octet_str;
octet_str = octetstring_value((BACNET_OCTET_STRING *)value);
for (i = 0; i < len; i++) {
slen = bacapp_snprintf(str, str_len, "%02X", *octet_str);
@@ -2207,6 +2233,8 @@ int bacapp_snprintf_octet_string(
octet_str++;
}
}
slen = bacapp_snprintf(str, str_len, "'");
ret_val += bacapp_snprintf_shift(slen, &str, &str_len);
return ret_val;
}
@@ -4027,6 +4055,18 @@ int bacapp_snprintf_value(
&value->type.Timer_Value, str, str_len);
break;
#endif
#if defined(BACAPP_RECIPIENT)
case BACNET_APPLICATION_TAG_RECIPIENT:
ret_val = bacnet_recipient_to_ascii(
&value->type.Recipient, str, str_len);
break;
#endif
#if defined(BACAPP_ADDRESS_BINDING)
case BACNET_APPLICATION_TAG_ADDRESS_BINDING:
ret_val = bacnet_address_binding_to_ascii(
&value->type.Address_Binding, str, str_len);
break;
#endif
#if defined(BACAPP_NO_VALUE)
case BACNET_APPLICATION_TAG_NO_VALUE:
ret_val = bacnet_timer_value_no_value_to_ascii(str, str_len);
@@ -4542,8 +4582,11 @@ bool bacapp_parse_application_data(
#endif
#if defined(BACAPP_OCTET_STRING)
case BACNET_APPLICATION_TAG_OCTET_STRING:
status =
octetstring_init_ascii_hex(&value->type.Octet_String, argv);
if (!octetstring_init_ascii_epics(
&value->type.Octet_String, argv)) {
status = octetstring_init_ascii_hex(
&value->type.Octet_String, argv);
}
break;
#endif
#if defined(BACAPP_CHARACTER_STRING)
@@ -4741,6 +4784,18 @@ bool bacapp_parse_application_data(
&value->type.Timer_Value, argv);
break;
#endif
#if defined(BACAPP_RECIPIENT)
case BACNET_APPLICATION_TAG_RECIPIENT:
status =
bacnet_recipient_from_ascii(&value->type.Recipient, argv);
break;
#endif
#if defined(BACAPP_ADDRESS_BINDING)
case BACNET_APPLICATION_TAG_ADDRESS_BINDING:
status = bacnet_address_binding_from_ascii(
&value->type.Address_Binding, argv);
break;
#endif
#if defined(BACAPP_NO_VALUE)
case BACNET_APPLICATION_TAG_NO_VALUE:
status =
@@ -5495,6 +5550,19 @@ bool bacapp_same_value(
&value->type.Timer_Value, &test_value->type.Timer_Value);
break;
#endif
#if defined(BACAPP_RECIPIENT)
case BACNET_APPLICATION_TAG_RECIPIENT:
status = bacnet_recipient_same(
&value->type.Recipient, &test_value->type.Recipient);
break;
#endif
#if defined(BACAPP_ADDRESS_BINDING)
case BACNET_APPLICATION_TAG_ADDRESS_BINDING:
status = bacnet_address_binding_same(
&value->type.Address_Binding,
&test_value->type.Address_Binding);
break;
#endif
#if defined(BACAPP_NO_VALUE)
case BACNET_APPLICATION_TAG_NO_VALUE:
if (value->tag == test_value->tag) {