Add segmentation support functions (#1218)
* Added segmentation support functions and example changes, but no support for segmentation in the TSM or APDU handlers.
This commit is contained in:
@@ -23,6 +23,7 @@ Frédéric Chaxel <fchaxel@users.sourceforge.net> <fchaxel@1e814d3a-8a88-4260-be
|
|||||||
Miroslav Novotny <koby3101@users.sourceforge.net> <koby3101@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
Miroslav Novotny <koby3101@users.sourceforge.net> <koby3101@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
||||||
Boris Weitsch <bow2@users.sourceforge.net> <bow2@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
Boris Weitsch <bow2@users.sourceforge.net> <bow2@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
||||||
Vasyl Tkhir <vasyl-tkhir@users.sourceforge.net> <vasyl-tkhir@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
Vasyl Tkhir <vasyl-tkhir@users.sourceforge.net> <vasyl-tkhir@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
||||||
|
Julien Bennet <antibarbie@users.sourceforge.net> <antibarbie@1e814d3a-8a88-4260-be86-c0dc25669c1e>
|
||||||
|
|
||||||
# github mappings
|
# github mappings
|
||||||
Greg Shue <greg.shue@outlook.com> <32416235+shuegr-personal@users.noreply.github.com>
|
Greg Shue <greg.shue@outlook.com> <32416235+shuegr-personal@users.noreply.github.com>
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ The git repositories are hosted at the following sites:
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
* Added segmentation support functions and example changes, but
|
||||||
|
no support for segmentation in the TSM or APDU handlers. (#1218)
|
||||||
* Added channel and timer object write-property observers in blinkt app
|
* Added channel and timer object write-property observers in blinkt app
|
||||||
to monitor internal writes. Added vacancy timer command line argument
|
to monitor internal writes. Added vacancy timer command line argument
|
||||||
for testing initial timer object vacancy time for lights channel. (#1212)
|
for testing initial timer object vacancy time for lights channel. (#1212)
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ option(
|
|||||||
"compile with secure-connect support"
|
"compile with secure-connect support"
|
||||||
OFF)
|
OFF)
|
||||||
|
|
||||||
|
option(
|
||||||
|
BACNET_SEGMENTATION_ENABLED
|
||||||
|
"enable segmentation"
|
||||||
|
ON)
|
||||||
|
|
||||||
if(NOT (BACDL_ETHERNET OR
|
if(NOT (BACDL_ETHERNET OR
|
||||||
BACDL_MSTP OR
|
BACDL_MSTP OR
|
||||||
BACDL_ARCNET OR
|
BACDL_ARCNET OR
|
||||||
@@ -683,6 +688,8 @@ add_library(${PROJECT_NAME}
|
|||||||
src/bacnet/rp.h
|
src/bacnet/rp.h
|
||||||
src/bacnet/rpm.c
|
src/bacnet/rpm.c
|
||||||
src/bacnet/rpm.h
|
src/bacnet/rpm.h
|
||||||
|
$<$<BOOL:${BACNET_SEGMENTATION_ENABLED}>:src/bacnet/segmentack.c>
|
||||||
|
$<$<BOOL:${BACNET_SEGMENTATION_ENABLED}>:src/bacnet/segmentack.h>
|
||||||
src/bacnet/shed_level.c
|
src/bacnet/shed_level.c
|
||||||
src/bacnet/shed_level.h
|
src/bacnet/shed_level.h
|
||||||
src/bacnet/timer_value.c
|
src/bacnet/timer_value.c
|
||||||
@@ -736,6 +743,7 @@ target_compile_definitions(
|
|||||||
$<$<BOOL:${BACDL_NONE}>:BACDL_NONE>
|
$<$<BOOL:${BACDL_NONE}>:BACDL_NONE>
|
||||||
$<$<BOOL:${BACNET_PROPERTY_LISTS}>:BACNET_PROPERTY_LISTS=1>
|
$<$<BOOL:${BACNET_PROPERTY_LISTS}>:BACNET_PROPERTY_LISTS=1>
|
||||||
$<$<BOOL:${BAC_ROUTING}>:BAC_ROUTING>
|
$<$<BOOL:${BAC_ROUTING}>:BAC_ROUTING>
|
||||||
|
$<$<BOOL:${BACNET_SEGMENTATION_ENABLED}>:BACNET_SEGMENTATION_ENABLED=1>
|
||||||
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:BACNET_STACK_STATIC_DEFINE>
|
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:BACNET_STACK_STATIC_DEFINE>
|
||||||
PRIVATE
|
PRIVATE
|
||||||
PRINT_ENABLED=1)
|
PRINT_ENABLED=1)
|
||||||
@@ -1302,3 +1310,4 @@ message(STATUS "BACNET: BACDL_ARCNET:...................\"${BACDL_ARCNET}\"")
|
|||||||
message(STATUS "BACNET: BACDL_MSTP:.....................\"${BACDL_MSTP}\"")
|
message(STATUS "BACNET: BACDL_MSTP:.....................\"${BACDL_MSTP}\"")
|
||||||
message(STATUS "BACNET: BACDL_ZIGBEE:...................\"${BACDL_ZIGBEE}\"")
|
message(STATUS "BACNET: BACDL_ZIGBEE:...................\"${BACDL_ZIGBEE}\"")
|
||||||
message(STATUS "BACNET: BACDL_ETHERNET:.................\"${BACDL_ETHERNET}\"")
|
message(STATUS "BACNET: BACDL_ETHERNET:.................\"${BACDL_ETHERNET}\"")
|
||||||
|
message(STATUS "BACNET: BACNET_SEGMENTATION_ENABLED:....\"${BACNET_SEGMENTATION_ENABLED}\"")
|
||||||
|
|||||||
@@ -224,6 +224,10 @@ server-discover:
|
|||||||
server-mini:
|
server-mini:
|
||||||
$(MAKE) LEGACY=true NOTIFY=false -s -C apps $@
|
$(MAKE) LEGACY=true NOTIFY=false -s -C apps $@
|
||||||
|
|
||||||
|
.PHONY: server-segmentation
|
||||||
|
server-segmentation:
|
||||||
|
$(MAKE) LEGACY=true SEGMENT=true -s -C apps server
|
||||||
|
|
||||||
.PHONY: sc-hub
|
.PHONY: sc-hub
|
||||||
sc-hub:
|
sc-hub:
|
||||||
$(MAKE) LEGACY=true BACDL=bsc -s -C apps $@
|
$(MAKE) LEGACY=true BACDL=bsc -s -C apps $@
|
||||||
|
|||||||
@@ -223,6 +223,11 @@ ifeq (${LEGACY},true)
|
|||||||
BACNET_DEFINES += -DBACNET_STACK_DEPRECATED_DISABLE
|
BACNET_DEFINES += -DBACNET_STACK_DEPRECATED_DISABLE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq (${SEGMENT},true)
|
||||||
|
# enable segmentation support
|
||||||
|
BACNET_DEFINES += -DBACNET_SEGMENTATION_ENABLED=1
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq (${NOTIFY},false)
|
ifeq (${NOTIFY},false)
|
||||||
# disable intrinsic reporting
|
# disable intrinsic reporting
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
|
||||||
|
{
|
||||||
|
return SEGMENTATION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
bool Device_Valid_Object_Instance_Number(uint32_t object_id)
|
||||||
{
|
{
|
||||||
/* BACnet allows for a wildcard instance number */
|
/* BACnet allows for a wildcard instance number */
|
||||||
|
|||||||
@@ -212,8 +212,24 @@ typedef struct BACnet_Object_Id {
|
|||||||
uint32_t instance;
|
uint32_t instance;
|
||||||
} BACNET_OBJECT_ID;
|
} BACNET_OBJECT_ID;
|
||||||
|
|
||||||
|
#if !defined(BACNET_MAX_SEGMENTS_ACCEPTED)
|
||||||
|
#if BACNET_SEGMENTATION_ENABLED
|
||||||
|
/* note: BACNET_MAX_SEGMENTS_ACCEPTED can be 1..255.
|
||||||
|
ASDU in this library is usually sized for 16-bit at 65535 max.
|
||||||
|
Therefore, the default here is limited to avoid overflow warnings. */
|
||||||
|
#define BACNET_MAX_SEGMENTS_ACCEPTED 32
|
||||||
|
#else
|
||||||
|
#define BACNET_MAX_SEGMENTS_ACCEPTED 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if !defined(MAX_APDU)
|
||||||
|
#define MAX_APDU 1476
|
||||||
|
#endif
|
||||||
#define MAX_NPDU (1 + 1 + 2 + 1 + MAX_MAC_LEN + 2 + 1 + MAX_MAC_LEN + 1 + 1 + 2)
|
#define MAX_NPDU (1 + 1 + 2 + 1 + MAX_MAC_LEN + 2 + 1 + MAX_MAC_LEN + 1 + 1 + 2)
|
||||||
#define MAX_PDU (MAX_APDU + MAX_NPDU)
|
#define MAX_PDU (MAX_APDU + MAX_NPDU)
|
||||||
|
/* Application Service Data Unit (ASDU) that has not yet been segmented
|
||||||
|
into a protocol data unit (PDU) by the lower layer. */
|
||||||
|
#define MAX_ASDU ((MAX_APDU * BACNET_MAX_SEGMENTS_ACCEPTED) + MAX_NPDU)
|
||||||
|
|
||||||
#define BACNET_ID_VALUE(bacnet_object_instance, bacnet_object_type) \
|
#define BACNET_ID_VALUE(bacnet_object_instance, bacnet_object_type) \
|
||||||
((((bacnet_object_type) & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS) | \
|
((((bacnet_object_type) & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS) | \
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ static struct Address_Cache_Entry {
|
|||||||
uint8_t Flags;
|
uint8_t Flags;
|
||||||
uint32_t device_id;
|
uint32_t device_id;
|
||||||
unsigned max_apdu;
|
unsigned max_apdu;
|
||||||
|
#if BACNET_SEGMENTATION_ENABLED
|
||||||
|
uint8_t segmentation;
|
||||||
|
uint16_t maxsegments;
|
||||||
|
#endif
|
||||||
BACNET_ADDRESS address;
|
BACNET_ADDRESS address;
|
||||||
uint32_t TimeToLive;
|
uint32_t TimeToLive;
|
||||||
} Address_Cache[MAX_ADDRESS_CACHE];
|
} Address_Cache[MAX_ADDRESS_CACHE];
|
||||||
@@ -346,9 +350,16 @@ void address_set_device_TTL(
|
|||||||
* @param device_id Device-Id
|
* @param device_id Device-Id
|
||||||
* @param max_apdu Pointer to a variable, taking the maximum APDU size.
|
* @param max_apdu Pointer to a variable, taking the maximum APDU size.
|
||||||
* @param src Pointer to address structure for return.
|
* @param src Pointer to address structure for return.
|
||||||
|
* @param segmentation Pointer to a variable, taking the BACNET_SEGMENTATION
|
||||||
|
* flag.
|
||||||
|
* @param maxsegments Pointer to a variable, taking the maximum segments.
|
||||||
*/
|
*/
|
||||||
bool address_get_by_device(
|
bool address_segment_get_by_device(
|
||||||
uint32_t device_id, unsigned *max_apdu, BACNET_ADDRESS *src)
|
uint32_t device_id,
|
||||||
|
unsigned *max_apdu,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
|
uint8_t *segmentation,
|
||||||
|
uint16_t *maxsegments)
|
||||||
{
|
{
|
||||||
struct Address_Cache_Entry *pMatch;
|
struct Address_Cache_Entry *pMatch;
|
||||||
bool found = false; /* return value */
|
bool found = false; /* return value */
|
||||||
@@ -364,6 +375,20 @@ bool address_get_by_device(
|
|||||||
if (max_apdu) {
|
if (max_apdu) {
|
||||||
*max_apdu = pMatch->max_apdu;
|
*max_apdu = pMatch->max_apdu;
|
||||||
}
|
}
|
||||||
|
if (segmentation) {
|
||||||
|
#if BACNET_SEGMENTATION_ENABLED
|
||||||
|
*segmentation = pMatch->segmentation;
|
||||||
|
#else
|
||||||
|
*segmentation = SEGMENTATION_NONE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (maxsegments) {
|
||||||
|
#if BACNET_SEGMENTATION_ENABLED
|
||||||
|
*maxsegments = pMatch->maxsegments;
|
||||||
|
#else
|
||||||
|
*maxsegments = 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
/* Prove we found it */
|
/* Prove we found it */
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
@@ -375,6 +400,18 @@ bool address_get_by_device(
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the cached address for the given device-id
|
||||||
|
* @param device_id Device-Id
|
||||||
|
* @param max_apdu Pointer to a variable, taking the maximum APDU size.
|
||||||
|
* @param src Pointer to address structure for return.
|
||||||
|
*/
|
||||||
|
bool address_get_by_device(
|
||||||
|
uint32_t device_id, unsigned *max_apdu, BACNET_ADDRESS *src)
|
||||||
|
{
|
||||||
|
return address_segment_get_by_device(device_id, max_apdu, src, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a device id from a given MAC address.
|
* Find a device id from a given MAC address.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ BACNET_STACK_EXPORT
|
|||||||
bool address_get_by_device(
|
bool address_get_by_device(
|
||||||
uint32_t device_id, unsigned *max_apdu, BACNET_ADDRESS *src);
|
uint32_t device_id, unsigned *max_apdu, BACNET_ADDRESS *src);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool address_segment_get_by_device(
|
||||||
|
uint32_t device_id,
|
||||||
|
unsigned *max_apdu,
|
||||||
|
BACNET_ADDRESS *src,
|
||||||
|
uint8_t *segmentation,
|
||||||
|
uint16_t *maxsegments);
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
bool address_get_by_index(
|
bool address_get_by_index(
|
||||||
unsigned index,
|
unsigned index,
|
||||||
|
|||||||
@@ -1333,7 +1333,11 @@ uint8_t Device_Protocol_Revision(void)
|
|||||||
|
|
||||||
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
|
BACNET_SEGMENTATION Device_Segmentation_Supported(void)
|
||||||
{
|
{
|
||||||
|
#if BACNET_SEGMENTATION_ENABLED
|
||||||
|
return SEGMENTATION_BOTH;
|
||||||
|
#else
|
||||||
return SEGMENTATION_NONE;
|
return SEGMENTATION_NONE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1804,8 +1808,12 @@ int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
|
|||||||
rpdata->object_instance, rpdata->array_index,
|
rpdata->object_instance, rpdata->array_index,
|
||||||
Device_Object_List_Element_Encode, count, apdu, apdu_max);
|
Device_Object_List_Element_Encode, count, apdu, apdu_max);
|
||||||
if (apdu_len == BACNET_STATUS_ABORT) {
|
if (apdu_len == BACNET_STATUS_ABORT) {
|
||||||
|
#if BACNET_SEGMENTATION_ENABLED
|
||||||
|
rpdata->error_code = ERROR_CODE_ABORT_BUFFER_OVERFLOW;
|
||||||
|
#else
|
||||||
rpdata->error_code =
|
rpdata->error_code =
|
||||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||||
|
#endif
|
||||||
} else if (apdu_len == BACNET_STATUS_ERROR) {
|
} else if (apdu_len == BACNET_STATUS_ERROR) {
|
||||||
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
rpdata->error_class = ERROR_CLASS_PROPERTY;
|
||||||
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ int iam_encode_pdu(
|
|||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
len = iam_encode_apdu(
|
len = iam_encode_apdu(
|
||||||
&buffer[pdu_len], Device_Object_Instance_Number(), MAX_APDU,
|
&buffer[pdu_len], Device_Object_Instance_Number(), MAX_APDU,
|
||||||
SEGMENTATION_NONE, Device_Vendor_Identifier());
|
Device_Segmentation_Supported(), Device_Vendor_Identifier());
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
|
|
||||||
return pdu_len;
|
return pdu_len;
|
||||||
@@ -158,7 +158,7 @@ int iam_unicast_encode_pdu(
|
|||||||
/* encode the APDU portion of the packet */
|
/* encode the APDU portion of the packet */
|
||||||
apdu_len = iam_encode_apdu(
|
apdu_len = iam_encode_apdu(
|
||||||
&buffer[npdu_len], Device_Object_Instance_Number(), MAX_APDU,
|
&buffer[npdu_len], Device_Object_Instance_Number(), MAX_APDU,
|
||||||
SEGMENTATION_NONE, Device_Vendor_Identifier());
|
Device_Segmentation_Supported(), Device_Vendor_Identifier());
|
||||||
pdu_len = npdu_len + apdu_len;
|
pdu_len = npdu_len + apdu_len;
|
||||||
|
|
||||||
return pdu_len;
|
return pdu_len;
|
||||||
|
|||||||
@@ -171,6 +171,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Enable or disable segmentation support in the library */
|
||||||
|
#ifndef BACNET_SEGMENTATION_ENABLED
|
||||||
|
#define BACNET_SEGMENTATION_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* for confirmed messages, this is the number of transactions */
|
/* for confirmed messages, this is the number of transactions */
|
||||||
/* that we hold in a queue waiting for timeout. */
|
/* that we hold in a queue waiting for timeout. */
|
||||||
/* Configure to zero if you don't want any confirmed messages */
|
/* Configure to zero if you don't want any confirmed messages */
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Segment Acknowledgment (SegmentAck) PDU encode and decode functions
|
||||||
|
* @author Julien Bennet <antibarbie@users.sourceforge.net>
|
||||||
|
* @date 2010
|
||||||
|
* @copyright SPDX-License-Identifier: GPL-2.0-or-later WITH GCC-exception-2.0
|
||||||
|
*/
|
||||||
|
#include "bacnet/segmentack.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Method to encode the segment ack .
|
||||||
|
* @param apdu[in] Pointer to the buffer for encoding.
|
||||||
|
* @param negativeack[in] Acknowledgment for the segment.
|
||||||
|
* @param server[in] Set to True if the acknowledgment is from the server, else
|
||||||
|
* false.
|
||||||
|
* @param invoke_id[in] Invoke Id
|
||||||
|
* @param sequence_number[in] Sequence number of the segment to be acknowledged
|
||||||
|
* @param actual_window_size[in] Actual window size.
|
||||||
|
* @return Length of encoded data or zero on error.
|
||||||
|
*/
|
||||||
|
int segmentack_encode_apdu(
|
||||||
|
uint8_t *apdu,
|
||||||
|
bool negativeack,
|
||||||
|
bool server,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
uint8_t sequence_number,
|
||||||
|
uint8_t actual_window_size)
|
||||||
|
{
|
||||||
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
uint8_t server_code = server ? 0x01 : 0x00;
|
||||||
|
uint8_t nak_code = negativeack ? 0x02 : 0x00;
|
||||||
|
|
||||||
|
if (apdu) {
|
||||||
|
apdu[0] = PDU_TYPE_SEGMENT_ACK | server_code | nak_code;
|
||||||
|
apdu[1] = invoke_id;
|
||||||
|
apdu[2] = sequence_number;
|
||||||
|
apdu[3] = actual_window_size;
|
||||||
|
apdu_len = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return apdu_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Method to decode the segment ack service request
|
||||||
|
* @param apdu[in] The apdu portion of the ACK reply.
|
||||||
|
* @param apdu_len[in] The total length of the apdu.
|
||||||
|
* @param invoke_id[out] Invoke Id of the request.
|
||||||
|
* @param sequence_number[out] Sequence number of the segment received.
|
||||||
|
* @param actual_window_size[out] Actual window size.
|
||||||
|
* @return Length of decoded data or zero on error.
|
||||||
|
*/
|
||||||
|
int segmentack_decode_service_request(
|
||||||
|
uint8_t *apdu,
|
||||||
|
unsigned apdu_len,
|
||||||
|
uint8_t *invoke_id,
|
||||||
|
uint8_t *sequence_number,
|
||||||
|
uint8_t *actual_window_size)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int apdu_header_size = 3;
|
||||||
|
|
||||||
|
if (apdu_len >= apdu_header_size) {
|
||||||
|
if (invoke_id) {
|
||||||
|
*invoke_id = apdu[0];
|
||||||
|
}
|
||||||
|
if (sequence_number) {
|
||||||
|
*sequence_number = apdu[1];
|
||||||
|
}
|
||||||
|
if (actual_window_size) {
|
||||||
|
*actual_window_size = apdu[2];
|
||||||
|
}
|
||||||
|
/* three bytes successfully decoded: invoke_id, sequence_number,
|
||||||
|
* and actual_window_size */
|
||||||
|
len = apdu_header_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Segment Acknowledgment (SegmentAck) PDU encode and decode functions
|
||||||
|
* @author Julien Bennet <antibarbie@users.sourceforge.net>
|
||||||
|
* @date 2010
|
||||||
|
* @copyright SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
#ifndef BACNET_SEGMENT_ACK_H
|
||||||
|
#define BACNET_SEGMENT_ACK_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
/* BACnet Stack defines - first */
|
||||||
|
#include "bacnet/bacdef.h"
|
||||||
|
#include "bacnet/bacdcode.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int segmentack_encode_apdu(
|
||||||
|
uint8_t *apdu,
|
||||||
|
bool negativeack,
|
||||||
|
bool server,
|
||||||
|
uint8_t invoke_id,
|
||||||
|
uint8_t sequence_number,
|
||||||
|
uint8_t actual_window_size);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
int segmentack_decode_service_request(
|
||||||
|
uint8_t *apdu,
|
||||||
|
unsigned apdu_len,
|
||||||
|
uint8_t *invoke_id,
|
||||||
|
uint8_t *sequence_number,
|
||||||
|
uint8_t *actual_window_size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#endif /* BACNET_SEGMENT_ACK_H */
|
||||||
Reference in New Issue
Block a user