Bugfix/secure alarm ack codec (#647)
* Secured BACnetAcknowledgeAlarmInfo codec and improved unit testing code coverage.
This commit is contained in:
+150
-114
@@ -1,36 +1,11 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2009 John Minack
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
this file and link it with other works to produce a work based
|
||||
on this file, this file does not by itself cause the resulting
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
/**
|
||||
* @file
|
||||
* @brief BACnetAcknowledgeAlarmInfo service encode and decode
|
||||
* @author John Minack <minack@users.sourceforge.net>
|
||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||
* @date 2009
|
||||
* @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "bacnet/alarm_ack.h"
|
||||
@@ -38,13 +13,11 @@
|
||||
/** @file alarm_ack.c Handles Event Notifications (ACKs) */
|
||||
|
||||
/**
|
||||
* @brief Creates an Unconfirmed Event Notification APDU
|
||||
*
|
||||
* @param apdu Transmission buffer
|
||||
* @brief Creates a Confirmed BACnetAcknowledgeAlarmInfo service request.
|
||||
* @param apdu application data buffer, or NULL for length
|
||||
* @param invoke_id Invoked ID
|
||||
* @param data Alarm acknowledge data that will be copied into the payload.
|
||||
*
|
||||
* @return Length of the APDU
|
||||
* @param data Pointer to the service data used for encoding values
|
||||
* @return number of bytes encoded
|
||||
*/
|
||||
int alarm_ack_encode_apdu(
|
||||
uint8_t *apdu, uint8_t invoke_id, BACNET_ALARM_ACK_DATA *data)
|
||||
@@ -57,119 +30,182 @@ int alarm_ack_encode_apdu(
|
||||
apdu[1] = encode_max_segs_max_apdu(0, MAX_APDU);
|
||||
apdu[2] = invoke_id;
|
||||
apdu[3] = SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM; /* service choice */
|
||||
apdu_len = 4;
|
||||
|
||||
len = alarm_ack_encode_service_request(&apdu[apdu_len], data);
|
||||
apdu_len += len;
|
||||
}
|
||||
len = 4;
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = alarm_ack_encode_service_request(apdu, data);
|
||||
apdu_len += len;
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encodes the service data part of Event Notification.
|
||||
* @brief Encodes a BACnetAcknowledgeAlarmInfo service request
|
||||
*
|
||||
* @param apdu Receive buffer
|
||||
* @param data Alarm acknowledge data that will be filled in
|
||||
* with the data from the payload.
|
||||
*
|
||||
* @return Total length of the apdu
|
||||
* BACnetAcknowledgeAlarmInfo ::= SEQUENCE {
|
||||
* event-state-acknowledged [0] BACnetEventState,
|
||||
* timestamp [1] BACnetTimeStamp
|
||||
* }
|
||||
*
|
||||
* @param apdu application data buffer, or NULL for length
|
||||
* @param data Pointer to the service data used for encoding values
|
||||
* @return number of bytes encoded
|
||||
*/
|
||||
int alarm_ack_encode_service_request(uint8_t *apdu, BACNET_ALARM_ACK_DATA *data)
|
||||
{
|
||||
int len = 0; /* length of each encoding */
|
||||
int apdu_len = 0; /* total length of the apdu, return value */
|
||||
|
||||
if (apdu) {
|
||||
len = encode_context_unsigned(
|
||||
&apdu[apdu_len], 0, data->ackProcessIdentifier);
|
||||
apdu_len += len;
|
||||
|
||||
len = encode_context_object_id(&apdu[apdu_len], 1,
|
||||
data->eventObjectIdentifier.type,
|
||||
data->eventObjectIdentifier.instance);
|
||||
apdu_len += len;
|
||||
|
||||
len = encode_context_enumerated(
|
||||
&apdu[apdu_len], 2, data->eventStateAcked);
|
||||
apdu_len += len;
|
||||
|
||||
len = bacapp_encode_context_timestamp(
|
||||
&apdu[apdu_len], 3, &data->eventTimeStamp);
|
||||
apdu_len += len;
|
||||
|
||||
len = encode_context_character_string(
|
||||
&apdu[apdu_len], 4, &data->ackSource);
|
||||
apdu_len += len;
|
||||
|
||||
len = bacapp_encode_context_timestamp(
|
||||
&apdu[apdu_len], 5, &data->ackTimeStamp);
|
||||
apdu_len += len;
|
||||
if (!data) {
|
||||
return 0;
|
||||
}
|
||||
len = encode_context_unsigned(apdu, 0, data->ackProcessIdentifier);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = encode_context_object_id(apdu, 1, data->eventObjectIdentifier.type,
|
||||
data->eventObjectIdentifier.instance);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = encode_context_enumerated(apdu, 2, data->eventStateAcked);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = bacapp_encode_context_timestamp(apdu, 3, &data->eventTimeStamp);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = encode_context_character_string(apdu, 4, &data->ackSource);
|
||||
apdu_len += len;
|
||||
if (apdu) {
|
||||
apdu += len;
|
||||
}
|
||||
len = bacapp_encode_context_timestamp(apdu, 5, &data->ackTimeStamp);
|
||||
apdu_len += len;
|
||||
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decodes the service data part of Event Notification.
|
||||
* @brief Encode the BACnetAcknowledgeAlarmInfo-Request service
|
||||
* @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 bacnet_acknowledge_alarm_info_request_encode(
|
||||
uint8_t *apdu,
|
||||
size_t apdu_size,
|
||||
BACNET_ALARM_ACK_DATA *data)
|
||||
{
|
||||
size_t apdu_len = 0; /* total length of the apdu, return value */
|
||||
|
||||
apdu_len = alarm_ack_encode_service_request(NULL, data);
|
||||
if (apdu_len > apdu_size) {
|
||||
apdu_len = 0;
|
||||
} else {
|
||||
apdu_len = alarm_ack_encode_service_request(apdu, data);
|
||||
}
|
||||
|
||||
return apdu_len;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decodes the service data part of BACnetAcknowledgeAlarmInfo
|
||||
*
|
||||
* @param apdu Receive buffer
|
||||
* @param apdu_len Bytes valid in the buffer.
|
||||
* @param data Alarm acknowledge data that will be filled.
|
||||
*
|
||||
* @return Total length of the apdu
|
||||
* @param apdu application date buffer
|
||||
* @param apdu_size number of bytes application date buffer
|
||||
* @param data BACnetAcknowledgeAlarmInfo to hold the decoded data
|
||||
* @return number of bytes decoded, or BACNET_STATUS_ERROR on error.
|
||||
*/
|
||||
int alarm_ack_decode_service_request(
|
||||
uint8_t *apdu, unsigned apdu_len, BACNET_ALARM_ACK_DATA *data)
|
||||
uint8_t *apdu, unsigned apdu_size, BACNET_ALARM_ACK_DATA *data)
|
||||
{
|
||||
int len = 0;
|
||||
int section_len = 0;
|
||||
int apdu_len = 0;
|
||||
uint32_t enum_value = 0;
|
||||
BACNET_UNSIGNED_INTEGER unsigned_value = 0;
|
||||
BACNET_OBJECT_TYPE object_type = 0;
|
||||
uint32_t instance = 0;
|
||||
BACNET_TIMESTAMP *timestamp_value = NULL;
|
||||
BACNET_CHARACTER_STRING *cs_value = NULL;
|
||||
|
||||
(void)apdu_len;
|
||||
section_len = decode_context_unsigned(&apdu[len], 0, &unsigned_value);
|
||||
if (section_len == BACNET_STATUS_ERROR) {
|
||||
if (!apdu) {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
data->ackProcessIdentifier = (uint32_t)unsigned_value;
|
||||
len += section_len;
|
||||
|
||||
section_len = decode_context_object_id(&apdu[len], 1,
|
||||
&data->eventObjectIdentifier.type,
|
||||
&data->eventObjectIdentifier.instance);
|
||||
if (section_len == BACNET_STATUS_ERROR) {
|
||||
if (apdu_size == 0) {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
len += section_len;
|
||||
|
||||
section_len = decode_context_enumerated(&apdu[len], 2, &enum_value);
|
||||
if (section_len == BACNET_STATUS_ERROR) {
|
||||
len = bacnet_unsigned_context_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, 0, &unsigned_value);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
data->eventStateAcked = (BACNET_EVENT_STATE)enum_value;
|
||||
len += section_len;
|
||||
|
||||
section_len =
|
||||
bacapp_decode_context_timestamp(&apdu[len], 3, &data->eventTimeStamp);
|
||||
if (section_len == BACNET_STATUS_ERROR) {
|
||||
if (data) {
|
||||
data->ackProcessIdentifier = (uint32_t)unsigned_value;
|
||||
}
|
||||
len = bacnet_object_id_context_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, 1, &object_type, &instance);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
len += section_len;
|
||||
|
||||
section_len =
|
||||
decode_context_character_string(&apdu[len], 4, &data->ackSource);
|
||||
if (section_len == BACNET_STATUS_ERROR) {
|
||||
if (data) {
|
||||
data->eventObjectIdentifier.type = object_type;
|
||||
data->eventObjectIdentifier.instance = instance;
|
||||
}
|
||||
len = bacnet_enumerated_context_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, 2, &enum_value);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
len += section_len;
|
||||
|
||||
section_len =
|
||||
bacapp_decode_context_timestamp(&apdu[len], 5, &data->ackTimeStamp);
|
||||
if (section_len == BACNET_STATUS_ERROR) {
|
||||
if (data) {
|
||||
data->eventStateAcked = (BACNET_EVENT_STATE)enum_value;
|
||||
}
|
||||
if (data) {
|
||||
timestamp_value = &data->eventTimeStamp;
|
||||
}
|
||||
len = bacnet_timestamp_context_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, 3, timestamp_value);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
if (data) {
|
||||
cs_value = &data->ackSource;
|
||||
}
|
||||
len = bacnet_character_string_context_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, 4, cs_value);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
if (data) {
|
||||
timestamp_value = &data->ackTimeStamp;
|
||||
}
|
||||
len = bacnet_timestamp_context_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, 5, timestamp_value);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
} else {
|
||||
return BACNET_STATUS_ERROR;
|
||||
}
|
||||
len += section_len;
|
||||
|
||||
return len;
|
||||
return apdu_len;
|
||||
}
|
||||
|
||||
+17
-41
@@ -1,28 +1,13 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 John Minack
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*********************************************************************/
|
||||
#ifndef ALARM_ACK_H_
|
||||
#define ALARM_ACK_H_
|
||||
/**
|
||||
* @file
|
||||
* @brief BACnetAcknowledgeAlarmInfo service encode and decode
|
||||
* @author John Minack <minack@users.sourceforge.net>
|
||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||
* @date 2009
|
||||
* @copyright SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#ifndef BACNET_ALARM_ACK_H
|
||||
#define BACNET_ALARM_ACK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -53,32 +38,23 @@ typedef int (
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/***************************************************
|
||||
**
|
||||
** Creates a Alarm Acknowledge APDU
|
||||
**
|
||||
****************************************************/
|
||||
BACNET_STACK_EXPORT
|
||||
int alarm_ack_encode_apdu(
|
||||
uint8_t * apdu,
|
||||
uint8_t invoke_id,
|
||||
BACNET_ALARM_ACK_DATA * data);
|
||||
|
||||
/***************************************************
|
||||
**
|
||||
** Encodes the service data part of Alarm Acknowledge
|
||||
**
|
||||
****************************************************/
|
||||
BACNET_STACK_EXPORT
|
||||
int alarm_ack_encode_service_request(
|
||||
uint8_t * apdu,
|
||||
BACNET_ALARM_ACK_DATA * data);
|
||||
|
||||
/***************************************************
|
||||
**
|
||||
** Decodes the service data part of Alarm Acknowledge
|
||||
**
|
||||
****************************************************/
|
||||
BACNET_STACK_EXPORT
|
||||
size_t bacnet_acknowledge_alarm_info_request_encode(
|
||||
uint8_t *apdu,
|
||||
size_t apdu_size,
|
||||
BACNET_ALARM_ACK_DATA *data);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
int alarm_ack_decode_service_request(
|
||||
uint8_t * apdu,
|
||||
@@ -88,4 +64,4 @@ extern "C" {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* ALARM_ACK_H_ */
|
||||
#endif
|
||||
|
||||
+8
-33
@@ -1,36 +1,11 @@
|
||||
/*####COPYRIGHTBEGIN####
|
||||
-------------------------------------------
|
||||
Copyright (C) 2008 John Minack
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
The Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
As a special exception, if other files instantiate templates or
|
||||
use macros or inline functions from this file, or you compile
|
||||
this file and link it with other works to produce a work based
|
||||
on this file, this file does not by itself cause the resulting
|
||||
work to be covered by the GNU General Public License. However
|
||||
the source code for this file must still be made available in
|
||||
accordance with section (3) of the GNU General Public License.
|
||||
|
||||
This exception does not invalidate any other reasons why a work
|
||||
based on this file might be covered by the GNU General Public
|
||||
License.
|
||||
-------------------------------------------
|
||||
####COPYRIGHTEND####*/
|
||||
/**
|
||||
* @file
|
||||
* @brief BACnetTimeStamp service encode and decode
|
||||
* @author John Minack <minack@users.sourceforge.net>
|
||||
* @author Steve Karg <skarg@users.sourceforge.net>
|
||||
* @date 2008
|
||||
* @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
Reference in New Issue
Block a user