Added some missing services to APDU. Fix maxes. Refactor Simple Ack.
This commit is contained in:
@@ -1478,7 +1478,7 @@ typedef enum BACnet_Confirmed_Service_Choice {
|
||||
/* Services added after 2016 */
|
||||
/* confirmed-audit-notification [32] see Alarm and Event Services */
|
||||
/* audit-log-query [33] see Object Access Services */
|
||||
MAX_BACNET_CONFIRMED_SERVICE = 30
|
||||
MAX_BACNET_CONFIRMED_SERVICE = 34
|
||||
} BACNET_CONFIRMED_SERVICE;
|
||||
|
||||
/* BACnetUnconfirmedServiceChoice ::= ENUMERATED */
|
||||
@@ -1515,6 +1515,7 @@ typedef enum BACnet_Services_Supported {
|
||||
/* Alarm and Event Services */
|
||||
SERVICE_SUPPORTED_ACKNOWLEDGE_ALARM = 0,
|
||||
SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION = 1,
|
||||
SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION_MULTIPLE = 42,
|
||||
SERVICE_SUPPORTED_CONFIRMED_EVENT_NOTIFICATION = 2,
|
||||
SERVICE_SUPPORTED_GET_ALARM_SUMMARY = 3,
|
||||
SERVICE_SUPPORTED_GET_ENROLLMENT_SUMMARY = 4,
|
||||
|
||||
+129
-160
@@ -76,7 +76,11 @@ static BACNET_SERVICES_SUPPORTED
|
||||
SERVICE_SUPPORTED_AUTHENTICATE, SERVICE_SUPPORTED_REQUEST_KEY,
|
||||
SERVICE_SUPPORTED_READ_RANGE, SERVICE_SUPPORTED_LIFE_SAFETY_OPERATION,
|
||||
SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY,
|
||||
SERVICE_SUPPORTED_GET_EVENT_INFORMATION
|
||||
SERVICE_SUPPORTED_GET_EVENT_INFORMATION,
|
||||
SERVICE_SUPPORTED_SUBSCRIBE_COV_PROPERTY_MULTIPLE,
|
||||
SERVICE_SUPPORTED_CONFIRMED_COV_NOTIFICATION_MULTIPLE,
|
||||
SERVICE_SUPPORTED_CONFIRMED_AUDIT_NOTIFICATION,
|
||||
SERVICE_SUPPORTED_AUDIT_LOG_QUERY
|
||||
};
|
||||
|
||||
/* a simple table for crossing the services supported */
|
||||
@@ -88,7 +92,13 @@ static BACNET_SERVICES_SUPPORTED
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_PRIVATE_TRANSFER,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_TEXT_MESSAGE,
|
||||
SERVICE_SUPPORTED_TIME_SYNCHRONIZATION, SERVICE_SUPPORTED_WHO_HAS,
|
||||
SERVICE_SUPPORTED_WHO_IS, SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION
|
||||
SERVICE_SUPPORTED_WHO_IS,
|
||||
SERVICE_SUPPORTED_UTC_TIME_SYNCHRONIZATION,
|
||||
SERVICE_SUPPORTED_WRITE_GROUP,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_COV_NOTIFICATION_MULTIPLE,
|
||||
SERVICE_SUPPORTED_UNCONFIRMED_AUDIT_NOTIFICATION,
|
||||
SERVICE_SUPPORTED_WHO_AM_I,
|
||||
SERVICE_SUPPORTED_YOU_ARE
|
||||
};
|
||||
|
||||
/* Confirmed Function Handlers */
|
||||
@@ -241,16 +251,24 @@ static union {
|
||||
confirmed_ack_function complex;
|
||||
} Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
||||
|
||||
void apdu_set_confirmed_simple_ack_handler(
|
||||
BACNET_CONFIRMED_SERVICE service_choice,
|
||||
confirmed_simple_ack_function pFunction)
|
||||
/**
|
||||
* @brief Determine if the BACnet service is a Simple Ack Service
|
||||
* @param service_choice [in] BACnet confirmed service choice
|
||||
*/
|
||||
bool apdu_confirmed_simple_ack_service(
|
||||
BACNET_CONFIRMED_SERVICE service_choice)
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM:
|
||||
case SERVICE_CONFIRMED_AUDIT_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_COV_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_COV_NOTIFICATION_MULTIPLE:
|
||||
case SERVICE_CONFIRMED_EVENT_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY_MULTIPLE:
|
||||
case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_ADD_LIST_ELEMENT:
|
||||
@@ -266,40 +284,29 @@ void apdu_set_confirmed_simple_ack_handler(
|
||||
case SERVICE_CONFIRMED_VT_CLOSE:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_REQUEST_KEY:
|
||||
Confirmed_ACK_Function[service_choice].simple = pFunction;
|
||||
status = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void apdu_set_confirmed_simple_ack_handler(
|
||||
BACNET_CONFIRMED_SERVICE service_choice,
|
||||
confirmed_simple_ack_function pFunction)
|
||||
{
|
||||
if (apdu_confirmed_simple_ack_service(service_choice)) {
|
||||
Confirmed_ACK_Function[service_choice].simple = pFunction;
|
||||
}
|
||||
}
|
||||
|
||||
void apdu_set_confirmed_ack_handler(
|
||||
BACNET_CONFIRMED_SERVICE service_choice, confirmed_ack_function pFunction)
|
||||
{
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_GET_ALARM_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_EVENT_INFORMATION:
|
||||
/* File Access Services */
|
||||
case SERVICE_CONFIRMED_ATOMIC_READ_FILE:
|
||||
case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_CREATE_OBJECT:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY:
|
||||
case SERVICE_CONFIRMED_READ_PROP_CONDITIONAL:
|
||||
case SERVICE_CONFIRMED_READ_PROP_MULTIPLE:
|
||||
case SERVICE_CONFIRMED_READ_RANGE:
|
||||
/* Remote Device Management Services */
|
||||
case SERVICE_CONFIRMED_PRIVATE_TRANSFER:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_OPEN:
|
||||
case SERVICE_CONFIRMED_VT_DATA:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_AUTHENTICATE:
|
||||
Confirmed_ACK_Function[service_choice].complex = pFunction;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (!apdu_confirmed_simple_ack_service(service_choice)) {
|
||||
Confirmed_ACK_Function[service_choice].complex = pFunction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,109 +585,68 @@ void apdu_handler(BACNET_ADDRESS *src,
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
|
||||
if (apdu_len >= 2) {
|
||||
service_choice = apdu[1];
|
||||
service_request = &apdu[2];
|
||||
service_request_len = apdu_len - 2;
|
||||
if (apdu_unconfirmed_dcc_disabled(service_choice)) {
|
||||
/* When network communications are disabled,
|
||||
only DeviceCommunicationControl and
|
||||
ReinitializeDevice APDUs shall be processed and no
|
||||
messages shall be initiated. If communications have
|
||||
been initiation disabled, then WhoIs may be
|
||||
processed. */
|
||||
break;
|
||||
}
|
||||
if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) {
|
||||
if (Unconfirmed_Function[service_choice]) {
|
||||
Unconfirmed_Function[service_choice](
|
||||
service_request, service_request_len, src);
|
||||
}
|
||||
if (apdu_len < 3) {
|
||||
break;
|
||||
}
|
||||
service_choice = apdu[1];
|
||||
service_request = &apdu[2];
|
||||
service_request_len = apdu_len - 2;
|
||||
if (apdu_unconfirmed_dcc_disabled(service_choice)) {
|
||||
/* When network communications are disabled,
|
||||
only DeviceCommunicationControl and
|
||||
ReinitializeDevice APDUs shall be processed and no
|
||||
messages shall be initiated. If communications have
|
||||
been initiation disabled, then WhoIs may be
|
||||
processed. */
|
||||
break;
|
||||
}
|
||||
if (service_choice < MAX_BACNET_UNCONFIRMED_SERVICE) {
|
||||
if (Unconfirmed_Function[service_choice]) {
|
||||
Unconfirmed_Function[service_choice](
|
||||
service_request, service_request_len, src);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_SIMPLE_ACK:
|
||||
if (apdu_len >= 3) {
|
||||
invoke_id = apdu[1];
|
||||
service_choice = apdu[2];
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM:
|
||||
case SERVICE_CONFIRMED_COV_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_EVENT_NOTIFICATION:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV:
|
||||
case SERVICE_CONFIRMED_SUBSCRIBE_COV_PROPERTY:
|
||||
case SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_ADD_LIST_ELEMENT:
|
||||
case SERVICE_CONFIRMED_REMOVE_LIST_ELEMENT:
|
||||
case SERVICE_CONFIRMED_DELETE_OBJECT:
|
||||
case SERVICE_CONFIRMED_WRITE_PROPERTY:
|
||||
case SERVICE_CONFIRMED_WRITE_PROP_MULTIPLE:
|
||||
/* Remote Device Management Services */
|
||||
case SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL:
|
||||
case SERVICE_CONFIRMED_REINITIALIZE_DEVICE:
|
||||
case SERVICE_CONFIRMED_TEXT_MESSAGE:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_CLOSE:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_REQUEST_KEY:
|
||||
if (Confirmed_ACK_Function[service_choice].simple !=
|
||||
NULL) {
|
||||
Confirmed_ACK_Function[service_choice].simple(
|
||||
src, invoke_id);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (apdu_len < 3) {
|
||||
break;
|
||||
}
|
||||
invoke_id = apdu[1];
|
||||
service_choice = apdu[2];
|
||||
if (apdu_confirmed_simple_ack_service(service_choice)) {
|
||||
if (Confirmed_ACK_Function[service_choice].simple !=
|
||||
NULL) {
|
||||
Confirmed_ACK_Function[service_choice].simple(
|
||||
src, invoke_id);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_COMPLEX_ACK:
|
||||
if (apdu_len >= 3) {
|
||||
service_ack_data.segmented_message =
|
||||
(apdu[0] & BIT(3)) ? true : false;
|
||||
service_ack_data.more_follows =
|
||||
(apdu[0] & BIT(2)) ? true : false;
|
||||
invoke_id = service_ack_data.invoke_id = apdu[1];
|
||||
len = 2;
|
||||
if (service_ack_data.segmented_message) {
|
||||
service_ack_data.sequence_number = apdu[len++];
|
||||
service_ack_data.proposed_window_number = apdu[len++];
|
||||
}
|
||||
service_choice = apdu[len++];
|
||||
service_request = &apdu[len];
|
||||
service_request_len = apdu_len - (uint16_t)len;
|
||||
switch (service_choice) {
|
||||
case SERVICE_CONFIRMED_GET_ALARM_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_ENROLLMENT_SUMMARY:
|
||||
case SERVICE_CONFIRMED_GET_EVENT_INFORMATION:
|
||||
/* File Access Services */
|
||||
case SERVICE_CONFIRMED_ATOMIC_READ_FILE:
|
||||
case SERVICE_CONFIRMED_ATOMIC_WRITE_FILE:
|
||||
/* Object Access Services */
|
||||
case SERVICE_CONFIRMED_CREATE_OBJECT:
|
||||
case SERVICE_CONFIRMED_READ_PROPERTY:
|
||||
case SERVICE_CONFIRMED_READ_PROP_CONDITIONAL:
|
||||
case SERVICE_CONFIRMED_READ_PROP_MULTIPLE:
|
||||
case SERVICE_CONFIRMED_READ_RANGE:
|
||||
case SERVICE_CONFIRMED_PRIVATE_TRANSFER:
|
||||
/* Virtual Terminal Services */
|
||||
case SERVICE_CONFIRMED_VT_OPEN:
|
||||
case SERVICE_CONFIRMED_VT_DATA:
|
||||
/* Security Services */
|
||||
case SERVICE_CONFIRMED_AUTHENTICATE:
|
||||
if (Confirmed_ACK_Function[service_choice]
|
||||
.complex != NULL) {
|
||||
Confirmed_ACK_Function[service_choice].complex(
|
||||
service_request, service_request_len, src,
|
||||
&service_ack_data);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (apdu_len < 3) {
|
||||
break;
|
||||
}
|
||||
service_ack_data.segmented_message =
|
||||
(apdu[0] & BIT(3)) ? true : false;
|
||||
service_ack_data.more_follows =
|
||||
(apdu[0] & BIT(2)) ? true : false;
|
||||
invoke_id = service_ack_data.invoke_id = apdu[1];
|
||||
len = 2;
|
||||
if (service_ack_data.segmented_message) {
|
||||
service_ack_data.sequence_number = apdu[len++];
|
||||
service_ack_data.proposed_window_number = apdu[len++];
|
||||
}
|
||||
service_choice = apdu[len++];
|
||||
service_request = &apdu[len];
|
||||
service_request_len = apdu_len - (uint16_t)len;
|
||||
if (!apdu_confirmed_simple_ack_service(service_choice)) {
|
||||
if (Confirmed_ACK_Function[service_choice]
|
||||
.complex != NULL) {
|
||||
Confirmed_ACK_Function[service_choice].complex(
|
||||
service_request, service_request_len, src,
|
||||
&service_ack_data);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
}
|
||||
break;
|
||||
case PDU_TYPE_SEGMENT_ACK:
|
||||
@@ -688,49 +654,52 @@ void apdu_handler(BACNET_ADDRESS *src,
|
||||
we could check src to see if that matched the tsm */
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
case PDU_TYPE_ERROR:
|
||||
if (apdu_len >= 3) {
|
||||
invoke_id = apdu[1];
|
||||
service_choice = apdu[2];
|
||||
if (apdu_complex_error(service_choice)) {
|
||||
if (Error_Function[service_choice].complex) {
|
||||
Error_Function[service_choice].complex(src,
|
||||
invoke_id, service_choice, &apdu[3],
|
||||
apdu_len - 3);
|
||||
}
|
||||
} else if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) {
|
||||
len = bacerror_decode_error_class_and_code(
|
||||
&apdu[3], apdu_len - 3, &error_class, &error_code);
|
||||
if ((len != 0) &&
|
||||
(Error_Function[service_choice].error)) {
|
||||
Error_Function[service_choice].error(src, invoke_id,
|
||||
(BACNET_ERROR_CLASS)error_class,
|
||||
(BACNET_ERROR_CODE)error_code);
|
||||
}
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
case PDU_TYPE_ERROR:
|
||||
if (apdu_len < 3) {
|
||||
break;
|
||||
}
|
||||
invoke_id = apdu[1];
|
||||
service_choice = apdu[2];
|
||||
if (apdu_complex_error(service_choice)) {
|
||||
if (Error_Function[service_choice].complex) {
|
||||
Error_Function[service_choice].complex(src,
|
||||
invoke_id, service_choice, &apdu[3],
|
||||
apdu_len - 3);
|
||||
}
|
||||
} else if (service_choice < MAX_BACNET_CONFIRMED_SERVICE) {
|
||||
len = bacerror_decode_error_class_and_code(
|
||||
&apdu[3], apdu_len - 3, &error_class, &error_code);
|
||||
if ((len != 0) &&
|
||||
(Error_Function[service_choice].error)) {
|
||||
Error_Function[service_choice].error(src, invoke_id,
|
||||
(BACNET_ERROR_CLASS)error_class,
|
||||
(BACNET_ERROR_CODE)error_code);
|
||||
}
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
case PDU_TYPE_REJECT:
|
||||
if (apdu_len >= 3) {
|
||||
invoke_id = apdu[1];
|
||||
reason = apdu[2];
|
||||
if (Reject_Function) {
|
||||
Reject_Function(src, invoke_id, reason);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
if (apdu_len < 3) {
|
||||
break;
|
||||
}
|
||||
invoke_id = apdu[1];
|
||||
reason = apdu[2];
|
||||
if (Reject_Function) {
|
||||
Reject_Function(src, invoke_id, reason);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
case PDU_TYPE_ABORT:
|
||||
if (apdu_len >= 3) {
|
||||
server = apdu[0] & 0x01;
|
||||
invoke_id = apdu[1];
|
||||
reason = apdu[2];
|
||||
if (Abort_Function) {
|
||||
Abort_Function(src, invoke_id, reason, server);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
if (apdu_len < 3) {
|
||||
break;
|
||||
}
|
||||
server = apdu[0] & 0x01;
|
||||
invoke_id = apdu[1];
|
||||
reason = apdu[2];
|
||||
if (Abort_Function) {
|
||||
Abort_Function(src, invoke_id, reason, server);
|
||||
}
|
||||
tsm_free_invoke_id(invoke_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -125,6 +125,10 @@ extern "C" {
|
||||
BACNET_CONFIRMED_SERVICE service_choice,
|
||||
confirmed_ack_function pFunction);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool apdu_confirmed_simple_ack_service(
|
||||
BACNET_CONFIRMED_SERVICE service_choice);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
void apdu_set_confirmed_simple_ack_handler(
|
||||
BACNET_CONFIRMED_SERVICE service_choice,
|
||||
|
||||
Reference in New Issue
Block a user