Bugfix/service request refactor size check (#553)
* refactor service requests from service header * add APDU size checking and length feature * add unit tests to check for length when passing NULL buffer --------- Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
+82
-21
@@ -38,37 +38,98 @@
|
||||
|
||||
/** @file lso.c BACnet Life Safety Operation encode/decode */
|
||||
|
||||
/**
|
||||
* @brief Encode APDU for LifeSafetyOperation-Request
|
||||
* @param apdu Pointer to the buffer, or NULL for length
|
||||
* @param data Pointer to the data to encode.
|
||||
* @return number of bytes encoded, or zero on error.
|
||||
*/
|
||||
int life_safety_operation_encode(uint8_t *apdu, BACNET_LSO_DATA *data)
|
||||
{
|
||||
int len = 0; /* length of each encoding */
|
||||
int apdu_len = 0; /* total length of the apdu, return value */
|
||||
|
||||
if (!data) {
|
||||
return 0;
|
||||
}
|
||||
/* tag 0 - requestingProcessId */
|
||||
len = encode_context_unsigned(apdu, 0, data->processId);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
/* tag 1 - requestingSource */
|
||||
len = encode_context_character_string(
|
||||
apdu, 1, &data->requestingSrc);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
/* Operation */
|
||||
len = encode_context_enumerated(apdu, 2, data->operation);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
/* Object ID */
|
||||
if (data->use_target) {
|
||||
len = encode_context_object_id(apdu, 3,
|
||||
data->targetObject.type, data->targetObject.instance);
|
||||
apdu_len += len;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode APDU for LifeSafetyOperation-Request
|
||||
* @param apdu Pointer to the buffer, or NULL for length
|
||||
* @param data Pointer to the data to encode.
|
||||
* @return number of bytes encoded, or zero on error.
|
||||
*/
|
||||
int lso_encode_apdu(uint8_t *apdu, uint8_t invoke_id, BACNET_LSO_DATA *data)
|
||||
{
|
||||
int len = 0; /* length of each encoding */
|
||||
int apdu_len = 0; /* total length of the apdu, return value */
|
||||
|
||||
if (apdu && data) {
|
||||
if (apdu) {
|
||||
apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST;
|
||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||
apdu[2] = invoke_id;
|
||||
apdu[3] = SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION;
|
||||
apdu_len = 4;
|
||||
/* tag 0 - requestingProcessId */
|
||||
len = encode_context_unsigned(&apdu[apdu_len], 0, data->processId);
|
||||
}
|
||||
len = 4;
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = life_safety_operation_encode(apdu, data);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
/* tag 1 - requestingSource */
|
||||
len = encode_context_character_string(
|
||||
&apdu[apdu_len], 1, &data->requestingSrc);
|
||||
apdu_len += len;
|
||||
/*
|
||||
Operation
|
||||
*/
|
||||
len = encode_context_enumerated(&apdu[apdu_len], 2, data->operation);
|
||||
apdu_len += len;
|
||||
/*
|
||||
Object ID
|
||||
*/
|
||||
if (data->use_target) {
|
||||
len = encode_context_object_id(&apdu[apdu_len], 3,
|
||||
data->targetObject.type, data->targetObject.instance);
|
||||
apdu_len += len;
|
||||
}
|
||||
} else {
|
||||
apdu_len = len;
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode the LifeSafetyOperation-Request
|
||||
* @param apdu Pointer to the buffer for encoding into
|
||||
* @param apdu_size number of bytes available in the buffer
|
||||
* @param data Pointer to the service data used for encoding values
|
||||
* @return number of bytes encoded, or zero if unable to encode or too large
|
||||
*/
|
||||
size_t life_safety_operation_request_encode(
|
||||
uint8_t *apdu, size_t apdu_size, BACNET_LSO_DATA *data)
|
||||
{
|
||||
size_t apdu_len = 0;
|
||||
|
||||
apdu_len = life_safety_operation_encode(NULL, data);
|
||||
if (apdu_len > apdu_size) {
|
||||
apdu_len = 0;
|
||||
} else {
|
||||
apdu_len = life_safety_operation_encode(apdu, data);
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
|
||||
Reference in New Issue
Block a user