Refactored the bacnet file object to be storage agnostic with callbacks. (#1056)
This commit is contained in:
@@ -736,10 +736,13 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
|||||||
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/linux)
|
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/linux)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC m)
|
target_link_libraries(${PROJECT_NAME} PUBLIC m)
|
||||||
add_compile_definitions(BACNET_PORT=linux)
|
add_compile_definitions(BACNET_PORT=linux)
|
||||||
|
include_directories(ports/posix)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
ports/linux/bacport.h
|
ports/linux/bacport.h
|
||||||
ports/linux/datetime-init.c
|
ports/linux/datetime-init.c
|
||||||
|
ports/posix/bacfile-posix.c
|
||||||
|
ports/posix/bacfile-posix.h
|
||||||
$<$<BOOL:${BACDL_BIP}>:ports/linux/bip-init.c>
|
$<$<BOOL:${BACDL_BIP}>:ports/linux/bip-init.c>
|
||||||
$<$<BOOL:${BACDL_BIP6}>:ports/linux/bip6.c>
|
$<$<BOOL:${BACDL_BIP6}>:ports/linux/bip6.c>
|
||||||
$<$<BOOL:${BACDL_ZIGBEE}>:ports/linux/bzll-init.c>
|
$<$<BOOL:${BACDL_ZIGBEE}>:ports/linux/bzll-init.c>
|
||||||
@@ -767,8 +770,12 @@ elseif(WIN32)
|
|||||||
$<$<BOOL:${BACDL_BIP} OR BOOL:${BACDL_BIP6}>:ws2_32>
|
$<$<BOOL:${BACDL_BIP} OR BOOL:${BACDL_BIP6}>:ws2_32>
|
||||||
$<$<BOOL:${BACDL_BIP} OR BOOL:${BACDL_BIP6}>:iphlpapi>)
|
$<$<BOOL:${BACDL_BIP} OR BOOL:${BACDL_BIP6}>:iphlpapi>)
|
||||||
|
|
||||||
|
include_directories(ports/posix)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
ports/win32/bacport.h
|
ports/win32/bacport.h
|
||||||
|
ports/posix/bacfile-posix.c
|
||||||
|
ports/posix/bacfile-posix.h
|
||||||
$<$<BOOL:${BACDL_BIP6}>:ports/win32/bip6.c>
|
$<$<BOOL:${BACDL_BIP6}>:ports/win32/bip6.c>
|
||||||
$<$<BOOL:${BACDL_BIP}>:ports/win32/bip-init.c>
|
$<$<BOOL:${BACDL_BIP}>:ports/win32/bip-init.c>
|
||||||
$<$<BOOL:${BACDL_ZIGBEE}>:ports/win32/bzll-init.c>
|
$<$<BOOL:${BACDL_ZIGBEE}>:ports/win32/bzll-init.c>
|
||||||
@@ -815,9 +822,12 @@ elseif(APPLE)
|
|||||||
message(STATUS "BACNET: building for APPLE")
|
message(STATUS "BACNET: building for APPLE")
|
||||||
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/bsd)
|
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/bsd)
|
||||||
add_compile_definitions(BACNET_PORT=bsd)
|
add_compile_definitions(BACNET_PORT=bsd)
|
||||||
|
include_directories(ports/posix)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
ports/bsd/bacport.h
|
ports/bsd/bacport.h
|
||||||
|
ports/posix/bacfile-posix.c
|
||||||
|
ports/posix/bacfile-posix.h
|
||||||
$<$<BOOL:${BACDL_BIP}>:ports/bsd/bip-init.c>
|
$<$<BOOL:${BACDL_BIP}>:ports/bsd/bip-init.c>
|
||||||
$<$<BOOL:${BACDL_ZIGBEE}>:ports/bsd/bzll-init.c>
|
$<$<BOOL:${BACDL_ZIGBEE}>:ports/bsd/bzll-init.c>
|
||||||
$<$<BOOL:${BACDL_BIP6}>:ports/bsd/bip6.c>
|
$<$<BOOL:${BACDL_BIP6}>:ports/bsd/bip6.c>
|
||||||
@@ -856,9 +866,12 @@ elseif(APPLE)
|
|||||||
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||||
message(STATUS "BACNET: building for FreeBSD")
|
message(STATUS "BACNET: building for FreeBSD")
|
||||||
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/bsd)
|
set(BACNET_PORT_DIRECTORY_PATH ${CMAKE_CURRENT_LIST_DIR}/ports/bsd)
|
||||||
|
include_directories(ports/posix)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE
|
target_sources(${PROJECT_NAME} PRIVATE
|
||||||
ports/bsd/bacport.h
|
ports/bsd/bacport.h
|
||||||
|
ports/posix/bacfile-posix.c
|
||||||
|
ports/posix/bacfile-posix.h
|
||||||
$<$<BOOL:${BACDL_BIP}>:ports/bsd/bip-init.c>
|
$<$<BOOL:${BACDL_BIP}>:ports/bsd/bip-init.c>
|
||||||
$<$<BOOL:${BACDL_ZIGBEE}>:ports/bsd/bzll-init.c>
|
$<$<BOOL:${BACDL_ZIGBEE}>:ports/bsd/bzll-init.c>
|
||||||
$<$<BOOL:${BACDL_BIP6}>:ports/bsd/bip6.c>
|
$<$<BOOL:${BACDL_BIP6}>:ports/bsd/bip6.c>
|
||||||
|
|||||||
+2
-1
@@ -138,6 +138,7 @@ endif
|
|||||||
|
|
||||||
# source file locations
|
# source file locations
|
||||||
BACNET_PORT_DIR = $(realpath ../ports/$(BACNET_PORT))
|
BACNET_PORT_DIR = $(realpath ../ports/$(BACNET_PORT))
|
||||||
|
BACNET_POSIX_DIR = $(realpath ../ports/posix)
|
||||||
BACNET_SRC_DIR = $(realpath ../src)
|
BACNET_SRC_DIR = $(realpath ../src)
|
||||||
|
|
||||||
# Compiler flag to set the C Standard level.
|
# Compiler flag to set the C Standard level.
|
||||||
@@ -197,7 +198,7 @@ BACNET_DEFINES += -DBACNET_PROPERTY_LISTS=1
|
|||||||
BACNET_DEFINES += -DBACNET_PROTOCOL_REVISION=24
|
BACNET_DEFINES += -DBACNET_PROTOCOL_REVISION=24
|
||||||
|
|
||||||
# put all the flags together
|
# put all the flags together
|
||||||
INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR)
|
INCLUDES = -I$(BACNET_SRC_DIR) -I$(BACNET_PORT_DIR) -I$(BACNET_POSIX_DIR)
|
||||||
CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES)
|
CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES)
|
||||||
CFLAGS += $(CSTANDARD)
|
CFLAGS += $(CSTANDARD)
|
||||||
ifneq (${BACNET_LIB},)
|
ifneq (${BACNET_LIB},)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ BACNET_LIB_DIR ?= $(realpath .)
|
|||||||
BACNET_LIB_TARGET ?= $(BACNET_LIB_DIR)/lib$(BACNET_LIB_NAME).a
|
BACNET_LIB_TARGET ?= $(BACNET_LIB_DIR)/lib$(BACNET_LIB_NAME).a
|
||||||
BACNET_SRC_DIR ?= $(realpath ../../src)
|
BACNET_SRC_DIR ?= $(realpath ../../src)
|
||||||
BACNET_PORT_DIR ?= $(realpath ../../ports/linux)
|
BACNET_PORT_DIR ?= $(realpath ../../ports/linux)
|
||||||
|
BACNET_POSIX_DIR ?= $(realpath ../../ports/posix)
|
||||||
BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object
|
BACNET_OBJECT_DIR = $(BACNET_SRC_DIR)/bacnet/basic/object
|
||||||
BACNET_DEFINES ?=
|
BACNET_DEFINES ?=
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ CFLAGS += $(WARNINGS) $(DEBUGGING) $(OPTIMIZATION) $(BACNET_DEFINES) $(INCLUDES)
|
|||||||
CFLAGS += -ffunction-sections -fdata-sections
|
CFLAGS += -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
APPS_ENVIRONMENT_SRC = \
|
APPS_ENVIRONMENT_SRC = \
|
||||||
|
$(BACNET_POSIX_DIR)/bacfile-posix.c \
|
||||||
$(BACNET_SRC_DIR)/bacnet/datalink/dlenv.c
|
$(BACNET_SRC_DIR)/bacnet/datalink/dlenv.c
|
||||||
|
|
||||||
PORT_ARCNET_SRC = \
|
PORT_ARCNET_SRC = \
|
||||||
|
|||||||
@@ -0,0 +1,272 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief A POSIX BACnet File Object implementation.
|
||||||
|
* @author Steve Karg
|
||||||
|
* @date 2005
|
||||||
|
* @copyright SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
/* BACnet Stack defines - first */
|
||||||
|
#include "bacnet/bacdef.h"
|
||||||
|
#include "bacnet/basic/object/bacfile.h"
|
||||||
|
|
||||||
|
#ifndef FILE_RECORD_SIZE
|
||||||
|
#define FILE_RECORD_SIZE MAX_OCTET_STRING_BYTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determines the file size for a given file
|
||||||
|
* @param pFile - file handle
|
||||||
|
* @return file size in bytes, or 0 if not found
|
||||||
|
*/
|
||||||
|
static long fsize(FILE *pFile)
|
||||||
|
{
|
||||||
|
long size = 0;
|
||||||
|
long origin = 0;
|
||||||
|
|
||||||
|
if (pFile) {
|
||||||
|
origin = ftell(pFile);
|
||||||
|
fseek(pFile, 0L, SEEK_END);
|
||||||
|
size = ftell(pFile);
|
||||||
|
fseek(pFile, origin, SEEK_SET);
|
||||||
|
}
|
||||||
|
return (size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Determines the file size for a given file
|
||||||
|
* @param pathname - name of the file to get the size for
|
||||||
|
* @return file size in bytes, or 0 if not found
|
||||||
|
*/
|
||||||
|
size_t bacfile_posix_file_size(const char *pathname)
|
||||||
|
{
|
||||||
|
FILE *pFile = NULL;
|
||||||
|
long file_position = 0;
|
||||||
|
size_t file_size = 0;
|
||||||
|
|
||||||
|
if (pathname) {
|
||||||
|
pFile = fopen(pathname, "rb");
|
||||||
|
if (pFile) {
|
||||||
|
file_position = fsize(pFile);
|
||||||
|
if (file_position >= 0) {
|
||||||
|
file_size = (size_t)file_position;
|
||||||
|
}
|
||||||
|
fclose(pFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the file size property value
|
||||||
|
* @param pathname - name of the file to set the size for
|
||||||
|
* @param file_size - value of the file size property
|
||||||
|
* @return true if file size is writable
|
||||||
|
*/
|
||||||
|
bool bacfile_posix_file_size_set(const char *pathname, size_t file_size)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
(void)pathname; /* unused parameter */
|
||||||
|
(void)file_size; /* unused parameter */
|
||||||
|
/* FIXME: add clever POSIX file stuff here */
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads stream data from a file
|
||||||
|
* @param pathname - name of the file to read from
|
||||||
|
* @param fileStartPosition - starting position in the file
|
||||||
|
* @param fileData - data buffer to read into
|
||||||
|
* @param fileDataLen - size of the data buffer
|
||||||
|
* @return number of bytes read, or 0 if not successful
|
||||||
|
*/
|
||||||
|
size_t bacfile_posix_read_stream_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartPosition,
|
||||||
|
uint8_t *fileData,
|
||||||
|
size_t fileDataLen)
|
||||||
|
{
|
||||||
|
FILE *pFile = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
if (pathname) {
|
||||||
|
pFile = fopen(pathname, "rb");
|
||||||
|
if (pFile) {
|
||||||
|
(void)fseek(pFile, fileStartPosition, SEEK_SET);
|
||||||
|
len = fread(fileData, 1, fileDataLen, pFile);
|
||||||
|
fclose(pFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes stream data to a file
|
||||||
|
* @param pathname - name of the file to write to
|
||||||
|
* @param fileStartPosition - starting position in the file
|
||||||
|
* @param fileData - data buffer to write from
|
||||||
|
* @param fileDataLen - size of the data buffer
|
||||||
|
* @return number of bytes written, or 0 if not successful
|
||||||
|
*/
|
||||||
|
size_t bacfile_posix_write_stream_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartPosition,
|
||||||
|
const uint8_t *fileData,
|
||||||
|
size_t fileDataLen)
|
||||||
|
{
|
||||||
|
size_t bytes_written = 0;
|
||||||
|
FILE *pFile = NULL;
|
||||||
|
|
||||||
|
if (pathname) {
|
||||||
|
if (fileStartPosition == 0) {
|
||||||
|
/* open the file as a clean slate when starting at 0 */
|
||||||
|
pFile = fopen(pathname, "wb");
|
||||||
|
} else if (fileStartPosition == -1) {
|
||||||
|
/* If 'File Start Position' parameter has the special
|
||||||
|
value -1, then the write operation shall be treated
|
||||||
|
as an append to the current end of file. */
|
||||||
|
pFile = fopen(pathname, "ab+");
|
||||||
|
} else {
|
||||||
|
/* open for update */
|
||||||
|
pFile = fopen(pathname, "rb+");
|
||||||
|
}
|
||||||
|
if (pFile) {
|
||||||
|
if (fileStartPosition != -1) {
|
||||||
|
(void)fseek(pFile, fileStartPosition, SEEK_SET);
|
||||||
|
}
|
||||||
|
bytes_written = fwrite(fileData, fileDataLen, 1, pFile);
|
||||||
|
fclose(pFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Writes record data to a file
|
||||||
|
* @param pathname - name of the file to write to
|
||||||
|
* @param fileStartRecord - starting record in the file
|
||||||
|
* @param fileIndexRecord - index of the record to read
|
||||||
|
* @param fileData - data buffer to read into
|
||||||
|
* @param fileDataLen - size of the data buffer
|
||||||
|
* @return true if successful, false otherwise
|
||||||
|
*/
|
||||||
|
bool bacfile_posix_write_record_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartRecord,
|
||||||
|
size_t fileIndexRecord,
|
||||||
|
const uint8_t *fileData,
|
||||||
|
size_t fileDataLen)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
FILE *pFile = NULL;
|
||||||
|
uint32_t i = 0;
|
||||||
|
char dummy_data[FILE_RECORD_SIZE];
|
||||||
|
const char *pData = NULL;
|
||||||
|
size_t fileSeekRecord = 0;
|
||||||
|
|
||||||
|
if (pathname) {
|
||||||
|
if (fileStartRecord == 0) {
|
||||||
|
/* open the file as a clean slate when starting at 0 */
|
||||||
|
pFile = fopen(pathname, "wb");
|
||||||
|
fileSeekRecord = fileIndexRecord;
|
||||||
|
} else if (fileStartRecord == -1) {
|
||||||
|
/* If 'File Start Record' parameter has the special
|
||||||
|
value -1, then the write operation shall be treated
|
||||||
|
as an append to the current end of file. */
|
||||||
|
pFile = fopen(pathname, "ab+");
|
||||||
|
fileSeekRecord = fileIndexRecord;
|
||||||
|
} else {
|
||||||
|
/* open for update */
|
||||||
|
pFile = fopen(pathname, "rb+");
|
||||||
|
fileSeekRecord = fileStartRecord + fileIndexRecord;
|
||||||
|
}
|
||||||
|
if (pFile) {
|
||||||
|
if ((fileStartRecord != -1) && (fileSeekRecord > 0)) {
|
||||||
|
/* seek to the start record */
|
||||||
|
for (i = 0; i < fileSeekRecord; i++) {
|
||||||
|
pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile);
|
||||||
|
if ((pData == NULL) || feof(pFile)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fwrite(fileData, fileDataLen, 1, pFile) == 1) {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
fclose(pFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reads record data from a file
|
||||||
|
* @param pathname - name of the file to read from
|
||||||
|
* @param fileStartRecord - starting record in the file
|
||||||
|
* @param fileIndexRecord - index of the record to read
|
||||||
|
* @param fileData - data buffer to read into
|
||||||
|
* @param fileDataLen - size of the data buffer
|
||||||
|
* @return true if successful, false otherwise
|
||||||
|
*/
|
||||||
|
bool bacfile_posix_read_record_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartRecord,
|
||||||
|
size_t fileIndexRecord,
|
||||||
|
uint8_t *fileData,
|
||||||
|
size_t fileDataLen)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
FILE *pFile = NULL;
|
||||||
|
uint32_t i = 0;
|
||||||
|
char dummy_data[FILE_RECORD_SIZE] = { 0 };
|
||||||
|
const char *pData = NULL;
|
||||||
|
size_t fileSeekRecord = 0;
|
||||||
|
|
||||||
|
if (pathname) {
|
||||||
|
pFile = fopen(pathname, "rb");
|
||||||
|
if (pFile) {
|
||||||
|
fileSeekRecord = fileStartRecord + fileIndexRecord;
|
||||||
|
/* seek to the start record */
|
||||||
|
for (i = 0; i < fileSeekRecord; i++) {
|
||||||
|
pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile);
|
||||||
|
if ((pData == NULL) || feof(pFile)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((i == fileSeekRecord) && (fileDataLen <= sizeof(dummy_data))) {
|
||||||
|
/* copy the record data */
|
||||||
|
memmove(fileData, &dummy_data[0], fileDataLen);
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
fclose(pFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the object data
|
||||||
|
*/
|
||||||
|
void bacfile_posix_init(void)
|
||||||
|
{
|
||||||
|
#if defined(BACFILE)
|
||||||
|
bacfile_write_stream_data_callback_set(bacfile_posix_write_stream_data);
|
||||||
|
bacfile_read_stream_data_callback_set(bacfile_posix_read_stream_data);
|
||||||
|
bacfile_write_record_data_callback_set(bacfile_posix_write_record_data);
|
||||||
|
bacfile_read_record_data_callback_set(bacfile_posix_read_record_data);
|
||||||
|
bacfile_file_size_callback_set(bacfile_posix_file_size);
|
||||||
|
bacfile_file_size_set_callback_set(bacfile_posix_file_size_set);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief A POSIX BACnet File Object implementation.
|
||||||
|
* @author Steve Karg
|
||||||
|
* @date July 2025
|
||||||
|
* @copyright SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
#ifndef BACNET_FILE_POSIX_H
|
||||||
|
#define BACNET_FILE_POSIX_H
|
||||||
|
/* BACnet Stack defines - first */
|
||||||
|
#include "bacnet/bacdef.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t bacfile_posix_file_size(const char *pathname);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool bacfile_posix_file_size_set(const char *pathname, size_t file_size);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t bacfile_posix_read_stream_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartPosition,
|
||||||
|
uint8_t *fileData,
|
||||||
|
size_t fileDataLen);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
size_t bacfile_posix_write_stream_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartPosition,
|
||||||
|
const uint8_t *fileData,
|
||||||
|
size_t fileDataLen);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool bacfile_posix_write_record_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartRecord,
|
||||||
|
size_t fileIndexRecord,
|
||||||
|
const uint8_t *fileData,
|
||||||
|
size_t fileDataLen);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool bacfile_posix_read_record_data(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartRecord,
|
||||||
|
size_t fileIndexRecord,
|
||||||
|
uint8_t *fileData,
|
||||||
|
size_t fileDataLen);
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_posix_init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
#endif
|
||||||
+1
@@ -205,6 +205,7 @@
|
|||||||
<ClCompile Include="..\..\..\..\src\bacnet\basic\service\h_arf.c" />
|
<ClCompile Include="..\..\..\..\src\bacnet\basic\service\h_arf.c" />
|
||||||
<ClCompile Include="..\..\..\..\src\bacnet\basic\service\h_arf_a.c" />
|
<ClCompile Include="..\..\..\..\src\bacnet\basic\service\h_arf_a.c" />
|
||||||
<ClCompile Include="..\..\..\..\src\bacnet\datalink\dlenv.c" />
|
<ClCompile Include="..\..\..\..\src\bacnet\datalink\dlenv.c" />
|
||||||
|
<ClCompile Include="..\..\..\..\ports\posix\bacfile-posix.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|||||||
+3
@@ -165,5 +165,8 @@
|
|||||||
<ClCompile Include="..\..\..\..\src\bacnet\basic\bbmd\h_bbmd.c">
|
<ClCompile Include="..\..\..\..\src\bacnet\basic\bbmd\h_bbmd.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\..\ports\posix\bacfile-posix.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -219,6 +219,7 @@
|
|||||||
<ClCompile Include="..\..\..\..\src\bacnet\wpm.c" />
|
<ClCompile Include="..\..\..\..\src\bacnet\wpm.c" />
|
||||||
<ClCompile Include="..\..\..\..\src\bacnet\write_group.c" />
|
<ClCompile Include="..\..\..\..\src\bacnet\write_group.c" />
|
||||||
<ClCompile Include="..\..\..\..\src\bacnet\youare.c" />
|
<ClCompile Include="..\..\..\..\src\bacnet\youare.c" />
|
||||||
|
<ClCompile Include="..\..\..\..\ports\posix\bacfile-posix.c" />
|
||||||
<ClCompile Include="..\..\bip-init.c" />
|
<ClCompile Include="..\..\bip-init.c" />
|
||||||
<ClCompile Include="..\..\datetime-init.c" />
|
<ClCompile Include="..\..\datetime-init.c" />
|
||||||
<ClCompile Include="..\..\mstimer-init.c" />
|
<ClCompile Include="..\..\mstimer-init.c" />
|
||||||
@@ -439,6 +440,7 @@
|
|||||||
<ClInclude Include="..\..\..\..\src\bacnet\wpm.h" />
|
<ClInclude Include="..\..\..\..\src\bacnet\wpm.h" />
|
||||||
<ClInclude Include="..\..\..\..\src\bacnet\write_group.h" />
|
<ClInclude Include="..\..\..\..\src\bacnet\write_group.h" />
|
||||||
<ClInclude Include="..\..\..\..\src\bacnet\youare.h" />
|
<ClInclude Include="..\..\..\..\src\bacnet\youare.h" />
|
||||||
|
<ClInclude Include="..\..\..\..\ports\posix\bacfile-posix.h" />
|
||||||
<ClInclude Include="..\..\bacport.h" />
|
<ClInclude Include="..\..\bacport.h" />
|
||||||
<ClInclude Include="..\..\rs485.h" />
|
<ClInclude Include="..\..\rs485.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -594,6 +594,9 @@
|
|||||||
<ClCompile Include="..\..\..\..\src\bacnet\basic\sys\lighting_command.c">
|
<ClCompile Include="..\..\..\..\src\bacnet\basic\sys\lighting_command.c">
|
||||||
<Filter>Source Files\src\bacnet\basic\sys</Filter>
|
<Filter>Source Files\src\bacnet\basic\sys</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\..\ports\posix\bacfile-posix.c">
|
||||||
|
<Filter>Source Files\ports\posix</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\bip-init.c">
|
<ClCompile Include="..\..\bip-init.c">
|
||||||
<Filter>Source Files\ports\win32</Filter>
|
<Filter>Source Files\ports\win32</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -926,6 +929,9 @@
|
|||||||
<ClInclude Include="..\..\..\..\src\bacnet\basic\sys\sbuf.h">
|
<ClInclude Include="..\..\..\..\src\bacnet\basic\sys\sbuf.h">
|
||||||
<Filter>Source Files\src\bacnet\basic\sys</Filter>
|
<Filter>Source Files\src\bacnet\basic\sys</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\..\ports\posix\bacfile-posix.h">
|
||||||
|
<Filter>Source Files\ports\posix</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\bacport.h">
|
<ClInclude Include="..\..\bacport.h">
|
||||||
<Filter>Source Files\ports\win32</Filter>
|
<Filter>Source Files\ports\win32</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -27,17 +27,20 @@ struct object_data {
|
|||||||
static struct object_data Object_List[MAX_ACCUMULATORS];
|
static struct object_data Object_List[MAX_ACCUMULATORS];
|
||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_NAME,
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER,
|
||||||
PROP_PRESENT_VALUE,
|
PROP_OBJECT_NAME,
|
||||||
PROP_STATUS_FLAGS,
|
PROP_OBJECT_TYPE,
|
||||||
PROP_EVENT_STATE,
|
PROP_PRESENT_VALUE,
|
||||||
PROP_OUT_OF_SERVICE,
|
PROP_STATUS_FLAGS,
|
||||||
PROP_SCALE,
|
PROP_EVENT_STATE,
|
||||||
PROP_UNITS,
|
PROP_OUT_OF_SERVICE,
|
||||||
PROP_MAX_PRES_VALUE,
|
PROP_SCALE,
|
||||||
-1 };
|
PROP_UNITS,
|
||||||
|
PROP_MAX_PRES_VALUE,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = { PROP_DESCRIPTION, -1 };
|
static const int Properties_Optional[] = { PROP_DESCRIPTION, -1 };
|
||||||
|
|
||||||
|
|||||||
@@ -24,20 +24,23 @@ static bool Access_Credential_Initialized = false;
|
|||||||
static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS];
|
static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS];
|
||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_NAME,
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER,
|
||||||
PROP_GLOBAL_IDENTIFIER,
|
PROP_OBJECT_NAME,
|
||||||
PROP_STATUS_FLAGS,
|
PROP_OBJECT_TYPE,
|
||||||
PROP_RELIABILITY,
|
PROP_GLOBAL_IDENTIFIER,
|
||||||
PROP_CREDENTIAL_STATUS,
|
PROP_STATUS_FLAGS,
|
||||||
PROP_REASON_FOR_DISABLE,
|
PROP_RELIABILITY,
|
||||||
PROP_AUTHENTICATION_FACTORS,
|
PROP_CREDENTIAL_STATUS,
|
||||||
PROP_ACTIVATION_TIME,
|
PROP_REASON_FOR_DISABLE,
|
||||||
PROP_EXPIRATION_TIME,
|
PROP_AUTHENTICATION_FACTORS,
|
||||||
PROP_CREDENTIAL_DISABLE,
|
PROP_ACTIVATION_TIME,
|
||||||
PROP_ASSIGNED_ACCESS_RIGHTS,
|
PROP_EXPIRATION_TIME,
|
||||||
-1 };
|
PROP_CREDENTIAL_DISABLE,
|
||||||
|
PROP_ASSIGNED_ACCESS_RIGHTS,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = { -1 };
|
static const int Properties_Optional[] = { -1 };
|
||||||
|
|
||||||
|
|||||||
@@ -22,20 +22,23 @@ static bool Access_Door_Initialized = false;
|
|||||||
static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS];
|
static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS];
|
||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_NAME,
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER,
|
||||||
PROP_PRESENT_VALUE,
|
PROP_OBJECT_NAME,
|
||||||
PROP_STATUS_FLAGS,
|
PROP_OBJECT_TYPE,
|
||||||
PROP_EVENT_STATE,
|
PROP_PRESENT_VALUE,
|
||||||
PROP_RELIABILITY,
|
PROP_STATUS_FLAGS,
|
||||||
PROP_OUT_OF_SERVICE,
|
PROP_EVENT_STATE,
|
||||||
PROP_PRIORITY_ARRAY,
|
PROP_RELIABILITY,
|
||||||
PROP_RELINQUISH_DEFAULT,
|
PROP_OUT_OF_SERVICE,
|
||||||
PROP_DOOR_PULSE_TIME,
|
PROP_PRIORITY_ARRAY,
|
||||||
PROP_DOOR_EXTENDED_PULSE_TIME,
|
PROP_RELINQUISH_DEFAULT,
|
||||||
PROP_DOOR_OPEN_TOO_LONG_TIME,
|
PROP_DOOR_PULSE_TIME,
|
||||||
-1 };
|
PROP_DOOR_EXTENDED_PULSE_TIME,
|
||||||
|
PROP_DOOR_OPEN_TOO_LONG_TIME,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = {
|
static const int Properties_Optional[] = {
|
||||||
PROP_DOOR_STATUS, PROP_LOCK_STATUS,
|
PROP_DOOR_STATUS, PROP_LOCK_STATUS,
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ static ACCESS_POINT_DESCR ap_descr[MAX_ACCESS_POINTS];
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER,
|
PROP_OBJECT_IDENTIFIER,
|
||||||
PROP_OBJECT_NAME,
|
PROP_OBJECT_NAME,
|
||||||
PROP_OBJECT_TYPE,
|
PROP_OBJECT_TYPE,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ static ACCESS_USER_DESCR au_descr[MAX_ACCESS_USERS];
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_GLOBAL_IDENTIFIER, PROP_STATUS_FLAGS, PROP_RELIABILITY,
|
PROP_GLOBAL_IDENTIFIER, PROP_STATUS_FLAGS, PROP_RELIABILITY,
|
||||||
PROP_USER_TYPE, PROP_CREDENTIALS, -1
|
PROP_USER_TYPE, PROP_CREDENTIALS, -1
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ static ACCESS_ZONE_DESCR az_descr[MAX_ACCESS_ZONES];
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_GLOBAL_IDENTIFIER, PROP_OCCUPANCY_STATE, PROP_STATUS_FLAGS,
|
PROP_GLOBAL_IDENTIFIER, PROP_OCCUPANCY_STATE, PROP_STATUS_FLAGS,
|
||||||
PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE,
|
PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE,
|
||||||
|
|||||||
@@ -30,29 +30,36 @@ static OS_Keylist Object_List;
|
|||||||
/* common object type */
|
/* common object type */
|
||||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ANALOG_INPUT;
|
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ANALOG_INPUT;
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
/* unordered list of required properties */
|
||||||
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_OUT_OF_SERVICE, PROP_UNITS, -1
|
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
||||||
|
PROP_OUT_OF_SERVICE, PROP_UNITS, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = {
|
static const int Properties_Optional[] = {
|
||||||
PROP_DESCRIPTION, PROP_RELIABILITY, PROP_COV_INCREMENT,
|
/* unordered list of optional properties */
|
||||||
|
PROP_DESCRIPTION,
|
||||||
|
PROP_RELIABILITY,
|
||||||
|
PROP_COV_INCREMENT,
|
||||||
#if defined(INTRINSIC_REPORTING)
|
#if defined(INTRINSIC_REPORTING)
|
||||||
PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT,
|
PROP_TIME_DELAY,
|
||||||
PROP_LOW_LIMIT, PROP_DEADBAND, PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE,
|
PROP_NOTIFICATION_CLASS,
|
||||||
PROP_ACKED_TRANSITIONS, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS,
|
PROP_HIGH_LIMIT,
|
||||||
|
PROP_LOW_LIMIT,
|
||||||
|
PROP_DEADBAND,
|
||||||
|
PROP_LIMIT_ENABLE,
|
||||||
|
PROP_EVENT_ENABLE,
|
||||||
|
PROP_ACKED_TRANSITIONS,
|
||||||
|
PROP_NOTIFY_TYPE,
|
||||||
|
PROP_EVENT_TIME_STAMPS,
|
||||||
PROP_EVENT_DETECTION_ENABLE,
|
PROP_EVENT_DETECTION_ENABLE,
|
||||||
#endif
|
#endif
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Proprietary[] = {
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
-1
|
|
||||||
};
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the pointers for the required, the optional and the properitary
|
* Initialize the pointers for the required, the optional and the properitary
|
||||||
|
|||||||
+370
-220
@@ -46,20 +46,26 @@ static OS_Keylist Object_List;
|
|||||||
/* common object type */
|
/* common object type */
|
||||||
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_FILE;
|
static const BACNET_OBJECT_TYPE Object_Type = OBJECT_FILE;
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int bacfile_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_NAME,
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER,
|
||||||
PROP_FILE_TYPE,
|
PROP_OBJECT_NAME,
|
||||||
PROP_FILE_SIZE,
|
PROP_OBJECT_TYPE,
|
||||||
PROP_MODIFICATION_DATE,
|
PROP_FILE_TYPE,
|
||||||
PROP_ARCHIVE,
|
PROP_FILE_SIZE,
|
||||||
PROP_READ_ONLY,
|
PROP_MODIFICATION_DATE,
|
||||||
PROP_FILE_ACCESS_METHOD,
|
PROP_ARCHIVE,
|
||||||
-1 };
|
PROP_READ_ONLY,
|
||||||
|
PROP_FILE_ACCESS_METHOD,
|
||||||
|
-1
|
||||||
|
};
|
||||||
|
|
||||||
static const int bacfile_Properties_Optional[] = { PROP_DESCRIPTION, -1 };
|
static const int Properties_Optional[] = {
|
||||||
|
/* unordered list of optional properties */
|
||||||
|
PROP_DESCRIPTION, -1
|
||||||
|
};
|
||||||
|
|
||||||
static const int bacfile_Properties_Proprietary[] = { -1 };
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the list of required, optional, and proprietary properties.
|
* @brief Returns the list of required, optional, and proprietary properties.
|
||||||
@@ -75,13 +81,13 @@ void BACfile_Property_Lists(
|
|||||||
const int **pRequired, const int **pOptional, const int **pProprietary)
|
const int **pRequired, const int **pOptional, const int **pProprietary)
|
||||||
{
|
{
|
||||||
if (pRequired) {
|
if (pRequired) {
|
||||||
*pRequired = bacfile_Properties_Required;
|
*pRequired = Properties_Required;
|
||||||
}
|
}
|
||||||
if (pOptional) {
|
if (pOptional) {
|
||||||
*pOptional = bacfile_Properties_Optional;
|
*pOptional = Properties_Optional;
|
||||||
}
|
}
|
||||||
if (pProprietary) {
|
if (pProprietary) {
|
||||||
*pProprietary = bacfile_Properties_Proprietary;
|
*pProprietary = Properties_Proprietary;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -280,22 +286,221 @@ uint32_t bacfile_index_to_instance(unsigned find_index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Determines the file size for a given file
|
* @brief Callback function to write record data
|
||||||
* @param pFile - file handle
|
|
||||||
* @return file size in bytes, or 0 if not found
|
|
||||||
*/
|
*/
|
||||||
static long fsize(FILE *pFile)
|
static bool (*bacfile_write_record_data_cb)(
|
||||||
{
|
const char *, size_t, size_t, const uint8_t *, size_t) = NULL;
|
||||||
long size = 0;
|
|
||||||
long origin = 0;
|
|
||||||
|
|
||||||
if (pFile) {
|
/**
|
||||||
origin = ftell(pFile);
|
* @brief Callback function to write record data
|
||||||
fseek(pFile, 0L, SEEK_END);
|
*
|
||||||
size = ftell(pFile);
|
* @param pathname - name of the file to write to
|
||||||
fseek(pFile, origin, SEEK_SET);
|
* @param fileStartRecord - starting record number in the file
|
||||||
|
* @param record_index - index of the record to write
|
||||||
|
* @param buffer - data buffer to write
|
||||||
|
* @param buffer_size - size of the data buffer
|
||||||
|
* @return true if the record data was written successfully
|
||||||
|
* @return false if the record data could not be written
|
||||||
|
*/
|
||||||
|
static bool bacfile_write_record_data_callback(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartRecord,
|
||||||
|
size_t record_index,
|
||||||
|
const uint8_t *buffer,
|
||||||
|
size_t buffer_size)
|
||||||
|
{
|
||||||
|
if (bacfile_write_record_data_cb) {
|
||||||
|
return bacfile_write_record_data_cb(
|
||||||
|
pathname, fileStartRecord, record_index, buffer, buffer_size);
|
||||||
}
|
}
|
||||||
return (size);
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the callback function for writing record data
|
||||||
|
* @param callback - function pointer to the callback
|
||||||
|
*/
|
||||||
|
void bacfile_write_record_data_callback_set(
|
||||||
|
bool (*callback)(const char *, size_t, size_t, const uint8_t *, size_t))
|
||||||
|
{
|
||||||
|
bacfile_write_record_data_cb = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to read record data
|
||||||
|
*/
|
||||||
|
static bool (*bacfile_read_record_data_cb)(
|
||||||
|
const char *, size_t, size_t, uint8_t *, size_t) = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to read record data
|
||||||
|
* @param pathname - name of the file to read from
|
||||||
|
* @param fileStartRecord - starting record number in the file
|
||||||
|
* @param record_index - index of the record to read
|
||||||
|
* @param buffer - data buffer to read into
|
||||||
|
* @param buffer_size - size of the data buffer
|
||||||
|
* @return true if the record data was read successfully
|
||||||
|
* @return false if the record data could not be read
|
||||||
|
*/
|
||||||
|
static bool bacfile_read_record_data_callback(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartRecord,
|
||||||
|
size_t record_index,
|
||||||
|
uint8_t *buffer,
|
||||||
|
size_t buffer_size)
|
||||||
|
{
|
||||||
|
if (bacfile_read_record_data_cb) {
|
||||||
|
return bacfile_read_record_data_cb(
|
||||||
|
pathname, fileStartRecord, record_index, buffer, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the callback function for reading record data
|
||||||
|
* @param callback - function pointer to the callback
|
||||||
|
*/
|
||||||
|
void bacfile_read_record_data_callback_set(
|
||||||
|
bool (*callback)(const char *, size_t, size_t, uint8_t *, size_t))
|
||||||
|
{
|
||||||
|
bacfile_read_record_data_cb = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to write stream data
|
||||||
|
*/
|
||||||
|
static size_t (*bacfile_write_stream_data_cb)(
|
||||||
|
const char *, size_t, const uint8_t *, size_t) = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to write stream data
|
||||||
|
* @param pathname - name of the file to write to
|
||||||
|
* @param fileStartPosition - starting position in the file
|
||||||
|
* @param buffer - data buffer to write
|
||||||
|
* @param buffer_size - size of the data buffer
|
||||||
|
* @return number of bytes written, or 0 if not successful
|
||||||
|
*/
|
||||||
|
static size_t bacfile_write_stream_data_callback(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartPosition,
|
||||||
|
const uint8_t *buffer,
|
||||||
|
size_t buffer_size)
|
||||||
|
{
|
||||||
|
if (bacfile_write_stream_data_cb) {
|
||||||
|
return bacfile_write_stream_data_cb(
|
||||||
|
pathname, fileStartPosition, buffer, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the callback function for writing stream data
|
||||||
|
* @param callback - function pointer to the callback
|
||||||
|
*/
|
||||||
|
void bacfile_write_stream_data_callback_set(
|
||||||
|
size_t (*callback)(const char *, size_t, const uint8_t *, size_t))
|
||||||
|
{
|
||||||
|
bacfile_write_stream_data_cb = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to read stream data
|
||||||
|
*/
|
||||||
|
static size_t (*bacfile_read_stream_data_cb)(
|
||||||
|
const char *, size_t, uint8_t *, size_t) = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to read stream data
|
||||||
|
* @param pathname - name of the file to read from
|
||||||
|
* @param fileStartPosition - starting position in the file
|
||||||
|
* @param buffer - data buffer to read into
|
||||||
|
* @param buffer_size - size of the data buffer and number of bytes to read
|
||||||
|
* @return number of bytes read, or 0 if not successful
|
||||||
|
*/
|
||||||
|
static size_t bacfile_read_stream_data_callback(
|
||||||
|
const char *pathname,
|
||||||
|
size_t fileStartPosition,
|
||||||
|
uint8_t *buffer,
|
||||||
|
size_t buffer_size)
|
||||||
|
{
|
||||||
|
if (bacfile_read_stream_data_cb) {
|
||||||
|
return bacfile_read_stream_data_cb(
|
||||||
|
pathname, fileStartPosition, buffer, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the callback function for reading stream data
|
||||||
|
* @param callback - function pointer to the callback
|
||||||
|
*/
|
||||||
|
void bacfile_read_stream_data_callback_set(
|
||||||
|
size_t (*callback)(const char *, size_t, uint8_t *, size_t))
|
||||||
|
{
|
||||||
|
bacfile_read_stream_data_cb = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to get file size
|
||||||
|
*/
|
||||||
|
static size_t (*bacfile_file_size_cb)(const char *) = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to get file size
|
||||||
|
* @param pathname - name of the file to get the size of
|
||||||
|
* @return size of the file in bytes, or 0 if not found
|
||||||
|
*/
|
||||||
|
static size_t bacfile_file_size_callback(const char *pathname)
|
||||||
|
{
|
||||||
|
size_t file_size = 0;
|
||||||
|
|
||||||
|
if (bacfile_file_size_cb) {
|
||||||
|
file_size = bacfile_file_size_cb(pathname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the callback function for getting file size
|
||||||
|
* @param callback - function pointer to the callback
|
||||||
|
*/
|
||||||
|
void bacfile_file_size_callback_set(size_t (*callback)(const char *))
|
||||||
|
{
|
||||||
|
bacfile_file_size_cb = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to set file size
|
||||||
|
*/
|
||||||
|
static bool (*bacfile_file_size_set_cb)(const char *, size_t) = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback function to set file size
|
||||||
|
* @param pathname - name of the file to set the size for
|
||||||
|
* @param file_size - value of the file size property
|
||||||
|
* @return true if file size is writable, false otherwise
|
||||||
|
*/
|
||||||
|
bool bacfile_file_size_set_callback(const char *pathname, size_t file_size)
|
||||||
|
{
|
||||||
|
if (bacfile_file_size_set_cb) {
|
||||||
|
return bacfile_file_size_set_cb(pathname, file_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the callback function for setting file size
|
||||||
|
* @param callback - function pointer to the callback
|
||||||
|
*/
|
||||||
|
void bacfile_file_size_set_callback_set(bool (*callback)(const char *, size_t))
|
||||||
|
{
|
||||||
|
bacfile_file_size_set_cb = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -308,22 +513,13 @@ static long fsize(FILE *pFile)
|
|||||||
uint32_t
|
uint32_t
|
||||||
bacfile_read(uint32_t object_instance, uint8_t *buffer, uint32_t buffer_size)
|
bacfile_read(uint32_t object_instance, uint8_t *buffer, uint32_t buffer_size)
|
||||||
{
|
{
|
||||||
const char *pFilename = NULL;
|
const char *pathname = NULL;
|
||||||
FILE *pFile = NULL;
|
|
||||||
long file_size = 0;
|
long file_size = 0;
|
||||||
|
|
||||||
pFilename = bacfile_pathname(object_instance);
|
pathname = bacfile_pathname(object_instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
pFile = fopen(pFilename, "rb");
|
file_size =
|
||||||
if (pFile) {
|
bacfile_read_stream_data_callback(pathname, 0, buffer, buffer_size);
|
||||||
file_size = fsize(pFile);
|
|
||||||
if (buffer && (buffer_size >= file_size)) {
|
|
||||||
if (fread(buffer, file_size, 1, pFile) == 0) {
|
|
||||||
file_size = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint32_t)file_size;
|
return (uint32_t)file_size;
|
||||||
@@ -339,20 +535,13 @@ bacfile_read(uint32_t object_instance, uint8_t *buffer, uint32_t buffer_size)
|
|||||||
uint32_t bacfile_write(
|
uint32_t bacfile_write(
|
||||||
uint32_t object_instance, const uint8_t *buffer, uint32_t buffer_size)
|
uint32_t object_instance, const uint8_t *buffer, uint32_t buffer_size)
|
||||||
{
|
{
|
||||||
const char *pFilename = NULL;
|
const char *pathname = NULL;
|
||||||
FILE *pFile = NULL;
|
|
||||||
long file_size = 0;
|
long file_size = 0;
|
||||||
|
|
||||||
pFilename = bacfile_pathname(object_instance);
|
pathname = bacfile_pathname(object_instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
/* open the file as a clean slate when starting at 0 */
|
file_size = bacfile_write_stream_data_callback(
|
||||||
pFile = fopen(pFilename, "wb");
|
pathname, 0, buffer, buffer_size);
|
||||||
if (pFile) {
|
|
||||||
if (fwrite(buffer, buffer_size, 1, pFile) == 1) {
|
|
||||||
file_size = buffer_size;
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint32_t)file_size;
|
return (uint32_t)file_size;
|
||||||
@@ -365,20 +554,15 @@ uint32_t bacfile_write(
|
|||||||
*/
|
*/
|
||||||
BACNET_UNSIGNED_INTEGER bacfile_file_size(uint32_t object_instance)
|
BACNET_UNSIGNED_INTEGER bacfile_file_size(uint32_t object_instance)
|
||||||
{
|
{
|
||||||
const char *pFilename = NULL;
|
const char *pathname = NULL;
|
||||||
FILE *pFile = NULL;
|
|
||||||
long file_position = 0;
|
long file_position = 0;
|
||||||
BACNET_UNSIGNED_INTEGER file_size = 0;
|
BACNET_UNSIGNED_INTEGER file_size = 0;
|
||||||
|
|
||||||
pFilename = bacfile_pathname(object_instance);
|
pathname = bacfile_pathname(object_instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
pFile = fopen(pFilename, "rb");
|
file_position = bacfile_file_size_callback(pathname);
|
||||||
if (pFile) {
|
if (file_position >= 0) {
|
||||||
file_position = fsize(pFile);
|
file_size = (BACNET_UNSIGNED_INTEGER)file_position;
|
||||||
if (file_position >= 0) {
|
|
||||||
file_size = (BACNET_UNSIGNED_INTEGER)file_position;
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,8 +584,8 @@ bool bacfile_file_size_set(
|
|||||||
pObject = Keylist_Data(Object_List, object_instance);
|
pObject = Keylist_Data(Object_List, object_instance);
|
||||||
if (pObject) {
|
if (pObject) {
|
||||||
if (pObject->File_Access_Stream) {
|
if (pObject->File_Access_Stream) {
|
||||||
(void)file_size;
|
status =
|
||||||
/* FIXME: add clever POSIX file stuff here */
|
bacfile_file_size_set_callback(pObject->Pathname, file_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,20 +901,16 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
|
||||||
case PROP_OBJECT_NAME:
|
|
||||||
case PROP_OBJECT_TYPE:
|
|
||||||
case PROP_DESCRIPTION:
|
|
||||||
case PROP_FILE_TYPE:
|
|
||||||
case PROP_MODIFICATION_DATE:
|
|
||||||
case PROP_READ_ONLY:
|
|
||||||
case PROP_FILE_ACCESS_METHOD:
|
|
||||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
|
||||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
if (property_lists_member(
|
||||||
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
Properties_Required, Properties_Optional,
|
||||||
|
Properties_Proprietary, wp_data->object_property)) {
|
||||||
|
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
|
} else {
|
||||||
|
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -786,31 +966,27 @@ uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
|
|||||||
|
|
||||||
bool bacfile_read_stream_data(BACNET_ATOMIC_READ_FILE_DATA *data)
|
bool bacfile_read_stream_data(BACNET_ATOMIC_READ_FILE_DATA *data)
|
||||||
{
|
{
|
||||||
const char *pFilename = NULL;
|
const char *pathname = NULL;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
FILE *pFile = NULL;
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
size_t requestedOctetCount = 0;
|
||||||
|
|
||||||
pFilename = bacfile_pathname(data->object_instance);
|
pathname = bacfile_pathname(data->object_instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
found = true;
|
found = true;
|
||||||
pFile = fopen(pFilename, "rb");
|
requestedOctetCount = data->type.stream.requestedOctetCount;
|
||||||
if (pFile) {
|
if (requestedOctetCount > octetstring_capacity(&data->fileData[0])) {
|
||||||
(void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
|
requestedOctetCount = octetstring_capacity(&data->fileData[0]);
|
||||||
len = fread(
|
|
||||||
octetstring_value(&data->fileData[0]), 1,
|
|
||||||
data->type.stream.requestedOctetCount, pFile);
|
|
||||||
if (len < data->type.stream.requestedOctetCount) {
|
|
||||||
data->endOfFile = true;
|
|
||||||
} else {
|
|
||||||
data->endOfFile = false;
|
|
||||||
}
|
|
||||||
octetstring_truncate(&data->fileData[0], len);
|
|
||||||
fclose(pFile);
|
|
||||||
} else {
|
|
||||||
octetstring_truncate(&data->fileData[0], 0);
|
|
||||||
data->endOfFile = true;
|
|
||||||
}
|
}
|
||||||
|
len = bacfile_read_stream_data_callback(
|
||||||
|
pathname, data->type.stream.fileStartPosition,
|
||||||
|
octetstring_value(&data->fileData[0]), requestedOctetCount);
|
||||||
|
if (len < requestedOctetCount) {
|
||||||
|
data->endOfFile = true;
|
||||||
|
} else {
|
||||||
|
data->endOfFile = false;
|
||||||
|
}
|
||||||
|
octetstring_truncate(&data->fileData[0], len);
|
||||||
} else {
|
} else {
|
||||||
octetstring_truncate(&data->fileData[0], 0);
|
octetstring_truncate(&data->fileData[0], 0);
|
||||||
data->endOfFile = true;
|
data->endOfFile = true;
|
||||||
@@ -819,163 +995,137 @@ bool bacfile_read_stream_data(BACNET_ATOMIC_READ_FILE_DATA *data)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bacfile_read_record_data(BACNET_ATOMIC_READ_FILE_DATA *data)
|
||||||
|
{
|
||||||
|
const char *pathname = NULL;
|
||||||
|
bool found = false;
|
||||||
|
bool status = false;
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
pathname = bacfile_pathname(data->object_instance);
|
||||||
|
if (pathname) {
|
||||||
|
found = true;
|
||||||
|
data->endOfFile = false;
|
||||||
|
for (i = 0; i < data->type.record.RecordCount; i++) {
|
||||||
|
status = bacfile_read_record_data_callback(
|
||||||
|
pathname, data->type.record.fileStartRecord, i,
|
||||||
|
octetstring_value(&data->fileData[i]),
|
||||||
|
octetstring_capacity(&data->fileData[i]));
|
||||||
|
if (!status) {
|
||||||
|
data->endOfFile = true;
|
||||||
|
data->type.record.RecordCount = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA *data)
|
bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA *data)
|
||||||
{
|
{
|
||||||
const char *pFilename = NULL;
|
const char *pathname = NULL;
|
||||||
bool found = false;
|
bool status = false;
|
||||||
FILE *pFile = NULL;
|
size_t bytes_written = 0;
|
||||||
|
|
||||||
pFilename = bacfile_pathname(data->object_instance);
|
pathname = bacfile_pathname(data->object_instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
found = true;
|
status = true;
|
||||||
if (data->type.stream.fileStartPosition == 0) {
|
/* note: If 'File Start Position' parameter has the special
|
||||||
/* open the file as a clean slate when starting at 0 */
|
value -1, then the write operation shall be treated
|
||||||
pFile = fopen(pFilename, "wb");
|
as an append to the current end of file.
|
||||||
} else if (data->type.stream.fileStartPosition == -1) {
|
If the 'File Start Position' parameter is 0,
|
||||||
/* If 'File Start Position' parameter has the special
|
open the file as a clean slate. */
|
||||||
value -1, then the write operation shall be treated
|
bytes_written = bacfile_write_stream_data_callback(
|
||||||
as an append to the current end of file. */
|
pathname, data->type.stream.fileStartPosition,
|
||||||
pFile = fopen(pFilename, "ab+");
|
octetstring_value(&data->fileData[0]),
|
||||||
} else {
|
octetstring_length(&data->fileData[0]));
|
||||||
/* open for update */
|
if (bytes_written == 0) {
|
||||||
pFile = fopen(pFilename, "rb+");
|
status = false; /* no data written */
|
||||||
}
|
|
||||||
if (pFile) {
|
|
||||||
if (data->type.stream.fileStartPosition != -1) {
|
|
||||||
(void)fseek(
|
|
||||||
pFile, data->type.stream.fileStartPosition, SEEK_SET);
|
|
||||||
}
|
|
||||||
if (fwrite(
|
|
||||||
octetstring_value(&data->fileData[0]),
|
|
||||||
octetstring_length(&data->fileData[0]), 1, pFile) != 1) {
|
|
||||||
/* do something if it fails? */
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write the data received to the file specified
|
||||||
|
* @param data - pointer to the data to write
|
||||||
|
* @return true - if successful
|
||||||
|
* @return false - if failed
|
||||||
|
*/
|
||||||
bool bacfile_write_record_data(const BACNET_ATOMIC_WRITE_FILE_DATA *data)
|
bool bacfile_write_record_data(const BACNET_ATOMIC_WRITE_FILE_DATA *data)
|
||||||
{
|
{
|
||||||
const char *pFilename = NULL;
|
const char *pathname = NULL;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
FILE *pFile = NULL;
|
size_t i = 0;
|
||||||
uint32_t i = 0;
|
|
||||||
char dummy_data[FILE_RECORD_SIZE];
|
|
||||||
const char *pData = NULL;
|
|
||||||
|
|
||||||
pFilename = bacfile_pathname(data->object_instance);
|
pathname = bacfile_pathname(data->object_instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
found = true;
|
found = true;
|
||||||
if (data->type.record.fileStartRecord == 0) {
|
/* If 'File Start Record' parameter has the special
|
||||||
/* open the file as a clean slate when starting at 0 */
|
value -1, then the write operation shall be treated
|
||||||
pFile = fopen(pFilename, "wb");
|
as an append to the current end of file.
|
||||||
} else if (data->type.record.fileStartRecord == -1) {
|
If the 'File Start Record' parameter is 0,
|
||||||
/* If 'File Start Record' parameter has the special
|
open the file as a clean slate. */
|
||||||
value -1, then the write operation shall be treated
|
for (i = 0; i < data->type.record.returnedRecordCount; i++) {
|
||||||
as an append to the current end of file. */
|
bacfile_write_record_data_callback(
|
||||||
pFile = fopen(pFilename, "ab+");
|
pathname, data->type.record.fileStartRecord, i,
|
||||||
} else {
|
octetstring_value((BACNET_OCTET_STRING *)&data->fileData[i]),
|
||||||
/* open for update */
|
octetstring_length(&data->fileData[i]));
|
||||||
pFile = fopen(pFilename, "rb+");
|
|
||||||
}
|
|
||||||
if (pFile) {
|
|
||||||
if ((data->type.record.fileStartRecord != -1) &&
|
|
||||||
(data->type.record.fileStartRecord > 0)) {
|
|
||||||
for (i = 0; i < (uint32_t)data->type.record.fileStartRecord;
|
|
||||||
i++) {
|
|
||||||
pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile);
|
|
||||||
if ((pData == NULL) || feof(pFile)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < data->type.record.returnedRecordCount; i++) {
|
|
||||||
if (fwrite(
|
|
||||||
octetstring_value(
|
|
||||||
(BACNET_OCTET_STRING *)&data->fileData[i]),
|
|
||||||
octetstring_length(&data->fileData[i]), 1,
|
|
||||||
pFile) != 1) {
|
|
||||||
/* do something if it fails? */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write the requested data received into the file specified
|
||||||
|
* @param instance - object-instance number of the object
|
||||||
|
* @param data - pointer to the data to write
|
||||||
|
* @return true - if successful
|
||||||
|
* @return false - if failed
|
||||||
|
*/
|
||||||
bool bacfile_read_ack_stream_data(
|
bool bacfile_read_ack_stream_data(
|
||||||
uint32_t instance, const BACNET_ATOMIC_READ_FILE_DATA *data)
|
uint32_t instance, const BACNET_ATOMIC_READ_FILE_DATA *data)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
FILE *pFile = NULL;
|
const char *pathname = NULL;
|
||||||
const char *pFilename = NULL;
|
|
||||||
|
|
||||||
pFilename = bacfile_pathname(instance);
|
pathname = bacfile_pathname(instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
found = true;
|
found = true;
|
||||||
pFile = fopen(pFilename, "rb+");
|
bacfile_write_stream_data_callback(
|
||||||
if (pFile) {
|
pathname, data->type.stream.fileStartPosition,
|
||||||
(void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
|
octetstring_value((BACNET_OCTET_STRING *)&data->fileData[0]),
|
||||||
if (fwrite(
|
octetstring_length(&data->fileData[0]));
|
||||||
octetstring_value(
|
|
||||||
(BACNET_OCTET_STRING *)&data->fileData[0]),
|
|
||||||
octetstring_length(&data->fileData[0]), 1, pFile) != 1) {
|
|
||||||
#if PRINT_ENABLED
|
|
||||||
fprintf(
|
|
||||||
stderr, "Failed to write to %s (%lu)!\n", pFilename,
|
|
||||||
(unsigned long)instance);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write the requested data received into the file specified
|
||||||
|
* @param instance - object-instance number of the object
|
||||||
|
* @param data - pointer to the data to write
|
||||||
|
* @return true - if successful
|
||||||
|
* @return false - if failed
|
||||||
|
*/
|
||||||
bool bacfile_read_ack_record_data(
|
bool bacfile_read_ack_record_data(
|
||||||
uint32_t instance, const BACNET_ATOMIC_READ_FILE_DATA *data)
|
uint32_t instance, const BACNET_ATOMIC_READ_FILE_DATA *data)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
FILE *pFile = NULL;
|
const char *pathname = NULL;
|
||||||
const char *pFilename = NULL;
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
char dummy_data[MAX_OCTET_STRING_BYTES] = { 0 };
|
|
||||||
char *pData = NULL;
|
|
||||||
|
|
||||||
pFilename = bacfile_pathname(instance);
|
pathname = bacfile_pathname(instance);
|
||||||
if (pFilename) {
|
if (pathname) {
|
||||||
found = true;
|
found = true;
|
||||||
pFile = fopen(pFilename, "rb+");
|
for (i = 0; i < data->type.record.RecordCount; i++) {
|
||||||
if (pFile) {
|
bacfile_write_record_data_callback(
|
||||||
if (data->type.record.fileStartRecord > 0) {
|
pathname, data->type.record.fileStartRecord, i,
|
||||||
for (i = 0; i < (uint32_t)data->type.record.fileStartRecord;
|
octetstring_value((BACNET_OCTET_STRING *)&data->fileData[i]),
|
||||||
i++) {
|
octetstring_length(&data->fileData[i]));
|
||||||
pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile);
|
|
||||||
if ((pData == NULL) || feof(pFile)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = 0; i < data->type.record.RecordCount; i++) {
|
|
||||||
if (fwrite(
|
|
||||||
octetstring_value(
|
|
||||||
(BACNET_OCTET_STRING *)&data->fileData[i]),
|
|
||||||
octetstring_length(&data->fileData[i]), 1,
|
|
||||||
pFile) != 1) {
|
|
||||||
#if PRINT_ENABLED
|
|
||||||
fprintf(
|
|
||||||
stderr, "Failed to write to %s (%lu)!\n", pFilename,
|
|
||||||
(unsigned long)instance);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fclose(pFile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,23 @@ BACNET_STACK_EXPORT
|
|||||||
uint32_t bacfile_write(
|
uint32_t bacfile_write(
|
||||||
uint32_t object_instance, const uint8_t *buffer, uint32_t buffer_size);
|
uint32_t object_instance, const uint8_t *buffer, uint32_t buffer_size);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_write_stream_data_callback_set(
|
||||||
|
size_t (*callback)(const char *, size_t, const uint8_t *, size_t));
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_read_stream_data_callback_set(
|
||||||
|
size_t (*callback)(const char *, size_t, uint8_t *, size_t));
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_write_record_data_callback_set(
|
||||||
|
bool (*callback)(const char *, size_t, size_t, const uint8_t *, size_t));
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_read_record_data_callback_set(
|
||||||
|
bool (*callback)(const char *, size_t, size_t, uint8_t *, size_t));
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_file_size_callback_set(size_t (*callback)(const char *));
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
void bacfile_file_size_set_callback_set(bool (*callback)(const char *, size_t));
|
||||||
|
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
uint32_t bacfile_create(uint32_t object_instance);
|
uint32_t bacfile_create(uint32_t object_instance);
|
||||||
BACNET_STACK_EXPORT
|
BACNET_STACK_EXPORT
|
||||||
|
|||||||
@@ -67,21 +67,16 @@ static const BACNET_OBJECT_TYPE Object_Type = OBJECT_BINARY_INPUT;
|
|||||||
static binary_input_write_present_value_callback
|
static binary_input_write_present_value_callback
|
||||||
Binary_Input_Write_Present_Value_Callback;
|
Binary_Input_Write_Present_Value_Callback;
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_IDENTIFIER,
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_NAME,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_OBJECT_TYPE,
|
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
||||||
PROP_PRESENT_VALUE,
|
PROP_OUT_OF_SERVICE, PROP_POLARITY, -1
|
||||||
PROP_STATUS_FLAGS,
|
|
||||||
PROP_EVENT_STATE,
|
|
||||||
PROP_OUT_OF_SERVICE,
|
|
||||||
PROP_POLARITY,
|
|
||||||
-1
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = {
|
static const int Properties_Optional[] = {
|
||||||
|
/* unordered list of optional properties */
|
||||||
PROP_RELIABILITY,
|
PROP_RELIABILITY,
|
||||||
PROP_DESCRIPTION,
|
PROP_DESCRIPTION,
|
||||||
PROP_ACTIVE_TEXT,
|
PROP_ACTIVE_TEXT,
|
||||||
@@ -100,7 +95,6 @@ static const int Properties_Optional[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Proprietary[] = { -1 };
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the pointers for the required, the optional and the properitary
|
* Initialize the pointers for the required, the optional and the properitary
|
||||||
|
|||||||
@@ -42,13 +42,15 @@ static bitstring_value_write_present_value_callback
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1
|
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = { PROP_RELIABILITY,
|
static const int Properties_Optional[] = {
|
||||||
PROP_OUT_OF_SERVICE,
|
/* unordered list of optional properties */
|
||||||
PROP_DESCRIPTION, -1 };
|
PROP_RELIABILITY, PROP_OUT_OF_SERVICE, PROP_DESCRIPTION, -1
|
||||||
|
};
|
||||||
|
|
||||||
static const int Properties_Proprietary[] = { -1 };
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ static CREDENTIAL_DATA_INPUT_DESCR cdi_descr[MAX_CREDENTIAL_DATA_INPUTS];
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
|
||||||
PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
|
PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
|
||||||
PROP_STATUS_FLAGS, PROP_RELIABILITY,
|
PROP_STATUS_FLAGS, PROP_RELIABILITY,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ static const BACNET_OBJECT_TYPE Object_Type = OBJECT_CHARACTERSTRING_VALUE;
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
/* list of the required properties */
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1
|
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,13 +48,16 @@ static const char *Default_State_Text = "State 1\0"
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
||||||
PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1
|
PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = { PROP_DESCRIPTION, PROP_RELIABILITY,
|
static const int Properties_Optional[] = {
|
||||||
PROP_STATE_TEXT, -1 };
|
/* unordered list of optional properties */
|
||||||
|
PROP_DESCRIPTION, PROP_RELIABILITY, PROP_STATE_TEXT, -1
|
||||||
|
};
|
||||||
|
|
||||||
static const int Properties_Proprietary[] = { -1 };
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
|
|
||||||
|
|||||||
@@ -48,13 +48,16 @@ static const char *Default_State_Text = "State 1\0"
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
|
||||||
PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1
|
PROP_OUT_OF_SERVICE, PROP_NUMBER_OF_STATES, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = { PROP_DESCRIPTION, PROP_RELIABILITY,
|
static const int Properties_Optional[] = {
|
||||||
PROP_STATE_TEXT, -1 };
|
/* unordered list of required properties */
|
||||||
|
PROP_DESCRIPTION, PROP_RELIABILITY, PROP_STATE_TEXT, -1
|
||||||
|
};
|
||||||
|
|
||||||
static const int Properties_Proprietary[] = { -1 };
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ struct object_data {
|
|||||||
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
/* unordered list of properties */
|
/* unordered list of required properties */
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
|
||||||
PROP_OBJECT_TYPE, PROP_PROGRAM_STATE,
|
PROP_OBJECT_TYPE, PROP_PROGRAM_STATE,
|
||||||
PROP_PROGRAM_CHANGE, PROP_STATUS_FLAGS,
|
PROP_PROGRAM_CHANGE, PROP_STATUS_FLAGS,
|
||||||
@@ -65,7 +65,7 @@ static const int Properties_Required[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = {
|
static const int Properties_Optional[] = {
|
||||||
/* unordered list of properties */
|
/* unordered list of optional properties */
|
||||||
PROP_REASON_FOR_HALT,
|
PROP_REASON_FOR_HALT,
|
||||||
PROP_DESCRIPTION_OF_HALT,
|
PROP_DESCRIPTION_OF_HALT,
|
||||||
PROP_PROGRAM_LOCATION,
|
PROP_PROGRAM_LOCATION,
|
||||||
|
|||||||
@@ -45,26 +45,26 @@ struct object_data {
|
|||||||
/* Key List for storing the object data sorted by instance number */
|
/* Key List for storing the object data sorted by instance number */
|
||||||
static OS_Keylist Object_List;
|
static OS_Keylist Object_List;
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
/* These three arrays are used by the ReadPropertyMultiple handler */
|
/* These three arrays are used by the ReadPropertyMultiple handler */
|
||||||
static const int Properties_Required[] = {
|
static const int Properties_Required[] = {
|
||||||
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
/* unordered list of required properties */
|
||||||
PROP_NODE_TYPE, PROP_SUBORDINATE_LIST,
|
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
|
||||||
-1
|
PROP_NODE_TYPE, PROP_SUBORDINATE_LIST, -1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Optional[] = {
|
static const int Properties_Optional[] = {
|
||||||
PROP_DESCRIPTION, PROP_NODE_SUBTYPE, PROP_SUBORDINATE_ANNOTATIONS,
|
/* unordered list of optional properties */
|
||||||
PROP_SUBORDINATE_NODE_TYPES, PROP_SUBORDINATE_RELATIONSHIPS,
|
PROP_DESCRIPTION,
|
||||||
|
PROP_NODE_SUBTYPE,
|
||||||
|
PROP_SUBORDINATE_ANNOTATIONS,
|
||||||
|
PROP_SUBORDINATE_NODE_TYPES,
|
||||||
|
PROP_SUBORDINATE_RELATIONSHIPS,
|
||||||
PROP_DEFAULT_SUBORDINATE_RELATIONSHIP,
|
PROP_DEFAULT_SUBORDINATE_RELATIONSHIP,
|
||||||
PROP_REPRESENTS,
|
PROP_REPRESENTS,
|
||||||
-1
|
-1
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int Properties_Proprietary[] = {
|
static const int Properties_Proprietary[] = { -1 };
|
||||||
-1
|
|
||||||
};
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of required, optional, and proprietary properties.
|
* Returns the list of required, optional, and proprietary properties.
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ void handler_atomic_read_file(
|
|||||||
error_class = ERROR_CLASS_SERVICES;
|
error_class = ERROR_CLASS_SERVICES;
|
||||||
error_code = ERROR_CODE_INVALID_FILE_START_POSITION;
|
error_code = ERROR_CODE_INVALID_FILE_START_POSITION;
|
||||||
error = true;
|
error = true;
|
||||||
} else if (bacfile_read_stream_data(&data)) {
|
} else if (bacfile_read_record_data(&data)) {
|
||||||
debug_fprintf(
|
debug_fprintf(
|
||||||
stderr, "ARF: fileStartRecord %d, %u RecordCount.\n",
|
stderr, "ARF: fileStartRecord %d, %u RecordCount.\n",
|
||||||
(int)data.type.record.fileStartRecord,
|
(int)data.type.record.fileStartRecord,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "bacnet/basic/object/bacfile.h"
|
#include "bacnet/basic/object/bacfile.h"
|
||||||
#include "bacnet/basic/object/netport.h"
|
#include "bacnet/basic/object/netport.h"
|
||||||
#include "bacnet/basic/object/sc_netport.h"
|
#include "bacnet/basic/object/sc_netport.h"
|
||||||
#include "bacnet/basic/object/bacfile.h"
|
|
||||||
#include "bacnet/basic/sys/debug.h"
|
#include "bacnet/basic/sys/debug.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include "bacnet/datalink/datalink.h"
|
#include "bacnet/datalink/datalink.h"
|
||||||
#include "bacnet/datalink/dlenv.h"
|
#include "bacnet/datalink/dlenv.h"
|
||||||
#include "bacnet/datalink/dlmstp.h"
|
#include "bacnet/datalink/dlmstp.h"
|
||||||
|
#include "bacfile-posix.h"
|
||||||
|
|
||||||
/* enable debugging */
|
/* enable debugging */
|
||||||
static bool Datalink_Debug;
|
static bool Datalink_Debug;
|
||||||
@@ -989,6 +990,9 @@ void dlenv_init(void)
|
|||||||
port_type = PORT_TYPE_NON_BACNET;
|
port_type = PORT_TYPE_NON_BACNET;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
/* initialize the POSIX file objects */
|
||||||
|
bacfile_posix_init();
|
||||||
|
/* === Initialize the Network Port Object Here === */
|
||||||
Network_Port_Type_Set(Network_Port_Instance, port_type);
|
Network_Port_Type_Set(Network_Port_Instance, port_type);
|
||||||
switch (port_type) {
|
switch (port_type) {
|
||||||
case PORT_TYPE_BIP:
|
case PORT_TYPE_BIP:
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ string(REGEX REPLACE
|
|||||||
"/test"
|
"/test"
|
||||||
TST_DIR
|
TST_DIR
|
||||||
${CMAKE_CURRENT_SOURCE_DIR})
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
string(REGEX REPLACE
|
||||||
|
"/test/bacnet/[a-zA-Z_/-]*$"
|
||||||
|
"/ports"
|
||||||
|
PORTS_DIR
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
set(ZTST_DIR "${TST_DIR}/ztest/src")
|
set(ZTST_DIR "${TST_DIR}/ztest/src")
|
||||||
|
|
||||||
add_compile_definitions(
|
add_compile_definitions(
|
||||||
@@ -34,6 +39,7 @@ add_compile_definitions(
|
|||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${SRC_DIR}
|
${SRC_DIR}
|
||||||
|
${PORTS_DIR}/posix
|
||||||
${TST_DIR}/bacnet/basic/object/test
|
${TST_DIR}/bacnet/basic/object/test
|
||||||
${TST_DIR}/ztest/include
|
${TST_DIR}/ztest/include
|
||||||
)
|
)
|
||||||
@@ -80,6 +86,7 @@ add_executable(${PROJECT_NAME}
|
|||||||
${SRC_DIR}/bacnet/datalink/bvlc.c
|
${SRC_DIR}/bacnet/datalink/bvlc.c
|
||||||
${SRC_DIR}/bacnet/datalink/bvlc6.c
|
${SRC_DIR}/bacnet/datalink/bvlc6.c
|
||||||
${SRC_DIR}/bacnet/datalink/bsc/bsc-util.c
|
${SRC_DIR}/bacnet/datalink/bsc/bsc-util.c
|
||||||
|
${PORTS_DIR}/posix/bacfile-posix.c
|
||||||
# Test and test library files
|
# Test and test library files
|
||||||
${TST_DIR}/bacnet/basic/object/test/device_mock.c
|
${TST_DIR}/bacnet/basic/object/test/device_mock.c
|
||||||
${TST_DIR}/bacnet/basic/object/test/datetime_local.c
|
${TST_DIR}/bacnet/basic/object/test/datetime_local.c
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <bacnet/basic/object/netport.h>
|
#include <bacnet/basic/object/netport.h>
|
||||||
#include <bacnet/basic/object/sc_netport.h>
|
#include <bacnet/basic/object/sc_netport.h>
|
||||||
#include <bacnet/basic/object/bacfile.h>
|
#include <bacnet/basic/object/bacfile.h>
|
||||||
|
#include <bacfile-posix.h>
|
||||||
#include <property_test.h>
|
#include <property_test.h>
|
||||||
#ifndef BACDL_BSC
|
#ifndef BACDL_BSC
|
||||||
#define BACDL_BSC
|
#define BACDL_BSC
|
||||||
@@ -765,6 +766,7 @@ static void test_network_port_sc_certificates(void)
|
|||||||
zassert_true(count > 0, NULL);
|
zassert_true(count > 0, NULL);
|
||||||
|
|
||||||
bacfile_init();
|
bacfile_init();
|
||||||
|
bacfile_posix_init();
|
||||||
// CA certificate
|
// CA certificate
|
||||||
status = bacfile_create(BSC_ISSUER_CERTIFICATE_FILE_1_INSTANCE);
|
status = bacfile_create(BSC_ISSUER_CERTIFICATE_FILE_1_INSTANCE);
|
||||||
zassert_true(status, NULL);
|
zassert_true(status, NULL);
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ set(ZTST_DIR "${TST_DIR}/ztest/src")
|
|||||||
add_compile_definitions(
|
add_compile_definitions(
|
||||||
BIG_ENDIAN=0
|
BIG_ENDIAN=0
|
||||||
CONFIG_ZTEST=1
|
CONFIG_ZTEST=1
|
||||||
BACDL_BSC
|
|
||||||
MAX_BACFILES=4
|
MAX_BACFILES=4
|
||||||
|
BACFILE=1
|
||||||
BSC_CONF_WSURL_MAX_LEN=128
|
BSC_CONF_WSURL_MAX_LEN=128
|
||||||
BSC_CONF_WEBSOCKET_ERR_DESC_STR_MAX_LEN=128
|
BSC_CONF_WEBSOCKET_ERR_DESC_STR_MAX_LEN=128
|
||||||
BSC_CONF_HUB_FUNCTION_CONNECTIONS_NUM=3
|
BSC_CONF_HUB_FUNCTION_CONNECTIONS_NUM=3
|
||||||
@@ -47,6 +47,7 @@ add_compile_definitions(
|
|||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${SRC_DIR}
|
${SRC_DIR}
|
||||||
|
${PORTS_DIR}/posix
|
||||||
${TST_DIR}/ztest/include
|
${TST_DIR}/ztest/include
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -197,6 +198,7 @@ target_sources(${PROJECT_NAME} PRIVATE
|
|||||||
${SRC_DIR}/bacnet/timestamp.c
|
${SRC_DIR}/bacnet/timestamp.c
|
||||||
${SRC_DIR}/bacnet/weeklyschedule.c
|
${SRC_DIR}/bacnet/weeklyschedule.c
|
||||||
${SRC_DIR}/bacnet/wp.c
|
${SRC_DIR}/bacnet/wp.c
|
||||||
|
${PORTS_DIR}/posix/bacfile-posix.c
|
||||||
# Test and test library files
|
# Test and test library files
|
||||||
./src/main.c
|
./src/main.c
|
||||||
${TST_DIR}/bacnet/basic/object/test/device_mock.c
|
${TST_DIR}/bacnet/basic/object/test/device_mock.c
|
||||||
|
|||||||
@@ -23,7 +23,8 @@
|
|||||||
#include <bacnet/datalink/bsc/bsc-util.h>
|
#include <bacnet/datalink/bsc/bsc-util.h>
|
||||||
#include <bacnet/datalink/bsc/bsc-event.h>
|
#include <bacnet/datalink/bsc/bsc-event.h>
|
||||||
#include <bacnet/bacdef.h>
|
#include <bacnet/bacdef.h>
|
||||||
#include "bacnet/basic/sys/debug.h"
|
#include <bacnet/basic/sys/debug.h>
|
||||||
|
#include <bacfile-posix.h>
|
||||||
|
|
||||||
unsigned char ca_key[] = { 0x2d,
|
unsigned char ca_key[] = { 0x2d,
|
||||||
0x2d,
|
0x2d,
|
||||||
@@ -10004,6 +10005,7 @@ static void test_sc_parameters(void)
|
|||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
bacfile_init();
|
bacfile_init();
|
||||||
|
bacfile_posix_init();
|
||||||
netport_object_init(
|
netport_object_init(
|
||||||
SC_DATALINK_INSTANCE, ca_cert, sizeof(ca_cert), server_cert,
|
SC_DATALINK_INSTANCE, ca_cert, sizeof(ca_cert), server_cert,
|
||||||
sizeof(server_cert), server_key, sizeof(server_key),
|
sizeof(server_cert), server_key, sizeof(server_key),
|
||||||
@@ -10017,7 +10019,9 @@ static void test_sc_parameters(void)
|
|||||||
|
|
||||||
// check
|
// check
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
bsc_conf.ca_cert_chain_size, sizeof(ca_cert) + ZERO_BYTE, NULL);
|
bsc_conf.ca_cert_chain_size, sizeof(ca_cert) + ZERO_BYTE,
|
||||||
|
"ca_cert=%zu actual=%zu", bsc_conf.ca_cert_chain_size,
|
||||||
|
sizeof(ca_cert) + ZERO_BYTE);
|
||||||
zassert_mem_equal(bsc_conf.ca_cert_chain, ca_cert, sizeof(ca_cert), NULL);
|
zassert_mem_equal(bsc_conf.ca_cert_chain, ca_cert, sizeof(ca_cert), NULL);
|
||||||
zassert_equal(
|
zassert_equal(
|
||||||
bsc_conf.cert_chain_size, sizeof(server_cert) + ZERO_BYTE, NULL);
|
bsc_conf.cert_chain_size, sizeof(server_cert) + ZERO_BYTE, NULL);
|
||||||
@@ -10155,6 +10159,7 @@ static void test_sc_datalink(void)
|
|||||||
SC_NETPORT_DIRECT_SERVER_PORT);
|
SC_NETPORT_DIRECT_SERVER_PORT);
|
||||||
|
|
||||||
bacfile_init();
|
bacfile_init();
|
||||||
|
bacfile_posix_init();
|
||||||
netport_object_init(
|
netport_object_init(
|
||||||
SC_DATALINK_INSTANCE, ca_cert, sizeof(ca_cert), server_cert,
|
SC_DATALINK_INSTANCE, ca_cert, sizeof(ca_cert), server_cert,
|
||||||
sizeof(server_cert), server_key, sizeof(server_key),
|
sizeof(server_cert), server_key, sizeof(server_key),
|
||||||
|
|||||||
Reference in New Issue
Block a user