added error, abort, and reject optional handlers.
This commit is contained in:
+71
-1
@@ -149,6 +149,33 @@ void apdu_set_confirmed_ack_handler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static error_function
|
||||||
|
Error_Function[MAX_BACNET_CONFIRMED_SERVICE];
|
||||||
|
|
||||||
|
void apdu_set_error_handler(
|
||||||
|
BACNET_CONFIRMED_SERVICE service_choice,
|
||||||
|
error_function pFunction)
|
||||||
|
{
|
||||||
|
if (service_choice < MAX_BACNET_CONFIRMED_SERVICE)
|
||||||
|
Error_Function[service_choice] = pFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
static abort_function Abort_Function;
|
||||||
|
|
||||||
|
void apdu_set_abort_handler(
|
||||||
|
abort_function pFunction)
|
||||||
|
{
|
||||||
|
Abort_Function = pFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
static reject_function Reject_Function;
|
||||||
|
|
||||||
|
void apdu_set_reject_handler(
|
||||||
|
reject_function pFunction)
|
||||||
|
{
|
||||||
|
Reject_Function = pFunction;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t apdu_decode_confirmed_service_request(
|
uint16_t apdu_decode_confirmed_service_request(
|
||||||
uint8_t *apdu, // APDU data
|
uint8_t *apdu, // APDU data
|
||||||
uint16_t apdu_len,
|
uint16_t apdu_len,
|
||||||
@@ -191,6 +218,11 @@ void apdu_handler(
|
|||||||
uint8_t *service_request = NULL;
|
uint8_t *service_request = NULL;
|
||||||
uint16_t service_request_len = 0;
|
uint16_t service_request_len = 0;
|
||||||
uint16_t len = 0; // counts where we are in PDU
|
uint16_t len = 0; // counts where we are in PDU
|
||||||
|
uint8_t tag_number = 0;
|
||||||
|
uint32_t len_value = 0;
|
||||||
|
int error_code = 0;
|
||||||
|
int error_class = 0;
|
||||||
|
uint8_t reason = 0;
|
||||||
|
|
||||||
(void)data_expecting_reply;
|
(void)data_expecting_reply;
|
||||||
if (apdu)
|
if (apdu)
|
||||||
@@ -325,11 +357,49 @@ void apdu_handler(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PDU_TYPE_SEGMENT_ACK:
|
case PDU_TYPE_SEGMENT_ACK:
|
||||||
|
/* FIXME: what about a denial of service attack here?
|
||||||
|
we could check src to see if that matched the tsm */
|
||||||
|
tsm_free_invoke_id(invoke_id);
|
||||||
|
break;
|
||||||
case PDU_TYPE_ERROR:
|
case PDU_TYPE_ERROR:
|
||||||
|
invoke_id = apdu[1];
|
||||||
|
service_choice = apdu[2];
|
||||||
|
len = 3;
|
||||||
|
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
|
||||||
|
/* FIXME: we could validate that the tag is enumerated... */
|
||||||
|
len += decode_enumerated(&apdu[len],len_value, &error_class);
|
||||||
|
len += decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
|
||||||
|
/* FIXME: we could validate that the tag is enumerated... */
|
||||||
|
len += decode_enumerated(&apdu[len],len_value, &error_code);
|
||||||
|
if (service_choice < MAX_BACNET_CONFIRMED_SERVICE)
|
||||||
|
{
|
||||||
|
if (Error_Function[service_choice])
|
||||||
|
Error_Function[service_choice](
|
||||||
|
src,
|
||||||
|
invoke_id,
|
||||||
|
error_class,
|
||||||
|
error_code);
|
||||||
|
}
|
||||||
|
tsm_free_invoke_id(invoke_id);
|
||||||
|
break;
|
||||||
case PDU_TYPE_REJECT:
|
case PDU_TYPE_REJECT:
|
||||||
|
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:
|
case PDU_TYPE_ABORT:
|
||||||
invoke_id = apdu[1];
|
invoke_id = apdu[1];
|
||||||
/* FIXME: what about a way to let a client know? */
|
reason = apdu[2];
|
||||||
|
if (Abort_Function)
|
||||||
|
Abort_Function(
|
||||||
|
src,
|
||||||
|
invoke_id,
|
||||||
|
reason);
|
||||||
tsm_free_invoke_id(invoke_id);
|
tsm_free_invoke_id(invoke_id);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -109,6 +109,25 @@ typedef void (*confirmed_ack_function)(
|
|||||||
BACNET_ADDRESS *src,
|
BACNET_ADDRESS *src,
|
||||||
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data);
|
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data);
|
||||||
|
|
||||||
|
// generic error reply function
|
||||||
|
typedef void (*error_function)(
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
BACNET_ERROR_CLASS error_class,
|
||||||
|
BACNET_ERROR_CODE error_code);
|
||||||
|
|
||||||
|
// generic abort reply function
|
||||||
|
typedef void (*abort_function)(
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
uint8_t abort_reason);
|
||||||
|
|
||||||
|
// generic reject reply function
|
||||||
|
typedef void (*reject_function)(
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
uint8_t reject_reason);
|
||||||
|
|
||||||
void apdu_set_confirmed_ack_handler(
|
void apdu_set_confirmed_ack_handler(
|
||||||
BACNET_CONFIRMED_SERVICE service_choice,
|
BACNET_CONFIRMED_SERVICE service_choice,
|
||||||
confirmed_ack_function pFunction);
|
confirmed_ack_function pFunction);
|
||||||
@@ -129,6 +148,16 @@ void apdu_set_unconfirmed_handler(
|
|||||||
BACNET_UNCONFIRMED_SERVICE service_choice,
|
BACNET_UNCONFIRMED_SERVICE service_choice,
|
||||||
unconfirmed_function pFunction);
|
unconfirmed_function pFunction);
|
||||||
|
|
||||||
|
void apdu_set_error_handler(
|
||||||
|
BACNET_CONFIRMED_SERVICE service_choice,
|
||||||
|
error_function pFunction);
|
||||||
|
|
||||||
|
void apdu_set_abort_handler(
|
||||||
|
abort_function pFunction);
|
||||||
|
|
||||||
|
void apdu_set_reject_handler(
|
||||||
|
reject_function pFunction);
|
||||||
|
|
||||||
uint16_t apdu_decode_confirmed_service_request(
|
uint16_t apdu_decode_confirmed_service_request(
|
||||||
uint8_t *apdu, // APDU data
|
uint8_t *apdu, // APDU data
|
||||||
uint16_t apdu_len,
|
uint16_t apdu_len,
|
||||||
|
|||||||
Reference in New Issue
Block a user