re-save line endings to LF for git
This commit is contained in:
+1228
-1228
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
# Visual C++ Express 2008
|
# Visual C++ Express 2008
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rdproperty", "rdproperty.vcproj", "{7AC60281-278A-4060-B900-A1343E438701}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rdproperty", "rdproperty.vcproj", "{7AC60281-278A-4060-B900-A1343E438701}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{7AC60281-278A-4060-B900-A1343E438701}.Debug|Win32.ActiveCfg = Debug|Win32
|
{7AC60281-278A-4060-B900-A1343E438701}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{7AC60281-278A-4060-B900-A1343E438701}.Debug|Win32.Build.0 = Debug|Win32
|
{7AC60281-278A-4060-B900-A1343E438701}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{7AC60281-278A-4060-B900-A1343E438701}.Release|Win32.ActiveCfg = Release|Win32
|
{7AC60281-278A-4060-B900-A1343E438701}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{7AC60281-278A-4060-B900-A1343E438701}.Release|Win32.Build.0 = Release|Win32
|
{7AC60281-278A-4060-B900-A1343E438701}.Release|Win32.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
# Visual C++ Express 2008
|
# Visual C++ Express 2008
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "readrange", "readrange.vcproj", "{6017A2EA-1296-4E67-995F-6344A3CC27C2}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "readrange", "readrange.vcproj", "{6017A2EA-1296-4E67-995F-6344A3CC27C2}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Debug|Win32.ActiveCfg = Debug|Win32
|
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Debug|Win32.Build.0 = Debug|Win32
|
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Release|Win32.ActiveCfg = Release|Win32
|
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Release|Win32.Build.0 = Release|Win32
|
{6017A2EA-1296-4E67-995F-6344A3CC27C2}.Release|Win32.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
+59
-59
@@ -1,59 +1,59 @@
|
|||||||
#Makefile to build BACnet Application for the GCC port
|
#Makefile to build BACnet Application for the GCC port
|
||||||
|
|
||||||
# tools - only if you need them.
|
# tools - only if you need them.
|
||||||
# Most platforms have this already defined
|
# Most platforms have this already defined
|
||||||
# CC = gcc
|
# CC = gcc
|
||||||
|
|
||||||
# Executable file name
|
# Executable file name
|
||||||
TARGET = bacroute
|
TARGET = bacroute
|
||||||
|
|
||||||
TARGET_BIN = ${TARGET}$(TARGET_EXT)
|
TARGET_BIN = ${TARGET}$(TARGET_EXT)
|
||||||
|
|
||||||
CFLAGS += -DPRINT_ENABLED=1
|
CFLAGS += -DPRINT_ENABLED=1
|
||||||
|
|
||||||
BACNET_SOURCE_DIR = ../../src
|
BACNET_SOURCE_DIR = ../../src
|
||||||
BACNET_HANDLER_DIR = ../handler
|
BACNET_HANDLER_DIR = ../handler
|
||||||
BACNET_OBJECT_DIR = ../object
|
BACNET_OBJECT_DIR = ../object
|
||||||
|
|
||||||
SRC = main.c \
|
SRC = main.c \
|
||||||
$(BACNET_OBJECT_DIR)/netport.c \
|
$(BACNET_OBJECT_DIR)/netport.c \
|
||||||
$(BACNET_OBJECT_DIR)/device-client.c
|
$(BACNET_OBJECT_DIR)/device-client.c
|
||||||
|
|
||||||
PORT_BIP6_SRC = \
|
PORT_BIP6_SRC = \
|
||||||
$(BACNET_PORT_DIR)/bip6.c \
|
$(BACNET_PORT_DIR)/bip6.c \
|
||||||
$(BACNET_SOURCE_DIR)/bvlc6.c \
|
$(BACNET_SOURCE_DIR)/bvlc6.c \
|
||||||
$(BACNET_HANDLER_DIR)/h_bbmd6.c \
|
$(BACNET_HANDLER_DIR)/h_bbmd6.c \
|
||||||
$(BACNET_SOURCE_DIR)/vmac.c
|
$(BACNET_SOURCE_DIR)/vmac.c
|
||||||
|
|
||||||
PORT_BIP_SRC = \
|
PORT_BIP_SRC = \
|
||||||
$(BACNET_PORT_DIR)/bip-init.c \
|
$(BACNET_PORT_DIR)/bip-init.c \
|
||||||
$(BACNET_SOURCE_DIR)/bvlc.c \
|
$(BACNET_SOURCE_DIR)/bvlc.c \
|
||||||
$(BACNET_SOURCE_DIR)/bip.c
|
$(BACNET_SOURCE_DIR)/bip.c
|
||||||
|
|
||||||
SRCS = ${SRC} ${PORT_BIP6_SRC} ${PORT_BIP_SRC}
|
SRCS = ${SRC} ${PORT_BIP6_SRC} ${PORT_BIP_SRC}
|
||||||
|
|
||||||
OBJS = ${SRCS:.c=.o}
|
OBJS = ${SRCS:.c=.o}
|
||||||
|
|
||||||
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
|
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
|
||||||
|
|
||||||
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
|
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
|
||||||
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
|
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
|
||||||
size $@
|
size $@
|
||||||
cp $@ ../../bin
|
cp $@ ../../bin
|
||||||
|
|
||||||
lib: ${BACNET_LIB_TARGET}
|
lib: ${BACNET_LIB_TARGET}
|
||||||
|
|
||||||
${BACNET_LIB_TARGET}:
|
${BACNET_LIB_TARGET}:
|
||||||
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
|
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
${CC} -c ${CFLAGS} $*.c -o $@
|
${CC} -c ${CFLAGS} $*.c -o $@
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
rm -f .depend
|
rm -f .depend
|
||||||
${CC} -MM ${CFLAGS} *.c >> .depend
|
${CC} -MM ${CFLAGS} *.c >> .depend
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
|
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
|
||||||
|
|
||||||
include: .depend
|
include: .depend
|
||||||
|
|||||||
+1253
-1253
File diff suppressed because it is too large
Load Diff
+40
-40
@@ -1,40 +1,40 @@
|
|||||||
#Makefile to build BACnet Application for the Linux Port
|
#Makefile to build BACnet Application for the Linux Port
|
||||||
|
|
||||||
# tools - only if you need them.
|
# tools - only if you need them.
|
||||||
# Most platforms have this already defined
|
# Most platforms have this already defined
|
||||||
# CC = gcc
|
# CC = gcc
|
||||||
|
|
||||||
# Executable file name
|
# Executable file name
|
||||||
TARGET = bacwpm
|
TARGET = bacwpm
|
||||||
|
|
||||||
TARGET_BIN = ${TARGET}$(TARGET_EXT)
|
TARGET_BIN = ${TARGET}$(TARGET_EXT)
|
||||||
|
|
||||||
SRCS = main.c \
|
SRCS = main.c \
|
||||||
../object/netport.c \
|
../object/netport.c \
|
||||||
../object/device-client.c
|
../object/device-client.c
|
||||||
|
|
||||||
OBJS = ${SRCS:.c=.o}
|
OBJS = ${SRCS:.c=.o}
|
||||||
|
|
||||||
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
|
all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
|
||||||
|
|
||||||
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
|
${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
|
||||||
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
|
${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
|
||||||
size $@
|
size $@
|
||||||
cp $@ ../../bin
|
cp $@ ../../bin
|
||||||
|
|
||||||
lib: ${BACNET_LIB_TARGET}
|
lib: ${BACNET_LIB_TARGET}
|
||||||
|
|
||||||
${BACNET_LIB_TARGET}:
|
${BACNET_LIB_TARGET}:
|
||||||
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
|
( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
${CC} -c ${CFLAGS} $*.c -o $@
|
${CC} -c ${CFLAGS} $*.c -o $@
|
||||||
|
|
||||||
depend:
|
depend:
|
||||||
rm -f .depend
|
rm -f .depend
|
||||||
${CC} -MM ${CFLAGS} *.c >> .depend
|
${CC} -MM ${CFLAGS} *.c >> .depend
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
|
rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
|
||||||
|
|
||||||
include: .depend
|
include: .depend
|
||||||
|
|||||||
+522
-522
File diff suppressed because it is too large
Load Diff
+87
-87
@@ -1,87 +1,87 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @author Steve Karg
|
* @author Steve Karg
|
||||||
* @date 2015
|
* @date 2015
|
||||||
* @defgroup DLBIP6 BACnet/IPv6 DataLink Network Layer
|
* @defgroup DLBIP6 BACnet/IPv6 DataLink Network Layer
|
||||||
* @ingroup DataLink
|
* @ingroup DataLink
|
||||||
*
|
*
|
||||||
* Implementation of the Network Layer using BACnet/IPv6 as the transport, as
|
* Implementation of the Network Layer using BACnet/IPv6 as the transport, as
|
||||||
* described in Annex J.
|
* described in Annex J.
|
||||||
* The functions described here fulfill the roles defined generically at the
|
* The functions described here fulfill the roles defined generically at the
|
||||||
* DataLink level by serving as the implementation of the function templates.
|
* DataLink level by serving as the implementation of the function templates.
|
||||||
*/
|
*/
|
||||||
#ifndef BIP6_H
|
#ifndef BIP6_H
|
||||||
#define BIP6_H
|
#define BIP6_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
#include "bvlc6.h"
|
#include "bvlc6.h"
|
||||||
|
|
||||||
/* specific defines for BACnet/IP over Ethernet */
|
/* specific defines for BACnet/IP over Ethernet */
|
||||||
#define BIP6_HEADER_MAX (1 + 1 + 2)
|
#define BIP6_HEADER_MAX (1 + 1 + 2)
|
||||||
#define BIP6_MPDU_MAX (BIP6_HEADER_MAX+MAX_PDU)
|
#define BIP6_MPDU_MAX (BIP6_HEADER_MAX+MAX_PDU)
|
||||||
/* for legacy demo applications */
|
/* for legacy demo applications */
|
||||||
#define MAX_MPDU BIP6_MPDU_MAX
|
#define MAX_MPDU BIP6_MPDU_MAX
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* 6 datalink functions used by demo handlers and applications:
|
/* 6 datalink functions used by demo handlers and applications:
|
||||||
init, send, receive, cleanup, unicast/broadcast address.
|
init, send, receive, cleanup, unicast/broadcast address.
|
||||||
Note: the addresses used here are VMAC addresses. */
|
Note: the addresses used here are VMAC addresses. */
|
||||||
bool bip6_init(
|
bool bip6_init(
|
||||||
char *ifname);
|
char *ifname);
|
||||||
void bip6_cleanup(
|
void bip6_cleanup(
|
||||||
void);
|
void);
|
||||||
void bip6_get_broadcast_address(
|
void bip6_get_broadcast_address(
|
||||||
BACNET_ADDRESS * my_address);
|
BACNET_ADDRESS * my_address);
|
||||||
void bip6_get_my_address(
|
void bip6_get_my_address(
|
||||||
BACNET_ADDRESS * my_address);
|
BACNET_ADDRESS * my_address);
|
||||||
int bip6_send_pdu(
|
int bip6_send_pdu(
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_ADDRESS * dest,
|
||||||
BACNET_NPDU_DATA * npdu_data,
|
BACNET_NPDU_DATA * npdu_data,
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
unsigned pdu_len);
|
unsigned pdu_len);
|
||||||
uint16_t bip6_receive(
|
uint16_t bip6_receive(
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t max_pdu,
|
uint16_t max_pdu,
|
||||||
unsigned timeout);
|
unsigned timeout);
|
||||||
|
|
||||||
/* functions that are custom per port */
|
/* functions that are custom per port */
|
||||||
void bip6_set_interface(
|
void bip6_set_interface(
|
||||||
char *ifname);
|
char *ifname);
|
||||||
|
|
||||||
bool bip6_address_match_self(
|
bool bip6_address_match_self(
|
||||||
BACNET_IP6_ADDRESS *addr);
|
BACNET_IP6_ADDRESS *addr);
|
||||||
|
|
||||||
bool bip6_set_addr(
|
bool bip6_set_addr(
|
||||||
BACNET_IP6_ADDRESS *addr);
|
BACNET_IP6_ADDRESS *addr);
|
||||||
bool bip6_get_addr(
|
bool bip6_get_addr(
|
||||||
BACNET_IP6_ADDRESS *addr);
|
BACNET_IP6_ADDRESS *addr);
|
||||||
|
|
||||||
void bip6_set_port(
|
void bip6_set_port(
|
||||||
uint16_t port);
|
uint16_t port);
|
||||||
uint16_t bip6_get_port(
|
uint16_t bip6_get_port(
|
||||||
void);
|
void);
|
||||||
|
|
||||||
bool bip6_set_broadcast_addr(
|
bool bip6_set_broadcast_addr(
|
||||||
BACNET_IP6_ADDRESS *addr);
|
BACNET_IP6_ADDRESS *addr);
|
||||||
/* returns network byte order */
|
/* returns network byte order */
|
||||||
bool bip6_get_broadcast_addr(
|
bool bip6_get_broadcast_addr(
|
||||||
BACNET_IP6_ADDRESS *addr);
|
BACNET_IP6_ADDRESS *addr);
|
||||||
|
|
||||||
int bip6_send_mpdu(
|
int bip6_send_mpdu(
|
||||||
BACNET_IP6_ADDRESS *addr,
|
BACNET_IP6_ADDRESS *addr,
|
||||||
uint8_t * mtu,
|
uint8_t * mtu,
|
||||||
uint16_t mtu_len);
|
uint16_t mtu_len);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+403
-403
@@ -1,403 +1,403 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @author Steve Karg
|
* @author Steve Karg
|
||||||
* @date 2015
|
* @date 2015
|
||||||
*
|
*
|
||||||
* Implementation of the BACnet Virtual Link Layer using IPv6,
|
* Implementation of the BACnet Virtual Link Layer using IPv6,
|
||||||
* as described in Annex J.
|
* as described in Annex J.
|
||||||
*/
|
*/
|
||||||
#ifndef BVLC6_H
|
#ifndef BVLC6_H
|
||||||
#define BVLC6_H
|
#define BVLC6_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BVLL for BACnet/IPv6
|
* BVLL for BACnet/IPv6
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define BVLL_TYPE_BACNET_IP6 (0x82)
|
#define BVLL_TYPE_BACNET_IP6 (0x82)
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* B/IPv6 BVLL Messages
|
* B/IPv6 BVLL Messages
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define BVLC6_RESULT 0x00
|
#define BVLC6_RESULT 0x00
|
||||||
#define BVLC6_ORIGINAL_UNICAST_NPDU 0x01
|
#define BVLC6_ORIGINAL_UNICAST_NPDU 0x01
|
||||||
#define BVLC6_ORIGINAL_BROADCAST_NPDU 0x02
|
#define BVLC6_ORIGINAL_BROADCAST_NPDU 0x02
|
||||||
#define BVLC6_ADDRESS_RESOLUTION 0x03
|
#define BVLC6_ADDRESS_RESOLUTION 0x03
|
||||||
#define BVLC6_FORWARDED_ADDRESS_RESOLUTION 0x04
|
#define BVLC6_FORWARDED_ADDRESS_RESOLUTION 0x04
|
||||||
#define BVLC6_ADDRESS_RESOLUTION_ACK 0x05
|
#define BVLC6_ADDRESS_RESOLUTION_ACK 0x05
|
||||||
#define BVLC6_VIRTUAL_ADDRESS_RESOLUTION 0x06
|
#define BVLC6_VIRTUAL_ADDRESS_RESOLUTION 0x06
|
||||||
#define BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK 0x07
|
#define BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK 0x07
|
||||||
#define BVLC6_FORWARDED_NPDU 0x08
|
#define BVLC6_FORWARDED_NPDU 0x08
|
||||||
#define BVLC6_REGISTER_FOREIGN_DEVICE 0x09
|
#define BVLC6_REGISTER_FOREIGN_DEVICE 0x09
|
||||||
#define BVLC6_DELETE_FOREIGN_DEVICE 0x0A
|
#define BVLC6_DELETE_FOREIGN_DEVICE 0x0A
|
||||||
#define BVLC6_SECURE_BVLL 0x0B
|
#define BVLC6_SECURE_BVLL 0x0B
|
||||||
#define BVLC6_DISTRIBUTE_BROADCAST_TO_NETWORK 0x0C
|
#define BVLC6_DISTRIBUTE_BROADCAST_TO_NETWORK 0x0C
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BVLC Result Code
|
* BVLC Result Code
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define BVLC6_RESULT_SUCCESSFUL_COMPLETION 0x0000
|
#define BVLC6_RESULT_SUCCESSFUL_COMPLETION 0x0000
|
||||||
#define BVLC6_RESULT_ADDRESS_RESOLUTION_NAK 0x0030
|
#define BVLC6_RESULT_ADDRESS_RESOLUTION_NAK 0x0030
|
||||||
#define BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK 0x0060
|
#define BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK 0x0060
|
||||||
#define BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK 0x0090
|
#define BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK 0x0090
|
||||||
#define BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK 0x00A0
|
#define BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK 0x00A0
|
||||||
#define BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK 0x00C0
|
#define BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK 0x00C0
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BACnet IPv6 Multicast Group ID
|
* BACnet IPv6 Multicast Group ID
|
||||||
* BACnet broadcast messages shall be delivered by IPv6 multicasts
|
* BACnet broadcast messages shall be delivered by IPv6 multicasts
|
||||||
* as opposed to using IP broadcasting. Broadcasting in
|
* as opposed to using IP broadcasting. Broadcasting in
|
||||||
* IPv6 is subsumed by multicasting to the all-nodes link
|
* IPv6 is subsumed by multicasting to the all-nodes link
|
||||||
* group FF02::1; however, the use of the all-nodes group is not
|
* group FF02::1; however, the use of the all-nodes group is not
|
||||||
* recommended, and BACnet/IPv6 uses an IANA permanently assigned
|
* recommended, and BACnet/IPv6 uses an IANA permanently assigned
|
||||||
* multicast group identifier to avoid disturbing
|
* multicast group identifier to avoid disturbing
|
||||||
* every interface in the network.
|
* every interface in the network.
|
||||||
*
|
*
|
||||||
* The IANA assigned BACnet/IPv6 variable scope multicast address
|
* The IANA assigned BACnet/IPv6 variable scope multicast address
|
||||||
* is FF0X:0:0:0:0:0:0:BAC0 (FF0X::BAC0) which indicates the multicast
|
* is FF0X:0:0:0:0:0:0:BAC0 (FF0X::BAC0) which indicates the multicast
|
||||||
* group identifier X'BAC0'. The following multicast scopes are
|
* group identifier X'BAC0'. The following multicast scopes are
|
||||||
* defined for B/IPv6.
|
* defined for B/IPv6.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define BIP6_MULTICAST_GROUP_ID 0xBAC0
|
#define BIP6_MULTICAST_GROUP_ID 0xBAC0
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IANA prefixes
|
* IANA prefixes
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define BIP6_MULTICAST_reserved_0 0xFF00
|
#define BIP6_MULTICAST_reserved_0 0xFF00
|
||||||
#define BIP6_MULTICAST_NODE_LOCAL 0xFF01
|
#define BIP6_MULTICAST_NODE_LOCAL 0xFF01
|
||||||
#define BIP6_MULTICAST_LINK_LOCAL 0xFF02
|
#define BIP6_MULTICAST_LINK_LOCAL 0xFF02
|
||||||
#define BIP6_MULTICAST_reserved_3 0xFF03
|
#define BIP6_MULTICAST_reserved_3 0xFF03
|
||||||
#define BIP6_MULTICAST_ADMIN_LOCAL 0xFF04
|
#define BIP6_MULTICAST_ADMIN_LOCAL 0xFF04
|
||||||
#define BIP6_MULTICAST_SITE_LOCAL 0xFF05
|
#define BIP6_MULTICAST_SITE_LOCAL 0xFF05
|
||||||
#define BIP6_MULTICAST_ORG_LOCAL 0xFF08
|
#define BIP6_MULTICAST_ORG_LOCAL 0xFF08
|
||||||
#define BIP6_MULTICAST_GLOBAL 0xFF0E
|
#define BIP6_MULTICAST_GLOBAL 0xFF0E
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/* number of bytes in the IPv6 address */
|
/* number of bytes in the IPv6 address */
|
||||||
#define IP6_ADDRESS_MAX 16
|
#define IP6_ADDRESS_MAX 16
|
||||||
/* number of bytes in the B/IPv6 address */
|
/* number of bytes in the B/IPv6 address */
|
||||||
#define BIP6_ADDRESS_MAX 18
|
#define BIP6_ADDRESS_MAX 18
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BACnet IPv6 Address
|
* BACnet IPv6 Address
|
||||||
*
|
*
|
||||||
* Data link layer addressing between B/IPv6 nodes consists of a 128-bit
|
* Data link layer addressing between B/IPv6 nodes consists of a 128-bit
|
||||||
* IPv6 address followed by a two-octet UDP port number (both of which
|
* IPv6 address followed by a two-octet UDP port number (both of which
|
||||||
* shall be transmitted with the most significant octet first).
|
* shall be transmitted with the most significant octet first).
|
||||||
* This address shall be referred to as a B/IPv6 address.
|
* This address shall be referred to as a B/IPv6 address.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
typedef struct BACnet_IP6_Address {
|
typedef struct BACnet_IP6_Address {
|
||||||
uint8_t address[IP6_ADDRESS_MAX];
|
uint8_t address[IP6_ADDRESS_MAX];
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
} BACNET_IP6_ADDRESS;
|
} BACNET_IP6_ADDRESS;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BACnet /IPv6 Broadcast Distribution Table Format
|
* BACnet /IPv6 Broadcast Distribution Table Format
|
||||||
*
|
*
|
||||||
* The BDT shall consist of either the eighteen-octet B/IPv6 address
|
* The BDT shall consist of either the eighteen-octet B/IPv6 address
|
||||||
* of the peer BBMD or the combination of the fully qualified
|
* of the peer BBMD or the combination of the fully qualified
|
||||||
* domain name service (DNS) entry and UDP port that resolves to
|
* domain name service (DNS) entry and UDP port that resolves to
|
||||||
* the B/IPv6 address of the peer BBMD. The Broadcast
|
* the B/IPv6 address of the peer BBMD. The Broadcast
|
||||||
* Distribution Table shall not contain an entry for the BBMD in
|
* Distribution Table shall not contain an entry for the BBMD in
|
||||||
* which the BDT resides.
|
* which the BDT resides.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
struct BACnet_IP6_Broadcast_Distribution_Table_Entry;
|
struct BACnet_IP6_Broadcast_Distribution_Table_Entry;
|
||||||
typedef struct BACnet_IP6_Broadcast_Distribution_Table_Entry {
|
typedef struct BACnet_IP6_Broadcast_Distribution_Table_Entry {
|
||||||
/* true if valid entry - false if not */
|
/* true if valid entry - false if not */
|
||||||
bool valid;
|
bool valid;
|
||||||
/* BACnet/IPv6 address */
|
/* BACnet/IPv6 address */
|
||||||
BACNET_IP6_ADDRESS bip6_address;
|
BACNET_IP6_ADDRESS bip6_address;
|
||||||
struct BACnet_IP6_Broadcast_Distribution_Table_Entry *next;
|
struct BACnet_IP6_Broadcast_Distribution_Table_Entry *next;
|
||||||
} BACNET_IP6_BROADCAST_DISTRIBUTION_TABLE_ENTRY;
|
} BACNET_IP6_BROADCAST_DISTRIBUTION_TABLE_ENTRY;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Foreign Device Table (FDT)
|
* Foreign Device Table (FDT)
|
||||||
*
|
*
|
||||||
* Each entry shall contain the B/IPv6 address and the TTL of the
|
* Each entry shall contain the B/IPv6 address and the TTL of the
|
||||||
* registered foreign device.
|
* registered foreign device.
|
||||||
*
|
*
|
||||||
* Each entry shall consist of the eighteen-octet B/IPv6 address of the
|
* Each entry shall consist of the eighteen-octet B/IPv6 address of the
|
||||||
* registrant; the 2-octet Time-to-Live value supplied at the time of
|
* registrant; the 2-octet Time-to-Live value supplied at the time of
|
||||||
* registration; and a 2-octet value representing the number of seconds
|
* registration; and a 2-octet value representing the number of seconds
|
||||||
* remaining before the BBMD will purge the registrant's FDT entry if no
|
* remaining before the BBMD will purge the registrant's FDT entry if no
|
||||||
* re-registration occurs. The number of seconds remaining shall be
|
* re-registration occurs. The number of seconds remaining shall be
|
||||||
* initialized to the 2-octet Time-to-Live value supplied at the time
|
* initialized to the 2-octet Time-to-Live value supplied at the time
|
||||||
* of registration plus 30 seconds (see U.4.5.2), with a maximum of 65535.
|
* of registration plus 30 seconds (see U.4.5.2), with a maximum of 65535.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
struct BACnet_IP6_Foreign_Device_Table_Entry;
|
struct BACnet_IP6_Foreign_Device_Table_Entry;
|
||||||
typedef struct BACnet_IP6_Foreign_Device_Table_Entry {
|
typedef struct BACnet_IP6_Foreign_Device_Table_Entry {
|
||||||
/* true if valid entry - false if not */
|
/* true if valid entry - false if not */
|
||||||
bool valid;
|
bool valid;
|
||||||
/* BACnet/IPv6 address */
|
/* BACnet/IPv6 address */
|
||||||
BACNET_IP6_ADDRESS bip6_address;
|
BACNET_IP6_ADDRESS bip6_address;
|
||||||
/* requested time-to-live value */
|
/* requested time-to-live value */
|
||||||
uint16_t ttl_seconds;
|
uint16_t ttl_seconds;
|
||||||
/* number of seconds remaining */
|
/* number of seconds remaining */
|
||||||
uint16_t ttl_seconds_remaining;
|
uint16_t ttl_seconds_remaining;
|
||||||
struct BACnet_IP6_Foreign_Device_Table_Entry *next;
|
struct BACnet_IP6_Foreign_Device_Table_Entry *next;
|
||||||
} BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY;
|
} BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY;
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
int bvlc6_encode_address(
|
int bvlc6_encode_address(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
BACNET_IP6_ADDRESS * ip6_address);
|
BACNET_IP6_ADDRESS * ip6_address);
|
||||||
int bvlc6_decode_address(
|
int bvlc6_decode_address(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
BACNET_IP6_ADDRESS * ip6_address);
|
BACNET_IP6_ADDRESS * ip6_address);
|
||||||
bool bvlc6_address_copy(
|
bool bvlc6_address_copy(
|
||||||
BACNET_IP6_ADDRESS * dst,
|
BACNET_IP6_ADDRESS * dst,
|
||||||
BACNET_IP6_ADDRESS * src);
|
BACNET_IP6_ADDRESS * src);
|
||||||
bool bvlc6_address_different(
|
bool bvlc6_address_different(
|
||||||
BACNET_IP6_ADDRESS * dst,
|
BACNET_IP6_ADDRESS * dst,
|
||||||
BACNET_IP6_ADDRESS * src);
|
BACNET_IP6_ADDRESS * src);
|
||||||
|
|
||||||
bool bvlc6_address_set(
|
bool bvlc6_address_set(
|
||||||
BACNET_IP6_ADDRESS * addr,
|
BACNET_IP6_ADDRESS * addr,
|
||||||
uint16_t addr0,
|
uint16_t addr0,
|
||||||
uint16_t addr1,
|
uint16_t addr1,
|
||||||
uint16_t addr2,
|
uint16_t addr2,
|
||||||
uint16_t addr3,
|
uint16_t addr3,
|
||||||
uint16_t addr4,
|
uint16_t addr4,
|
||||||
uint16_t addr5,
|
uint16_t addr5,
|
||||||
uint16_t addr6,
|
uint16_t addr6,
|
||||||
uint16_t addr7);
|
uint16_t addr7);
|
||||||
bool bvlc6_address_get(
|
bool bvlc6_address_get(
|
||||||
BACNET_IP6_ADDRESS * addr,
|
BACNET_IP6_ADDRESS * addr,
|
||||||
uint16_t *addr0,
|
uint16_t *addr0,
|
||||||
uint16_t *addr1,
|
uint16_t *addr1,
|
||||||
uint16_t *addr2,
|
uint16_t *addr2,
|
||||||
uint16_t *addr3,
|
uint16_t *addr3,
|
||||||
uint16_t *addr4,
|
uint16_t *addr4,
|
||||||
uint16_t *addr5,
|
uint16_t *addr5,
|
||||||
uint16_t *addr6,
|
uint16_t *addr6,
|
||||||
uint16_t *addr7);
|
uint16_t *addr7);
|
||||||
|
|
||||||
bool bvlc6_vmac_address_set(
|
bool bvlc6_vmac_address_set(
|
||||||
BACNET_ADDRESS * addr,
|
BACNET_ADDRESS * addr,
|
||||||
uint32_t device_id);
|
uint32_t device_id);
|
||||||
bool bvlc6_vmac_address_get(
|
bool bvlc6_vmac_address_get(
|
||||||
BACNET_ADDRESS * addr,
|
BACNET_ADDRESS * addr,
|
||||||
uint32_t *device_id);
|
uint32_t *device_id);
|
||||||
|
|
||||||
int bvlc6_encode_header(
|
int bvlc6_encode_header(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint8_t message_type,
|
uint8_t message_type,
|
||||||
uint16_t length);
|
uint16_t length);
|
||||||
int bvlc6_decode_header(
|
int bvlc6_decode_header(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint8_t * message_type,
|
uint8_t * message_type,
|
||||||
uint16_t * length);
|
uint16_t * length);
|
||||||
|
|
||||||
int bvlc6_encode_result(
|
int bvlc6_encode_result(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac,
|
uint32_t vmac,
|
||||||
uint16_t result_code);
|
uint16_t result_code);
|
||||||
int bvlc6_decode_result(
|
int bvlc6_decode_result(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac,
|
uint32_t * vmac,
|
||||||
uint16_t * result_code);
|
uint16_t * result_code);
|
||||||
|
|
||||||
int bvlc6_encode_original_unicast(
|
int bvlc6_encode_original_unicast(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint32_t vmac_dst,
|
uint32_t vmac_dst,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_len);
|
uint16_t npdu_len);
|
||||||
int bvlc6_decode_original_unicast(
|
int bvlc6_decode_original_unicast(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
uint32_t * vmac_dst,
|
uint32_t * vmac_dst,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_size,
|
uint16_t npdu_size,
|
||||||
uint16_t * npdu_len);
|
uint16_t * npdu_len);
|
||||||
|
|
||||||
int bvlc6_encode_original_broadcast(
|
int bvlc6_encode_original_broadcast(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac,
|
uint32_t vmac,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_len);
|
uint16_t npdu_len);
|
||||||
int bvlc6_decode_original_broadcast(
|
int bvlc6_decode_original_broadcast(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac,
|
uint32_t * vmac,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_size,
|
uint16_t npdu_size,
|
||||||
uint16_t * npdu_len);
|
uint16_t * npdu_len);
|
||||||
|
|
||||||
int bvlc6_encode_address_resolution(
|
int bvlc6_encode_address_resolution(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint32_t vmac_target);
|
uint32_t vmac_target);
|
||||||
int bvlc6_decode_address_resolution(
|
int bvlc6_decode_address_resolution(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
uint32_t * vmac_target);
|
uint32_t * vmac_target);
|
||||||
|
|
||||||
int bvlc6_encode_forwarded_address_resolution(
|
int bvlc6_encode_forwarded_address_resolution(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint32_t vmac_target,
|
uint32_t vmac_target,
|
||||||
BACNET_IP6_ADDRESS * bip6_address);
|
BACNET_IP6_ADDRESS * bip6_address);
|
||||||
int bvlc6_decode_forwarded_address_resolution(
|
int bvlc6_decode_forwarded_address_resolution(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
uint32_t * vmac_target,
|
uint32_t * vmac_target,
|
||||||
BACNET_IP6_ADDRESS * bip6_address);
|
BACNET_IP6_ADDRESS * bip6_address);
|
||||||
|
|
||||||
int bvlc6_encode_address_resolution_ack(
|
int bvlc6_encode_address_resolution_ack(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint32_t vmac_dst);
|
uint32_t vmac_dst);
|
||||||
int bvlc6_decode_address_resolution_ack(
|
int bvlc6_decode_address_resolution_ack(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
uint32_t * vmac_dst);
|
uint32_t * vmac_dst);
|
||||||
|
|
||||||
int bvlc6_encode_virtual_address_resolution(
|
int bvlc6_encode_virtual_address_resolution(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src);
|
uint32_t vmac_src);
|
||||||
int bvlc6_decode_virtual_address_resolution(
|
int bvlc6_decode_virtual_address_resolution(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src);
|
uint32_t * vmac_src);
|
||||||
|
|
||||||
int bvlc6_encode_virtual_address_resolution_ack(
|
int bvlc6_encode_virtual_address_resolution_ack(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint32_t vmac_dst);
|
uint32_t vmac_dst);
|
||||||
int bvlc6_decode_virtual_address_resolution_ack(
|
int bvlc6_decode_virtual_address_resolution_ack(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
uint32_t * vmac_dst);
|
uint32_t * vmac_dst);
|
||||||
|
|
||||||
int bvlc6_encode_forwarded_npdu(
|
int bvlc6_encode_forwarded_npdu(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
BACNET_IP6_ADDRESS * address,
|
BACNET_IP6_ADDRESS * address,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_len);
|
uint16_t npdu_len);
|
||||||
int bvlc6_decode_forwarded_npdu(
|
int bvlc6_decode_forwarded_npdu(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
BACNET_IP6_ADDRESS * address,
|
BACNET_IP6_ADDRESS * address,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_size,
|
uint16_t npdu_size,
|
||||||
uint16_t * npdu_len);
|
uint16_t * npdu_len);
|
||||||
|
|
||||||
int bvlc6_encode_register_foreign_device(
|
int bvlc6_encode_register_foreign_device(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint16_t ttl_seconds);
|
uint16_t ttl_seconds);
|
||||||
int bvlc6_decode_register_foreign_device(
|
int bvlc6_decode_register_foreign_device(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
uint16_t * ttl_seconds);
|
uint16_t * ttl_seconds);
|
||||||
|
|
||||||
int bvlc6_encode_delete_foreign_device(
|
int bvlc6_encode_delete_foreign_device(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY * fdt_entry);
|
BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY * fdt_entry);
|
||||||
int bvlc6_decode_delete_foreign_device(
|
int bvlc6_decode_delete_foreign_device(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac_src,
|
uint32_t * vmac_src,
|
||||||
BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY * fdt_entry);
|
BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY * fdt_entry);
|
||||||
|
|
||||||
int bvlc6_encode_secure_bvll(
|
int bvlc6_encode_secure_bvll(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint8_t * sbuf,
|
uint8_t * sbuf,
|
||||||
uint16_t sbuf_len);
|
uint16_t sbuf_len);
|
||||||
int bvlc6_decode_secure_bvll(
|
int bvlc6_decode_secure_bvll(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint8_t * sbuf,
|
uint8_t * sbuf,
|
||||||
uint16_t sbuf_size,
|
uint16_t sbuf_size,
|
||||||
uint16_t * sbuf_len);
|
uint16_t * sbuf_len);
|
||||||
|
|
||||||
int bvlc6_encode_distribute_broadcast_to_network(
|
int bvlc6_encode_distribute_broadcast_to_network(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_size,
|
uint16_t pdu_size,
|
||||||
uint32_t vmac,
|
uint32_t vmac,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_len);
|
uint16_t npdu_len);
|
||||||
int bvlc6_decode_distribute_broadcast_to_network(
|
int bvlc6_decode_distribute_broadcast_to_network(
|
||||||
uint8_t * pdu,
|
uint8_t * pdu,
|
||||||
uint16_t pdu_len,
|
uint16_t pdu_len,
|
||||||
uint32_t * vmac,
|
uint32_t * vmac,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_size,
|
uint16_t npdu_size,
|
||||||
uint16_t * npdu_len);
|
uint16_t * npdu_len);
|
||||||
|
|
||||||
/* user application function prototypes */
|
/* user application function prototypes */
|
||||||
int bvlc6_handler(
|
int bvlc6_handler(
|
||||||
BACNET_IP6_ADDRESS *addr,
|
BACNET_IP6_ADDRESS *addr,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t npdu_len);
|
uint16_t npdu_len);
|
||||||
int bvlc6_register_with_bbmd(
|
int bvlc6_register_with_bbmd(
|
||||||
BACNET_IP6_ADDRESS *bbmd_addr,
|
BACNET_IP6_ADDRESS *bbmd_addr,
|
||||||
uint32_t vmac_src,
|
uint32_t vmac_src,
|
||||||
uint16_t time_to_live_seconds);
|
uint16_t time_to_live_seconds);
|
||||||
uint16_t bvlc6_get_last_result(
|
uint16_t bvlc6_get_last_result(
|
||||||
void);
|
void);
|
||||||
uint8_t bvlc6_get_function_code(
|
uint8_t bvlc6_get_function_code(
|
||||||
void);
|
void);
|
||||||
void bvlc6_init(void);
|
void bvlc6_init(void);
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
void test_BVLC6(
|
void test_BVLC6(
|
||||||
Test * pTest);
|
Test * pTest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
#endif /* */
|
#endif /* */
|
||||||
|
|||||||
+52
-52
@@ -1,52 +1,52 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @author Steve Karg
|
* @author Steve Karg
|
||||||
* @date 2016
|
* @date 2016
|
||||||
*/
|
*/
|
||||||
#ifndef VMAC_H
|
#ifndef VMAC_H
|
||||||
#define VMAC_H
|
#define VMAC_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
/* define the max MAC as big as IPv6 + port number */
|
/* define the max MAC as big as IPv6 + port number */
|
||||||
#define VMAC_MAC_MAX 18
|
#define VMAC_MAC_MAX 18
|
||||||
/**
|
/**
|
||||||
* VMAC data structure
|
* VMAC data structure
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
struct vmac_data {
|
struct vmac_data {
|
||||||
uint8_t mac[18];
|
uint8_t mac[18];
|
||||||
uint8_t mac_len;
|
uint8_t mac_len;
|
||||||
};
|
};
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
unsigned int VMAC_Count(void);
|
unsigned int VMAC_Count(void);
|
||||||
struct vmac_data *VMAC_Find_By_Key(uint32_t device_id);
|
struct vmac_data *VMAC_Find_By_Key(uint32_t device_id);
|
||||||
bool VMAC_Find_By_Data(struct vmac_data *vmac, uint32_t *device_id);
|
bool VMAC_Find_By_Data(struct vmac_data *vmac, uint32_t *device_id);
|
||||||
bool VMAC_Add(uint32_t device_id, struct vmac_data *pVMAC);
|
bool VMAC_Add(uint32_t device_id, struct vmac_data *pVMAC);
|
||||||
bool VMAC_Delete(uint32_t device_id);
|
bool VMAC_Delete(uint32_t device_id);
|
||||||
bool VMAC_Different(
|
bool VMAC_Different(
|
||||||
struct vmac_data *vmac1,
|
struct vmac_data *vmac1,
|
||||||
struct vmac_data *vmac2);
|
struct vmac_data *vmac2);
|
||||||
bool VMAC_Match(
|
bool VMAC_Match(
|
||||||
struct vmac_data *vmac1,
|
struct vmac_data *vmac1,
|
||||||
struct vmac_data *vmac2);
|
struct vmac_data *vmac2);
|
||||||
void VMAC_Cleanup(void);
|
void VMAC_Cleanup(void);
|
||||||
void VMAC_Init(void);
|
void VMAC_Init(void);
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
void testVMAC(
|
void testVMAC(
|
||||||
Test * pTest);
|
Test * pTest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+117
-117
@@ -1,117 +1,117 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2012 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
* "Software"), to deal in the Software without restriction, including
|
* "Software"), to deal in the Software without restriction, including
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
* in all copies or substantial portions of the Software.
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#ifndef BIP_H
|
#ifndef BIP_H
|
||||||
#define BIP_H
|
#define BIP_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
|
|
||||||
/* specific defines for BACnet/IP over Ethernet */
|
/* specific defines for BACnet/IP over Ethernet */
|
||||||
#define MAX_HEADER (1 + 1 + 2)
|
#define MAX_HEADER (1 + 1 + 2)
|
||||||
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
|
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
|
||||||
|
|
||||||
#define BVLL_TYPE_BACNET_IP (0x81)
|
#define BVLL_TYPE_BACNET_IP (0x81)
|
||||||
|
|
||||||
extern bool BIP_Debug;
|
extern bool BIP_Debug;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* note: define init, set_interface, and cleanup in your port */
|
/* note: define init, set_interface, and cleanup in your port */
|
||||||
/* on Linux, ifname is eth0, ath0, arc0, and others.
|
/* on Linux, ifname is eth0, ath0, arc0, and others.
|
||||||
on Windows, ifname is the dotted ip address of the interface */
|
on Windows, ifname is the dotted ip address of the interface */
|
||||||
bool bip_init(char *ifname);
|
bool bip_init(char *ifname);
|
||||||
void bip_set_interface(char *ifname);
|
void bip_set_interface(char *ifname);
|
||||||
void bip_cleanup(void);
|
void bip_cleanup(void);
|
||||||
|
|
||||||
/* Convert uint8_t IPv4 to uint32 */
|
/* Convert uint8_t IPv4 to uint32 */
|
||||||
uint32_t convertBIP_Address2uint32(uint8_t * bip_address);
|
uint32_t convertBIP_Address2uint32(uint8_t * bip_address);
|
||||||
void convertUint32Address_2_uint8Address(uint32_t ip,
|
void convertUint32Address_2_uint8Address(uint32_t ip,
|
||||||
uint8_t * address);
|
uint8_t * address);
|
||||||
/* common BACnet/IP functions */
|
/* common BACnet/IP functions */
|
||||||
void bip_set_socket(uint8_t sock_fd);
|
void bip_set_socket(uint8_t sock_fd);
|
||||||
uint8_t bip_socket(void);
|
uint8_t bip_socket(void);
|
||||||
bool bip_valid(void);
|
bool bip_valid(void);
|
||||||
void bip_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
|
void bip_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
|
||||||
void bip_get_my_address(BACNET_ADDRESS * my_address);
|
void bip_get_my_address(BACNET_ADDRESS * my_address);
|
||||||
|
|
||||||
/* function to send a packet out the BACnet/IP socket */
|
/* function to send a packet out the BACnet/IP socket */
|
||||||
/* returns zero on success, non-zero on failure */
|
/* returns zero on success, non-zero on failure */
|
||||||
int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
||||||
|
|
||||||
BACNET_NPDU_DATA * npdu_data, /* network information */
|
BACNET_NPDU_DATA * npdu_data, /* network information */
|
||||||
|
|
||||||
uint8_t * pdu, /* any data to be sent - may be null */
|
uint8_t * pdu, /* any data to be sent - may be null */
|
||||||
|
|
||||||
unsigned pdu_len); /* number of bytes of data */
|
unsigned pdu_len); /* number of bytes of data */
|
||||||
|
|
||||||
/* receives a BACnet/IP packet */
|
/* receives a BACnet/IP packet */
|
||||||
/* returns the number of octets in the PDU, or zero on failure */
|
/* returns the number of octets in the PDU, or zero on failure */
|
||||||
uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */
|
uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */
|
||||||
|
|
||||||
uint8_t * pdu, /* PDU data */
|
uint8_t * pdu, /* PDU data */
|
||||||
|
|
||||||
uint16_t max_pdu, /* amount of space available in the PDU */
|
uint16_t max_pdu, /* amount of space available in the PDU */
|
||||||
|
|
||||||
unsigned timeout); /* milliseconds to wait for a packet */
|
unsigned timeout); /* milliseconds to wait for a packet */
|
||||||
|
|
||||||
/* use network byte order for setting */
|
/* use network byte order for setting */
|
||||||
void bip_set_port(uint16_t port);
|
void bip_set_port(uint16_t port);
|
||||||
/* returns network byte order */
|
/* returns network byte order */
|
||||||
uint16_t bip_get_port(void);
|
uint16_t bip_get_port(void);
|
||||||
|
|
||||||
/* use network byte order for setting */
|
/* use network byte order for setting */
|
||||||
void bip_set_addr(uint8_t * net_address);
|
void bip_set_addr(uint8_t * net_address);
|
||||||
/* returns network byte order */
|
/* returns network byte order */
|
||||||
uint8_t *bip_get_addr(void);
|
uint8_t *bip_get_addr(void);
|
||||||
|
|
||||||
/* use network byte order for setting */
|
/* use network byte order for setting */
|
||||||
void bip_set_broadcast_addr(uint8_t * net_address);
|
void bip_set_broadcast_addr(uint8_t * net_address);
|
||||||
/* returns network byte order */
|
/* returns network byte order */
|
||||||
uint8_t *bip_get_broadcast_addr(void);
|
uint8_t *bip_get_broadcast_addr(void);
|
||||||
|
|
||||||
/* gets an IP address by name, where name can be a
|
/* gets an IP address by name, where name can be a
|
||||||
string that is an IP address in dotted form, or
|
string that is an IP address in dotted form, or
|
||||||
a name that is a domain name
|
a name that is a domain name
|
||||||
returns 0 if not found, or
|
returns 0 if not found, or
|
||||||
an IP address in network byte order */
|
an IP address in network byte order */
|
||||||
long bip_getaddrbyname(const char *host_name);
|
long bip_getaddrbyname(const char *host_name);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
/** @defgroup DLBIP BACnet/IP DataLink Network Layer
|
/** @defgroup DLBIP BACnet/IP DataLink Network Layer
|
||||||
* @ingroup DataLink
|
* @ingroup DataLink
|
||||||
* Implementation of the Network Layer using BACnet/IP as the transport, as
|
* Implementation of the Network Layer using BACnet/IP as the transport, as
|
||||||
* described in Annex J.
|
* described in Annex J.
|
||||||
* The functions described here fulfill the roles defined generically at the
|
* The functions described here fulfill the roles defined generically at the
|
||||||
* DataLink level by serving as the implementation of the function templates.
|
* DataLink level by serving as the implementation of the function templates.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+460
-460
@@ -1,460 +1,460 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
* "Software"), to deal in the Software without restriction, including
|
* "Software"), to deal in the Software without restriction, including
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
* in all copies or substantial portions of the Software.
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "bacstr.h"
|
#include "bacstr.h"
|
||||||
#include "bacenum.h"
|
#include "bacenum.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "dlmstp.h"
|
#include "dlmstp.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
/* objects */
|
/* objects */
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "av.h"
|
#include "av.h"
|
||||||
#include "bv.h"
|
#include "bv.h"
|
||||||
#include "wp.h"
|
#include "wp.h"
|
||||||
|
|
||||||
/* note: you really only need to define variables for
|
/* note: you really only need to define variables for
|
||||||
properties that are writable or that may change.
|
properties that are writable or that may change.
|
||||||
The properties that are constant can be hard coded
|
The properties that are constant can be hard coded
|
||||||
into the read-property encoding. */
|
into the read-property encoding. */
|
||||||
static uint32_t Object_Instance_Number = 260001;
|
static uint32_t Object_Instance_Number = 260001;
|
||||||
static char Object_Name[20] = "My Device";
|
static char Object_Name[20] = "My Device";
|
||||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||||
|
|
||||||
void Device_Init(void)
|
void Device_Init(void)
|
||||||
{
|
{
|
||||||
/* Reinitialize_State = BACNET_REINIT_IDLE; */
|
/* Reinitialize_State = BACNET_REINIT_IDLE; */
|
||||||
/* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */
|
/* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */
|
||||||
/* FIXME: Get the data from the eeprom */
|
/* FIXME: Get the data from the eeprom */
|
||||||
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
||||||
(char *)&Object_Instance_Number,
|
(char *)&Object_Instance_Number,
|
||||||
sizeof(Object_Instance_Number),
|
sizeof(Object_Instance_Number),
|
||||||
EEPROM_BACNET_ID_ADDR); */
|
EEPROM_BACNET_ID_ADDR); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* methods to manipulate the data */
|
/* methods to manipulate the data */
|
||||||
uint32_t Device_Object_Instance_Number(void)
|
uint32_t Device_Object_Instance_Number(void)
|
||||||
{
|
{
|
||||||
return Object_Instance_Number;
|
return Object_Instance_Number;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
||||||
{
|
{
|
||||||
bool status = true; /* return value */
|
bool status = true; /* return value */
|
||||||
|
|
||||||
if (object_id <= BACNET_MAX_INSTANCE) {
|
if (object_id <= BACNET_MAX_INSTANCE) {
|
||||||
Object_Instance_Number = object_id;
|
Object_Instance_Number = object_id;
|
||||||
/* FIXME: Write the data to the eeprom */
|
/* FIXME: Write the data to the eeprom */
|
||||||
/* I2C_Write_Block(
|
/* I2C_Write_Block(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
(char *)&Object_Instance_Number,
|
(char *)&Object_Instance_Number,
|
||||||
sizeof(Object_Instance_Number),
|
sizeof(Object_Instance_Number),
|
||||||
EEPROM_BACNET_ID_ADDR); */
|
EEPROM_BACNET_ID_ADDR); */
|
||||||
} else
|
} else
|
||||||
status = false;
|
status = false;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 */
|
||||||
return ((Object_Instance_Number == object_id) ||
|
return ((Object_Instance_Number == object_id) ||
|
||||||
(object_id == BACNET_MAX_INSTANCE));
|
(object_id == BACNET_MAX_INSTANCE));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Device_Vendor_Identifier(void)
|
uint16_t Device_Vendor_Identifier(void)
|
||||||
{
|
{
|
||||||
return BACNET_VENDOR_ID;
|
return BACNET_VENDOR_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Device_Object_List_Count(void)
|
unsigned Device_Object_List_Count(void)
|
||||||
{
|
{
|
||||||
unsigned count = 1; /* at least 1 for device object */
|
unsigned count = 1; /* at least 1 for device object */
|
||||||
|
|
||||||
/* FIXME: add objects as needed */
|
/* FIXME: add objects as needed */
|
||||||
count += Analog_Value_Count();
|
count += Analog_Value_Count();
|
||||||
count += Binary_Value_Count();
|
count += Binary_Value_Count();
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device_Object_List_Identifier(uint32_t array_index,
|
bool Device_Object_List_Identifier(uint32_t array_index,
|
||||||
int *object_type,
|
int *object_type,
|
||||||
uint32_t * instance)
|
uint32_t * instance)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
uint32_t object_index = 0;
|
uint32_t object_index = 0;
|
||||||
uint32_t object_count = 0;
|
uint32_t object_count = 0;
|
||||||
|
|
||||||
/* device object */
|
/* device object */
|
||||||
if (array_index == 1) {
|
if (array_index == 1) {
|
||||||
*object_type = OBJECT_DEVICE;
|
*object_type = OBJECT_DEVICE;
|
||||||
*instance = Object_Instance_Number;
|
*instance = Object_Instance_Number;
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
/* normalize the index since
|
/* normalize the index since
|
||||||
we know it is not the previous objects */
|
we know it is not the previous objects */
|
||||||
/* array index starts at 1 */
|
/* array index starts at 1 */
|
||||||
object_index = array_index - 1;
|
object_index = array_index - 1;
|
||||||
/* 1 for the device object */
|
/* 1 for the device object */
|
||||||
object_count = 1;
|
object_count = 1;
|
||||||
/* FIXME: add objects as needed */
|
/* FIXME: add objects as needed */
|
||||||
/* analog value objects */
|
/* analog value objects */
|
||||||
if (!status) {
|
if (!status) {
|
||||||
/* array index starts at 1, and 1 for the device object */
|
/* array index starts at 1, and 1 for the device object */
|
||||||
object_index -= object_count;
|
object_index -= object_count;
|
||||||
object_count = Analog_Value_Count();
|
object_count = Analog_Value_Count();
|
||||||
if (object_index < object_count) {
|
if (object_index < object_count) {
|
||||||
*object_type = OBJECT_ANALOG_VALUE;
|
*object_type = OBJECT_ANALOG_VALUE;
|
||||||
*instance = Analog_Value_Index_To_Instance(object_index);
|
*instance = Analog_Value_Index_To_Instance(object_index);
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* binary value objects */
|
/* binary value objects */
|
||||||
if (!status) {
|
if (!status) {
|
||||||
object_index -= object_count;
|
object_index -= object_count;
|
||||||
object_count = Binary_Value_Count();
|
object_count = Binary_Value_Count();
|
||||||
/* is it a valid index for this object? */
|
/* is it a valid index for this object? */
|
||||||
if (object_index < object_count) {
|
if (object_index < object_count) {
|
||||||
*object_type = OBJECT_BINARY_VALUE;
|
*object_type = OBJECT_BINARY_VALUE;
|
||||||
*instance = Binary_Value_Index_To_Instance(object_index);
|
*instance = Binary_Value_Index_To_Instance(object_index);
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the length of the apdu encoded or -1 for error */
|
/* return the length of the apdu encoded or -1 for error */
|
||||||
int Device_Encode_Property_APDU(uint8_t * apdu,
|
int Device_Encode_Property_APDU(uint8_t * apdu,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
BACNET_PROPERTY_ID property,
|
BACNET_PROPERTY_ID property,
|
||||||
uint32_t array_index,
|
uint32_t array_index,
|
||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code)
|
BACNET_ERROR_CODE * error_code)
|
||||||
{
|
{
|
||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
int len = 0; /* apdu len intermediate value */
|
int len = 0; /* apdu len intermediate value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
BACNET_CHARACTER_STRING char_string;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
int object_type = 0;
|
int object_type = 0;
|
||||||
uint32_t instance = 0;
|
uint32_t instance = 0;
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
|
|
||||||
//object_instance = object_instance;
|
//object_instance = object_instance;
|
||||||
/* FIXME: change the hardcoded names to suit your application */
|
/* FIXME: change the hardcoded names to suit your application */
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
|
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
|
||||||
Object_Instance_Number);
|
Object_Instance_Number);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_NAME:
|
case PROP_OBJECT_NAME:
|
||||||
characterstring_init_ansi(&char_string, Object_Name);
|
characterstring_init_ansi(&char_string, Object_Name);
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_TYPE:
|
case PROP_OBJECT_TYPE:
|
||||||
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
|
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
|
||||||
break;
|
break;
|
||||||
case PROP_SYSTEM_STATUS:
|
case PROP_SYSTEM_STATUS:
|
||||||
apdu_len = encode_application_enumerated(&apdu[0], System_Status);
|
apdu_len = encode_application_enumerated(&apdu[0], System_Status);
|
||||||
break;
|
break;
|
||||||
case PROP_VENDOR_NAME:
|
case PROP_VENDOR_NAME:
|
||||||
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
|
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_VENDOR_IDENTIFIER:
|
case PROP_VENDOR_IDENTIFIER:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_unsigned(&apdu[0],
|
encode_application_unsigned(&apdu[0],
|
||||||
Device_Vendor_Identifier());
|
Device_Vendor_Identifier());
|
||||||
break;
|
break;
|
||||||
case PROP_MODEL_NAME:
|
case PROP_MODEL_NAME:
|
||||||
characterstring_init_ansi(&char_string, "GNU Demo");
|
characterstring_init_ansi(&char_string, "GNU Demo");
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_FIRMWARE_REVISION:
|
case PROP_FIRMWARE_REVISION:
|
||||||
characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT);
|
characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT);
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_APPLICATION_SOFTWARE_VERSION:
|
case PROP_APPLICATION_SOFTWARE_VERSION:
|
||||||
characterstring_init_ansi(&char_string, "1.0");
|
characterstring_init_ansi(&char_string, "1.0");
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_character_string(&apdu[0], &char_string);
|
encode_application_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_VERSION:
|
case PROP_PROTOCOL_VERSION:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_VERSION);
|
encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_VERSION);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_REVISION:
|
case PROP_PROTOCOL_REVISION:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_unsigned(&apdu[0],
|
encode_application_unsigned(&apdu[0],
|
||||||
BACNET_PROTOCOL_REVISION);
|
BACNET_PROTOCOL_REVISION);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
case PROP_PROTOCOL_SERVICES_SUPPORTED:
|
||||||
/* Note: list of services that are executed, not initiated. */
|
/* Note: list of services that are executed, not initiated. */
|
||||||
bitstring_init(&bit_string);
|
bitstring_init(&bit_string);
|
||||||
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
|
||||||
/* automatic lookup based on handlers set */
|
/* automatic lookup based on handlers set */
|
||||||
bitstring_set_bit(&bit_string, (uint8_t) i,
|
bitstring_set_bit(&bit_string, (uint8_t) i,
|
||||||
apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
|
apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
|
||||||
}
|
}
|
||||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||||
break;
|
break;
|
||||||
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
|
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
|
||||||
/* Note: this is the list of objects that can be in this device,
|
/* Note: this is the list of objects that can be in this device,
|
||||||
not a list of objects that this device can access */
|
not a list of objects that this device can access */
|
||||||
bitstring_init(&bit_string);
|
bitstring_init(&bit_string);
|
||||||
/* must have the bit string as big as it can be */
|
/* must have the bit string as big as it can be */
|
||||||
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
|
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
|
||||||
/* initialize all the object types to not-supported */
|
/* initialize all the object types to not-supported */
|
||||||
bitstring_set_bit(&bit_string, (uint8_t) i, false);
|
bitstring_set_bit(&bit_string, (uint8_t) i, false);
|
||||||
}
|
}
|
||||||
/* FIXME: indicate the objects that YOU support */
|
/* FIXME: indicate the objects that YOU support */
|
||||||
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
||||||
bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true);
|
bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true);
|
||||||
bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true);
|
bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true);
|
||||||
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_LIST:
|
case PROP_OBJECT_LIST:
|
||||||
count = Device_Object_List_Count();
|
count = Device_Object_List_Count();
|
||||||
/* Array element zero is the number of objects in the list */
|
/* Array element zero is the number of objects in the list */
|
||||||
if (array_index == 0)
|
if (array_index == 0)
|
||||||
apdu_len = encode_application_unsigned(&apdu[0], count);
|
apdu_len = encode_application_unsigned(&apdu[0], count);
|
||||||
/* if no index was specified, then try to encode the entire list */
|
/* if no index was specified, then try to encode the entire list */
|
||||||
/* into one packet. Note that more than likely you will have */
|
/* into one packet. Note that more than likely you will have */
|
||||||
/* to return an error if the number of encoded objects exceeds */
|
/* to return an error if the number of encoded objects exceeds */
|
||||||
/* your maximum APDU size. */
|
/* your maximum APDU size. */
|
||||||
else if (array_index == BACNET_ARRAY_ALL) {
|
else if (array_index == BACNET_ARRAY_ALL) {
|
||||||
for (i = 1; i <= count; i++) {
|
for (i = 1; i <= count; i++) {
|
||||||
Device_Object_List_Identifier(i, &object_type, &instance);
|
Device_Object_List_Identifier(i, &object_type, &instance);
|
||||||
len =
|
len =
|
||||||
encode_application_object_id(&apdu[apdu_len],
|
encode_application_object_id(&apdu[apdu_len],
|
||||||
object_type, instance);
|
object_type, instance);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/* assume next one is the same size as this one */
|
/* assume next one is the same size as this one */
|
||||||
/* can we all fit into the APDU? */
|
/* can we all fit into the APDU? */
|
||||||
if ((apdu_len + len) >= MAX_APDU) {
|
if ((apdu_len + len) >= MAX_APDU) {
|
||||||
/* Abort response */
|
/* Abort response */
|
||||||
*error_code =
|
*error_code =
|
||||||
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
|
||||||
apdu_len = BACNET_STATUS_ABORT;
|
apdu_len = BACNET_STATUS_ABORT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Device_Object_List_Identifier(array_index, &object_type,
|
if (Device_Object_List_Identifier(array_index, &object_type,
|
||||||
&instance))
|
&instance))
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_object_id(&apdu[0], object_type,
|
encode_application_object_id(&apdu[0], object_type,
|
||||||
instance);
|
instance);
|
||||||
else {
|
else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||||
apdu_len = BACNET_STATUS_ERROR;
|
apdu_len = BACNET_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_MAX_APDU_LENGTH_ACCEPTED:
|
case PROP_MAX_APDU_LENGTH_ACCEPTED:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
|
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
|
||||||
break;
|
break;
|
||||||
case PROP_SEGMENTATION_SUPPORTED:
|
case PROP_SEGMENTATION_SUPPORTED:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_application_enumerated(&apdu[0], SEGMENTATION_NONE);
|
encode_application_enumerated(&apdu[0], SEGMENTATION_NONE);
|
||||||
break;
|
break;
|
||||||
case PROP_APDU_TIMEOUT:
|
case PROP_APDU_TIMEOUT:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0], 60000);
|
apdu_len = encode_application_unsigned(&apdu[0], 60000);
|
||||||
break;
|
break;
|
||||||
case PROP_NUMBER_OF_APDU_RETRIES:
|
case PROP_NUMBER_OF_APDU_RETRIES:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
||||||
break;
|
break;
|
||||||
case PROP_DEVICE_ADDRESS_BINDING:
|
case PROP_DEVICE_ADDRESS_BINDING:
|
||||||
/* FIXME: encode the list here, if it exists */
|
/* FIXME: encode the list here, if it exists */
|
||||||
break;
|
break;
|
||||||
case PROP_DATABASE_REVISION:
|
case PROP_DATABASE_REVISION:
|
||||||
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
apdu_len = encode_application_unsigned(&apdu[0], 0);
|
||||||
break;
|
break;
|
||||||
// case PROP_MAX_INFO_FRAMES:
|
// case PROP_MAX_INFO_FRAMES:
|
||||||
// apdu_len =
|
// apdu_len =
|
||||||
// encode_application_unsigned(&apdu[0],
|
// encode_application_unsigned(&apdu[0],
|
||||||
// dlmstp_max_info_frames());
|
// dlmstp_max_info_frames());
|
||||||
// break;
|
// break;
|
||||||
// case PROP_MAX_MASTER:
|
// case PROP_MAX_MASTER:
|
||||||
// apdu_len =
|
// apdu_len =
|
||||||
// encode_application_unsigned(&apdu[0], dlmstp_max_master());
|
// encode_application_unsigned(&apdu[0], dlmstp_max_master());
|
||||||
// break;
|
// break;
|
||||||
// case 9600:
|
// case 9600:
|
||||||
// apdu_len =
|
// apdu_len =
|
||||||
// encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate());
|
// encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate());
|
||||||
// break;
|
// break;
|
||||||
// case 512:
|
// case 512:
|
||||||
// apdu_len = encode_application_unsigned(&apdu[0], stack_size());
|
// apdu_len = encode_application_unsigned(&apdu[0], stack_size());
|
||||||
// break;
|
// break;
|
||||||
// case 513:
|
// case 513:
|
||||||
// apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
|
// apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
|
||||||
// break;
|
// break;
|
||||||
default:
|
default:
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
|
||||||
apdu_len = -1;
|
apdu_len = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* only array properties can have array options */
|
/* only array properties can have array options */
|
||||||
if ((apdu_len >= 0) && (property != PROP_OBJECT_LIST) &&
|
if ((apdu_len >= 0) && (property != PROP_OBJECT_LIST) &&
|
||||||
(array_index != BACNET_ARRAY_ALL)) {
|
(array_index != BACNET_ARRAY_ALL)) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
*error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
|
||||||
apdu_len = BACNET_STATUS_ERROR;
|
apdu_len = BACNET_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code)
|
BACNET_ERROR_CODE * error_code)
|
||||||
{
|
{
|
||||||
bool status = false; /* return value */
|
bool status = false; /* return value */
|
||||||
int len = 0;
|
int len = 0;
|
||||||
BACNET_APPLICATION_DATA_VALUE value;
|
BACNET_APPLICATION_DATA_VALUE value;
|
||||||
|
|
||||||
if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
|
if (!Device_Valid_Object_Instance_Number(wp_data->object_instance)) {
|
||||||
*error_class = ERROR_CLASS_OBJECT;
|
*error_class = ERROR_CLASS_OBJECT;
|
||||||
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len =
|
len =
|
||||||
bacapp_decode_application_data(wp_data->application_data,
|
bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data_len, &value);
|
wp_data->application_data_len, &value);
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
/* error while decoding - a value larger than we can handle */
|
/* error while decoding - a value larger than we can handle */
|
||||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
||||||
instance))) {
|
instance))) {
|
||||||
/* we could send an I-Am broadcast to let the world know */
|
/* we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// case PROP_MAX_INFO_FRAMES:
|
// case PROP_MAX_INFO_FRAMES:
|
||||||
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
// if (value.type.Unsigned_Int <= 255) {
|
// if (value.type.Unsigned_Int <= 255) {
|
||||||
// dlmstp_set_max_info_frames(value.type.Unsigned_Int);
|
// dlmstp_set_max_info_frames(value.type.Unsigned_Int);
|
||||||
// status = true;
|
// status = true;
|
||||||
// } else {
|
// } else {
|
||||||
// *error_class = ERROR_CLASS_PROPERTY;
|
// *error_class = ERROR_CLASS_PROPERTY;
|
||||||
// *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
// *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
// *error_class = ERROR_CLASS_PROPERTY;
|
// *error_class = ERROR_CLASS_PROPERTY;
|
||||||
// *error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
// *error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||||
// }
|
// }
|
||||||
// break;
|
// break;
|
||||||
// case PROP_MAX_MASTER:
|
// case PROP_MAX_MASTER:
|
||||||
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
// if ((value.type.Unsigned_Int > 0) &&
|
// if ((value.type.Unsigned_Int > 0) &&
|
||||||
// (value.type.Unsigned_Int <= 127)) {
|
// (value.type.Unsigned_Int <= 127)) {
|
||||||
// dlmstp_set_max_master(value.type.Unsigned_Int);
|
// dlmstp_set_max_master(value.type.Unsigned_Int);
|
||||||
// status = true;
|
// status = true;
|
||||||
// } else {
|
// } else {
|
||||||
// *error_class = ERROR_CLASS_PROPERTY;
|
// *error_class = ERROR_CLASS_PROPERTY;
|
||||||
// *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
// *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
// *error_class = ERROR_CLASS_PROPERTY;
|
// *error_class = ERROR_CLASS_PROPERTY;
|
||||||
// *error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
// *error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||||
// }
|
// }
|
||||||
// break;
|
// break;
|
||||||
case PROP_OBJECT_NAME:
|
case PROP_OBJECT_NAME:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||||
uint8_t encoding;
|
uint8_t encoding;
|
||||||
|
|
||||||
encoding =
|
encoding =
|
||||||
characterstring_encoding(&value.type.Character_String);
|
characterstring_encoding(&value.type.Character_String);
|
||||||
if (encoding == CHARACTER_ANSI_X34) {
|
if (encoding == CHARACTER_ANSI_X34) {
|
||||||
if (characterstring_ansi_copy(&Object_Name[0],
|
if (characterstring_ansi_copy(&Object_Name[0],
|
||||||
sizeof(Object_Name),
|
sizeof(Object_Name),
|
||||||
&value.type.Character_String)) {
|
&value.type.Character_String)) {
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
|
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// case 9600:
|
// case 9600:
|
||||||
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
// if (value.type.Unsigned_Int > 115200) {
|
// if (value.type.Unsigned_Int > 115200) {
|
||||||
// RS485_Set_Baud_Rate(value.type.Unsigned_Int);
|
// RS485_Set_Baud_Rate(value.type.Unsigned_Int);
|
||||||
// status = true;
|
// status = true;
|
||||||
// } else {
|
// } else {
|
||||||
// *error_class = ERROR_CLASS_PROPERTY;
|
// *error_class = ERROR_CLASS_PROPERTY;
|
||||||
// *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
// *error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
// }
|
// }
|
||||||
// } else {
|
// } else {
|
||||||
// *error_class = ERROR_CLASS_PROPERTY;
|
// *error_class = ERROR_CLASS_PROPERTY;
|
||||||
// *error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
// *error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||||
// }
|
// }
|
||||||
// break;
|
// break;
|
||||||
default:
|
default:
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
+161
-161
@@ -1,161 +1,161 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
* "Software"), to deal in the Software without restriction, including
|
* "Software"), to deal in the Software without restriction, including
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
* the following conditions:
|
* the following conditions:
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
* in all copies or substantial portions of the Software.
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*
|
*
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "bacerror.h"
|
#include "bacerror.h"
|
||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
#include "abort.h"
|
#include "abort.h"
|
||||||
#include "rp.h"
|
#include "rp.h"
|
||||||
/* demo objects */
|
/* demo objects */
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "av.h"
|
#include "av.h"
|
||||||
#include "bv.h"
|
#include "bv.h"
|
||||||
|
|
||||||
/* Encodes the property APDU and returns the length,
|
/* Encodes the property APDU and returns the length,
|
||||||
or sets the error, and returns -1 */
|
or sets the error, and returns -1 */
|
||||||
int Encode_Property_APDU(uint8_t * apdu,
|
int Encode_Property_APDU(uint8_t * apdu,
|
||||||
BACNET_READ_PROPERTY_DATA * rp_data,
|
BACNET_READ_PROPERTY_DATA * rp_data,
|
||||||
BACNET_ERROR_CLASS * error_class,
|
BACNET_ERROR_CLASS * error_class,
|
||||||
BACNET_ERROR_CODE * error_code)
|
BACNET_ERROR_CODE * error_code)
|
||||||
{
|
{
|
||||||
int apdu_len = -1;
|
int apdu_len = -1;
|
||||||
|
|
||||||
/* handle each object type */
|
/* handle each object type */
|
||||||
switch (rp_data->object_type) {
|
switch (rp_data->object_type) {
|
||||||
case OBJECT_DEVICE:
|
case OBJECT_DEVICE:
|
||||||
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Device_Encode_Property_APDU(&apdu[0],
|
Device_Encode_Property_APDU(&apdu[0],
|
||||||
rp_data->object_instance, rp_data->object_property,
|
rp_data->object_instance, rp_data->object_property,
|
||||||
rp_data->array_index, error_class, error_code);
|
rp_data->array_index, error_class, error_code);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_ANALOG_VALUE:
|
case OBJECT_ANALOG_VALUE:
|
||||||
if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
|
if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Analog_Value_Encode_Property_APDU(&apdu[0],
|
Analog_Value_Encode_Property_APDU(&apdu[0],
|
||||||
rp_data->object_instance, rp_data->object_property,
|
rp_data->object_instance, rp_data->object_property,
|
||||||
rp_data->array_index, error_class, error_code);
|
rp_data->array_index, error_class, error_code);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_BINARY_VALUE:
|
case OBJECT_BINARY_VALUE:
|
||||||
if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
|
if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
|
||||||
apdu_len =
|
apdu_len =
|
||||||
Binary_Value_Encode_Property_APDU(&apdu[0],
|
Binary_Value_Encode_Property_APDU(&apdu[0],
|
||||||
rp_data->object_instance, rp_data->object_property,
|
rp_data->object_instance, rp_data->object_property,
|
||||||
rp_data->array_index, error_class, error_code);
|
rp_data->array_index, error_class, error_code);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*error_class = ERROR_CLASS_OBJECT;
|
*error_class = ERROR_CLASS_OBJECT;
|
||||||
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handler_read_property(uint8_t * service_request,
|
void handler_read_property(uint8_t * service_request,
|
||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||||
{
|
{
|
||||||
BACNET_READ_PROPERTY_DATA data;
|
BACNET_READ_PROPERTY_DATA data;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int ack_len = 0;
|
int ack_len = 0;
|
||||||
int property_len = 0;
|
int property_len = 0;
|
||||||
int pdu_len = 0;
|
int pdu_len = 0;
|
||||||
BACNET_NPDU_DATA npdu_data;
|
BACNET_NPDU_DATA npdu_data;
|
||||||
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
|
||||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
BACNET_ADDRESS my_address;
|
BACNET_ADDRESS my_address;
|
||||||
|
|
||||||
/* encode the NPDU portion of the packet */
|
/* encode the NPDU portion of the packet */
|
||||||
datalink_get_my_address(&my_address);
|
datalink_get_my_address(&my_address);
|
||||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||||
pdu_len =
|
pdu_len =
|
||||||
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
|
||||||
&npdu_data);
|
&npdu_data);
|
||||||
if (service_data->segmented_message) {
|
if (service_data->segmented_message) {
|
||||||
/* we don't support segmentation - send an abort */
|
/* we don't support segmentation - send an abort */
|
||||||
len =
|
len =
|
||||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
|
||||||
true);
|
true);
|
||||||
goto RP_ABORT;
|
goto RP_ABORT;
|
||||||
}
|
}
|
||||||
len = rp_decode_service_request(service_request, service_len, &data);
|
len = rp_decode_service_request(service_request, service_len, &data);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
/* bad decoding - send an abort */
|
/* bad decoding - send an abort */
|
||||||
len =
|
len =
|
||||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
service_data->invoke_id, ABORT_REASON_OTHER, true);
|
||||||
goto RP_ABORT;
|
goto RP_ABORT;
|
||||||
}
|
}
|
||||||
/* most cases will be error */
|
/* most cases will be error */
|
||||||
ack_len =
|
ack_len =
|
||||||
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
|
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, &data);
|
service_data->invoke_id, &data);
|
||||||
/* FIXME: add buffer len as passed into function or use smart buffer */
|
/* FIXME: add buffer len as passed into function or use smart buffer */
|
||||||
property_len =
|
property_len =
|
||||||
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len],
|
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len],
|
||||||
&data, &error_class, &error_code);
|
&data, &error_class, &error_code);
|
||||||
if (property_len >= 0) {
|
if (property_len >= 0) {
|
||||||
len =
|
len =
|
||||||
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer
|
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer
|
||||||
[pdu_len + property_len + ack_len]);
|
[pdu_len + property_len + ack_len]);
|
||||||
len += ack_len + property_len;
|
len += ack_len + property_len;
|
||||||
} else {
|
} else {
|
||||||
switch (property_len) {
|
switch (property_len) {
|
||||||
/* BACnet APDU too small to fit data, so proper response is Abort */
|
/* BACnet APDU too small to fit data, so proper response is Abort */
|
||||||
case BACNET_STATUS_ABORT:
|
case BACNET_STATUS_ABORT:
|
||||||
len =
|
len =
|
||||||
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id,
|
service_data->invoke_id,
|
||||||
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
len =
|
len =
|
||||||
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
error_class, error_code);
|
error_class, error_code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RP_ABORT:
|
RP_ABORT:
|
||||||
pdu_len += len;
|
pdu_len += len;
|
||||||
|
|
||||||
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-44
@@ -1,44 +1,44 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @author Miguel Fernandes <miguelandre.fernandes@gmail.com>
|
* @author Miguel Fernandes <miguelandre.fernandes@gmail.com>
|
||||||
* @date 6 de Jun de 2013
|
* @date 6 de Jun de 2013
|
||||||
* @brief For redirecting stdout, stdin and stderr
|
* @brief For redirecting stdout, stdin and stderr
|
||||||
* see http://www.appelsiini.net/2011/simple-usart-with-avr-libc
|
* see http://www.appelsiini.net/2011/simple-usart-with-avr-libc
|
||||||
*/
|
*/
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <util/setbaud.h>
|
#include <util/setbaud.h>
|
||||||
#include "hardware.h"
|
#include "hardware.h"
|
||||||
#include "uart.h"
|
#include "uart.h"
|
||||||
|
|
||||||
void uart_init(void)
|
void uart_init(void)
|
||||||
{
|
{
|
||||||
UBRR0H = UBRRH_VALUE;
|
UBRR0H = UBRRH_VALUE;
|
||||||
UBRR0L = UBRRL_VALUE;
|
UBRR0L = UBRRL_VALUE;
|
||||||
|
|
||||||
#if USE_2X
|
#if USE_2X
|
||||||
UCSR0A |= _BV(U2X0);
|
UCSR0A |= _BV(U2X0);
|
||||||
#else
|
#else
|
||||||
UCSR0A &= ~(_BV(U2X0));
|
UCSR0A &= ~(_BV(U2X0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
|
UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); /* 8-bit data */
|
||||||
UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */
|
UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_putchar(char c,
|
void uart_putchar(char c,
|
||||||
FILE * stream)
|
FILE * stream)
|
||||||
{
|
{
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
uart_putchar('\r', stream);
|
uart_putchar('\r', stream);
|
||||||
}
|
}
|
||||||
loop_until_bit_is_set(UCSR0A, UDRE0);
|
loop_until_bit_is_set(UCSR0A, UDRE0);
|
||||||
UDR0 = c;
|
UDR0 = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
char uart_getchar(FILE * stream)
|
char uart_getchar(FILE * stream)
|
||||||
{
|
{
|
||||||
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
|
loop_until_bit_is_set(UCSR0A, RXC0); /* Wait until data exists. */
|
||||||
return UDR0;
|
return UDR0;
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-27
@@ -1,27 +1,27 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @author Miguel Fernandes <miguelandre.fernandes@gmail.com>
|
* @author Miguel Fernandes <miguelandre.fernandes@gmail.com>
|
||||||
* @date 6 de Jun de 2013
|
* @date 6 de Jun de 2013
|
||||||
* @brief BACnet Virtual Link Control for Wiznet on Arduino-Uno
|
* @brief BACnet Virtual Link Control for Wiznet on Arduino-Uno
|
||||||
*/
|
*/
|
||||||
#ifndef UART_H_
|
#ifndef UART_H_
|
||||||
#define UART_H_
|
#define UART_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
void uart_init(void);
|
void uart_init(void);
|
||||||
void uart_putchar(char c,
|
void uart_putchar(char c,
|
||||||
FILE * stream);
|
FILE * stream);
|
||||||
char uart_getchar(FILE * stream);
|
char uart_getchar(FILE * stream);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+56
-56
@@ -1,57 +1,57 @@
|
|||||||
//
|
//
|
||||||
// Copyleft F.Chaxel 2017
|
// Copyleft F.Chaxel 2017
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
|
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
#include "lwip/netdb.h"
|
#include "lwip/netdb.h"
|
||||||
|
|
||||||
#include "bip.h"
|
#include "bip.h"
|
||||||
|
|
||||||
long bip_getaddrbyname(
|
long bip_getaddrbyname(
|
||||||
const char *host_name)
|
const char *host_name)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bip_set_interface(char *ifname)
|
void bip_set_interface(char *ifname)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void bip_cleanup (void)
|
void bip_cleanup (void)
|
||||||
{
|
{
|
||||||
close(bip_socket());
|
close(bip_socket());
|
||||||
bip_set_socket(-1);
|
bip_set_socket(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bip_init(char *ifname)
|
bool bip_init(char *ifname)
|
||||||
{
|
{
|
||||||
|
|
||||||
tcpip_adapter_ip_info_t ip_info = { 0 };
|
tcpip_adapter_ip_info_t ip_info = { 0 };
|
||||||
|
|
||||||
int value = 1;
|
int value = 1;
|
||||||
|
|
||||||
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
|
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info);
|
||||||
|
|
||||||
bip_set_interface(ifname);
|
bip_set_interface(ifname);
|
||||||
bip_set_port(htons(0xBAC0));
|
bip_set_port(htons(0xBAC0));
|
||||||
bip_set_addr(ip_info.ip.addr);
|
bip_set_addr(ip_info.ip.addr);
|
||||||
bip_set_broadcast_addr((ip_info.ip.addr&ip_info.netmask.addr)|(~ip_info.netmask.addr));
|
bip_set_broadcast_addr((ip_info.ip.addr&ip_info.netmask.addr)|(~ip_info.netmask.addr));
|
||||||
|
|
||||||
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||||
struct sockaddr_in saddr = { 0 };
|
struct sockaddr_in saddr = { 0 };
|
||||||
|
|
||||||
saddr.sin_family = PF_INET;
|
saddr.sin_family = PF_INET;
|
||||||
saddr.sin_port = htons(0xBAC0);
|
saddr.sin_port = htons(0xBAC0);
|
||||||
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
|
bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &value, sizeof(value));
|
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *) &value, sizeof(value));
|
||||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &value, sizeof(value));
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &value, sizeof(value));
|
||||||
|
|
||||||
bip_set_socket(sock);
|
bip_set_socket(sock);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
+214
-214
@@ -1,215 +1,215 @@
|
|||||||
//
|
//
|
||||||
// Copyleft F.Chaxel 2017
|
// Copyleft F.Chaxel 2017
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
#include "datalink.h"
|
#include "datalink.h"
|
||||||
#include "dcc.h"
|
#include "dcc.h"
|
||||||
#include "tsm.h"
|
#include "tsm.h"
|
||||||
// conflict filename address.h with another file in default include paths
|
// conflict filename address.h with another file in default include paths
|
||||||
#include "../lib/stack/address.h"
|
#include "../lib/stack/address.h"
|
||||||
#include "bip.h"
|
#include "bip.h"
|
||||||
|
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
#include "bo.h"
|
#include "bo.h"
|
||||||
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#include "esp_event_loop.h"
|
#include "esp_event_loop.h"
|
||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
#include "lwip/netdb.h"
|
#include "lwip/netdb.h"
|
||||||
|
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/event_groups.h"
|
#include "freertos/event_groups.h"
|
||||||
|
|
||||||
// hidden function not in any .h files
|
// hidden function not in any .h files
|
||||||
extern uint8_t temprature_sens_read();
|
extern uint8_t temprature_sens_read();
|
||||||
extern uint32_t hall_sens_read();
|
extern uint32_t hall_sens_read();
|
||||||
|
|
||||||
// Wifi params
|
// Wifi params
|
||||||
wifi_config_t wifi_config = {
|
wifi_config_t wifi_config = {
|
||||||
.sta = {
|
.sta = {
|
||||||
.ssid = "myWifi",
|
.ssid = "myWifi",
|
||||||
.password = "myPass",
|
.password = "myPass",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// GPIO 5 has a Led on Sparkfun ESP32 board
|
// GPIO 5 has a Led on Sparkfun ESP32 board
|
||||||
#define BACNET_LED 5
|
#define BACNET_LED 5
|
||||||
|
|
||||||
uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };
|
uint8_t Handler_Transmit_Buffer[MAX_PDU] = { 0 };
|
||||||
uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
uint8_t Rx_Buf[MAX_MPDU] = { 0 };
|
||||||
|
|
||||||
EventGroupHandle_t wifi_event_group;
|
EventGroupHandle_t wifi_event_group;
|
||||||
const static int CONNECTED_BIT = BIT0;
|
const static int CONNECTED_BIT = BIT0;
|
||||||
|
|
||||||
/* BACnet handler, stack init, IAm */
|
/* BACnet handler, stack init, IAm */
|
||||||
void StartBACnet()
|
void StartBACnet()
|
||||||
{
|
{
|
||||||
/* we need to handle who-is to support dynamic device binding */
|
/* we need to handle who-is to support dynamic device binding */
|
||||||
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
|
||||||
|
|
||||||
/* set the handler for all the services we don't implement */
|
/* set the handler for all the services we don't implement */
|
||||||
/* It is required to send the proper reject message... */
|
/* It is required to send the proper reject message... */
|
||||||
apdu_set_unrecognized_service_handler_handler
|
apdu_set_unrecognized_service_handler_handler
|
||||||
(handler_unrecognized_service);
|
(handler_unrecognized_service);
|
||||||
/* Set the handlers for any confirmed services that we support. */
|
/* Set the handlers for any confirmed services that we support. */
|
||||||
/* We must implement read property - it's required! */
|
/* We must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
handler_read_property);
|
handler_read_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
|
||||||
handler_read_property_multiple);
|
handler_read_property_multiple);
|
||||||
|
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
||||||
handler_write_property);
|
handler_write_property);
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
|
||||||
handler_cov_subscribe);
|
handler_cov_subscribe);
|
||||||
|
|
||||||
address_init();
|
address_init();
|
||||||
bip_init(NULL);
|
bip_init(NULL);
|
||||||
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
Send_I_Am(&Handler_Transmit_Buffer[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wifi events handler : start & stop bacnet with an event */
|
/* wifi events handler : start & stop bacnet with an event */
|
||||||
esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
|
esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
|
||||||
{
|
{
|
||||||
switch(event->event_id) {
|
switch(event->event_id) {
|
||||||
case SYSTEM_EVENT_STA_START:
|
case SYSTEM_EVENT_STA_START:
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
break;
|
break;
|
||||||
case SYSTEM_EVENT_STA_CONNECTED:
|
case SYSTEM_EVENT_STA_CONNECTED:
|
||||||
break ;
|
break ;
|
||||||
case SYSTEM_EVENT_STA_GOT_IP:
|
case SYSTEM_EVENT_STA_GOT_IP:
|
||||||
if (xEventGroupGetBits(wifi_event_group)!=CONNECTED_BIT)
|
if (xEventGroupGetBits(wifi_event_group)!=CONNECTED_BIT)
|
||||||
{
|
{
|
||||||
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
|
||||||
StartBACnet();
|
StartBACnet();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||||
/* This is a workaround as ESP32 WiFi libs don't currently
|
/* This is a workaround as ESP32 WiFi libs don't currently
|
||||||
auto-reassociate. */
|
auto-reassociate. */
|
||||||
esp_wifi_connect();
|
esp_wifi_connect();
|
||||||
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);
|
||||||
bip_cleanup();
|
bip_cleanup();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tcpip & wifi station start */
|
/* tcpip & wifi station start */
|
||||||
|
|
||||||
void wifi_init_station(void)
|
void wifi_init_station(void)
|
||||||
{
|
{
|
||||||
tcpip_adapter_init();
|
tcpip_adapter_init();
|
||||||
wifi_event_group = xEventGroupCreate();
|
wifi_event_group = xEventGroupCreate();
|
||||||
esp_event_loop_init(wifi_event_handler, NULL);
|
esp_event_loop_init(wifi_event_handler, NULL);
|
||||||
|
|
||||||
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
esp_wifi_init(&cfg);
|
esp_wifi_init(&cfg);
|
||||||
|
|
||||||
esp_wifi_set_storage(WIFI_STORAGE_RAM);
|
esp_wifi_set_storage(WIFI_STORAGE_RAM);
|
||||||
esp_wifi_set_mode(WIFI_MODE_STA);
|
esp_wifi_set_mode(WIFI_MODE_STA);
|
||||||
|
|
||||||
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
|
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
|
||||||
|
|
||||||
esp_wifi_start() ;
|
esp_wifi_start() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup gpio & nv flash, call wifi init code */
|
/* setup gpio & nv flash, call wifi init code */
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
gpio_pad_select_gpio(BACNET_LED);
|
gpio_pad_select_gpio(BACNET_LED);
|
||||||
gpio_set_direction(BACNET_LED, GPIO_MODE_OUTPUT);
|
gpio_set_direction(BACNET_LED, GPIO_MODE_OUTPUT);
|
||||||
|
|
||||||
gpio_set_level(BACNET_LED,0);
|
gpio_set_level(BACNET_LED,0);
|
||||||
|
|
||||||
esp_err_t ret = nvs_flash_init();
|
esp_err_t ret = nvs_flash_init();
|
||||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES)
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES)
|
||||||
{
|
{
|
||||||
nvs_flash_erase();
|
nvs_flash_erase();
|
||||||
ret = nvs_flash_init();
|
ret = nvs_flash_init();
|
||||||
}
|
}
|
||||||
wifi_init_station();
|
wifi_init_station();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bacnet Task */
|
/* Bacnet Task */
|
||||||
void BACnetTask(void *pvParameters)
|
void BACnetTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
BACNET_ADDRESS src = {
|
BACNET_ADDRESS src = {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
unsigned timeout = 1;
|
unsigned timeout = 1;
|
||||||
|
|
||||||
// Init Bacnet objets dictionnary
|
// Init Bacnet objets dictionnary
|
||||||
Device_Init(NULL);
|
Device_Init(NULL);
|
||||||
Device_Set_Object_Instance_Number(12);
|
Device_Set_Object_Instance_Number(12);
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
uint32_t tickcount=xTaskGetTickCount();
|
uint32_t tickcount=xTaskGetTickCount();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS); // could be remove to speed the code
|
vTaskDelay(10 / portTICK_PERIOD_MS); // could be remove to speed the code
|
||||||
|
|
||||||
// do nothing if not connected to wifi
|
// do nothing if not connected to wifi
|
||||||
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
|
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
|
||||||
{
|
{
|
||||||
uint32_t newtick=xTaskGetTickCount();
|
uint32_t newtick=xTaskGetTickCount();
|
||||||
|
|
||||||
// one second elapse at least (maybe much more if Wifi was deconnected for a long)
|
// one second elapse at least (maybe much more if Wifi was deconnected for a long)
|
||||||
if ((newtick<tickcount)||((newtick-tickcount)>=configTICK_RATE_HZ))
|
if ((newtick<tickcount)||((newtick-tickcount)>=configTICK_RATE_HZ))
|
||||||
{
|
{
|
||||||
tickcount=newtick;
|
tickcount=newtick;
|
||||||
dcc_timer_seconds(1);
|
dcc_timer_seconds(1);
|
||||||
bvlc_maintenance_timer(1);
|
bvlc_maintenance_timer(1);
|
||||||
handler_cov_timer_seconds(1);
|
handler_cov_timer_seconds(1);
|
||||||
tsm_timer_milliseconds(1000);
|
tsm_timer_milliseconds(1000);
|
||||||
|
|
||||||
// Read analog values from internal sensors
|
// Read analog values from internal sensors
|
||||||
Analog_Input_Present_Value_Set(0,temprature_sens_read());
|
Analog_Input_Present_Value_Set(0,temprature_sens_read());
|
||||||
Analog_Input_Present_Value_Set(1,hall_sens_read());
|
Analog_Input_Present_Value_Set(1,hall_sens_read());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
|
||||||
if (pdu_len)
|
if (pdu_len)
|
||||||
{
|
{
|
||||||
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
npdu_handler(&src, &Rx_Buf[0], pdu_len);
|
||||||
|
|
||||||
if(Binary_Output_Present_Value(0)==BINARY_ACTIVE)
|
if(Binary_Output_Present_Value(0)==BINARY_ACTIVE)
|
||||||
gpio_set_level(BACNET_LED,1);
|
gpio_set_level(BACNET_LED,1);
|
||||||
else
|
else
|
||||||
gpio_set_level(BACNET_LED,0);
|
gpio_set_level(BACNET_LED,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handler_cov_task();
|
handler_cov_task();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Entry point */
|
/* Entry point */
|
||||||
void app_main()
|
void app_main()
|
||||||
{
|
{
|
||||||
// Cannot run BACnet code here, the default stack size is to small : 4096 byte
|
// Cannot run BACnet code here, the default stack size is to small : 4096 byte
|
||||||
xTaskCreate(
|
xTaskCreate(
|
||||||
BACnetTask, /* Function to implement the task */
|
BACnetTask, /* Function to implement the task */
|
||||||
"BACnetTask", /* Name of the task */
|
"BACnetTask", /* Name of the task */
|
||||||
10000, /* Stack size in words */
|
10000, /* Stack size in words */
|
||||||
NULL, /* Task input parameter */
|
NULL, /* Task input parameter */
|
||||||
20, /* Priority of the task */
|
20, /* Priority of the task */
|
||||||
NULL); /* Task handle. */
|
NULL); /* Task handle. */
|
||||||
}
|
}
|
||||||
+125
-125
@@ -1,125 +1,125 @@
|
|||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Automatically generated file; DO NOT EDIT.
|
* Automatically generated file; DO NOT EDIT.
|
||||||
* Espressif IoT Development Framework Configuration
|
* Espressif IoT Development Framework Configuration
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define CONFIG_GATTC_ENABLE 1
|
#define CONFIG_GATTC_ENABLE 1
|
||||||
#define CONFIG_ESP32_PHY_MAX_TX_POWER 20
|
#define CONFIG_ESP32_PHY_MAX_TX_POWER 20
|
||||||
#define CONFIG_PHY_ENABLED 1
|
#define CONFIG_PHY_ENABLED 1
|
||||||
#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0
|
#define CONFIG_TRACEMEM_RESERVE_DRAM 0x0
|
||||||
#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16
|
#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16
|
||||||
#define CONFIG_BLE_SMP_ENABLE 1
|
#define CONFIG_BLE_SMP_ENABLE 1
|
||||||
#define CONFIG_IPC_TASK_STACK_SIZE 1024
|
#define CONFIG_IPC_TASK_STACK_SIZE 1024
|
||||||
#define CONFIG_ESPTOOLPY_FLASHFREQ "40m"
|
#define CONFIG_ESPTOOLPY_FLASHFREQ "40m"
|
||||||
#define CONFIG_NEWLIB_STDOUT_ADDCR 1
|
#define CONFIG_NEWLIB_STDOUT_ADDCR 1
|
||||||
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK 1
|
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK 1
|
||||||
#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB"
|
#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB"
|
||||||
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1
|
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1
|
||||||
#define CONFIG_ETHERNET 1
|
#define CONFIG_ETHERNET 1
|
||||||
#define CONFIG_INT_WDT 1
|
#define CONFIG_INT_WDT 1
|
||||||
#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1
|
#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1
|
||||||
#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO 1
|
#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO 1
|
||||||
#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1
|
#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1
|
||||||
#define CONFIG_AWS_IOT_MQTT_PORT 8883
|
#define CONFIG_AWS_IOT_MQTT_PORT 8883
|
||||||
#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1
|
#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1
|
||||||
#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10
|
#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10
|
||||||
#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1
|
#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1
|
||||||
#define CONFIG_BT_RESERVE_DRAM 0x10000
|
#define CONFIG_BT_RESERVE_DRAM 0x10000
|
||||||
#define CONFIG_ESP32_PANIC_PRINT_REBOOT 1
|
#define CONFIG_ESP32_PANIC_PRINT_REBOOT 1
|
||||||
#define CONFIG_CONSOLE_UART_BAUDRATE 115200
|
#define CONFIG_CONSOLE_UART_BAUDRATE 115200
|
||||||
#define CONFIG_LWIP_MAX_SOCKETS 10
|
#define CONFIG_LWIP_MAX_SOCKETS 10
|
||||||
#define CONFIG_EMAC_TASK_PRIORITY 20
|
#define CONFIG_EMAC_TASK_PRIORITY 20
|
||||||
#define CONFIG_TIMER_TASK_STACK_DEPTH 2048
|
#define CONFIG_TIMER_TASK_STACK_DEPTH 2048
|
||||||
#define CONFIG_FATFS_CODEPAGE 1
|
#define CONFIG_FATFS_CODEPAGE 1
|
||||||
#define CONFIG_ESP32_DEFAULT_CPU_FREQ_160 1
|
#define CONFIG_ESP32_DEFAULT_CPU_FREQ_160 1
|
||||||
#define CONFIG_ULP_COPROC_RESERVE_MEM 0
|
#define CONFIG_ULP_COPROC_RESERVE_MEM 0
|
||||||
#define CONFIG_ESPTOOLPY_BAUD 115200
|
#define CONFIG_ESPTOOLPY_BAUD 115200
|
||||||
#define CONFIG_INT_WDT_CHECK_CPU1 1
|
#define CONFIG_INT_WDT_CHECK_CPU1 1
|
||||||
#define CONFIG_FLASHMODE_DIO 1
|
#define CONFIG_FLASHMODE_DIO 1
|
||||||
#define CONFIG_ESPTOOLPY_AFTER_RESET 1
|
#define CONFIG_ESPTOOLPY_AFTER_RESET 1
|
||||||
#define CONFIG_TOOLPREFIX "xtensa-esp32-elf-"
|
#define CONFIG_TOOLPREFIX "xtensa-esp32-elf-"
|
||||||
#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1024
|
#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1024
|
||||||
#define CONFIG_ESP32_WIFI_AMPDU_ENABLED 1
|
#define CONFIG_ESP32_WIFI_AMPDU_ENABLED 1
|
||||||
#define CONFIG_CONSOLE_UART_NUM 0
|
#define CONFIG_CONSOLE_UART_NUM 0
|
||||||
#define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1
|
#define CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC 1
|
||||||
#define CONFIG_ESPTOOLPY_BAUD_115200B 1
|
#define CONFIG_ESPTOOLPY_BAUD_115200B 1
|
||||||
#define CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX 0
|
#define CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX 0
|
||||||
#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS 1
|
#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS 1
|
||||||
#define CONFIG_CONSOLE_UART_DEFAULT 1
|
#define CONFIG_CONSOLE_UART_DEFAULT 1
|
||||||
#define CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN 16384
|
#define CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN 16384
|
||||||
#define CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS 4
|
#define CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS 4
|
||||||
#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1
|
#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1
|
||||||
#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1
|
#define CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE 1
|
||||||
#define CONFIG_BTDM_CONTROLLER_RUN_CPU 0
|
#define CONFIG_BTDM_CONTROLLER_RUN_CPU 0
|
||||||
#define CONFIG_TCPIP_TASK_STACK_SIZE 2560
|
#define CONFIG_TCPIP_TASK_STACK_SIZE 2560
|
||||||
#define CONFIG_TASK_WDT 1
|
#define CONFIG_TASK_WDT 1
|
||||||
#define CONFIG_MAIN_TASK_STACK_SIZE 4096
|
#define CONFIG_MAIN_TASK_STACK_SIZE 4096
|
||||||
#define CONFIG_TASK_WDT_TIMEOUT_S 5
|
#define CONFIG_TASK_WDT_TIMEOUT_S 5
|
||||||
#define CONFIG_INT_WDT_TIMEOUT_MS 300
|
#define CONFIG_INT_WDT_TIMEOUT_MS 300
|
||||||
#define CONFIG_ESPTOOLPY_FLASHMODE "dio"
|
#define CONFIG_ESPTOOLPY_FLASHMODE "dio"
|
||||||
#define CONFIG_BTC_TASK_STACK_SIZE 3072
|
#define CONFIG_BTC_TASK_STACK_SIZE 3072
|
||||||
#define CONFIG_BLUEDROID_ENABLED 1
|
#define CONFIG_BLUEDROID_ENABLED 1
|
||||||
#define CONFIG_ESPTOOLPY_BEFORE "default_reset"
|
#define CONFIG_ESPTOOLPY_BEFORE "default_reset"
|
||||||
#define CONFIG_LOG_DEFAULT_LEVEL 3
|
#define CONFIG_LOG_DEFAULT_LEVEL 3
|
||||||
#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1
|
#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1
|
||||||
#define CONFIG_TIMER_QUEUE_LENGTH 10
|
#define CONFIG_TIMER_QUEUE_LENGTH 10
|
||||||
#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32
|
#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32
|
||||||
#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20
|
#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20
|
||||||
#define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024
|
#define CONFIG_ESP32_RTC_CLK_CAL_CYCLES 1024
|
||||||
#define CONFIG_ESP32_WIFI_NVS_ENABLED 1
|
#define CONFIG_ESP32_WIFI_NVS_ENABLED 1
|
||||||
#define CONFIG_AWS_IOT_SDK 1
|
#define CONFIG_AWS_IOT_SDK 1
|
||||||
#define CONFIG_DMA_RX_BUF_NUM 10
|
#define CONFIG_DMA_RX_BUF_NUM 10
|
||||||
#define CONFIG_TCP_SYNMAXRTX 6
|
#define CONFIG_TCP_SYNMAXRTX 6
|
||||||
#define CONFIG_PYTHON "python"
|
#define CONFIG_PYTHON "python"
|
||||||
#define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1
|
#define CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1 1
|
||||||
#define CONFIG_ESPTOOLPY_COMPRESSED 1
|
#define CONFIG_ESPTOOLPY_COMPRESSED 1
|
||||||
#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv"
|
#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv"
|
||||||
#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1
|
#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1
|
||||||
#define CONFIG_PARTITION_TABLE_SINGLE_APP 1
|
#define CONFIG_PARTITION_TABLE_SINGLE_APP 1
|
||||||
#define CONFIG_WIFI_ENABLED 1
|
#define CONFIG_WIFI_ENABLED 1
|
||||||
#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1
|
#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1
|
||||||
#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE 4096
|
#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE 4096
|
||||||
#define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000
|
#define CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY 2000
|
||||||
#define CONFIG_ESP32_APPTRACE_DEST_NONE 1
|
#define CONFIG_ESP32_APPTRACE_DEST_NONE 1
|
||||||
#define CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET 0x10000
|
#define CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET 0x10000
|
||||||
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32
|
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32
|
||||||
#define CONFIG_FATFS_CODEPAGE_ASCII 1
|
#define CONFIG_FATFS_CODEPAGE_ASCII 1
|
||||||
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 1
|
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 1
|
||||||
#define CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 160
|
#define CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ 160
|
||||||
#define CONFIG_FREERTOS_HZ 100
|
#define CONFIG_FREERTOS_HZ 100
|
||||||
#define CONFIG_LOG_COLORS 1
|
#define CONFIG_LOG_COLORS 1
|
||||||
#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1
|
#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1
|
||||||
#define CONFIG_FREERTOS_ASSERT_FAIL_ABORT 1
|
#define CONFIG_FREERTOS_ASSERT_FAIL_ABORT 1
|
||||||
#define CONFIG_ESP32_XTAL_FREQ 0
|
#define CONFIG_ESP32_XTAL_FREQ 0
|
||||||
#define CONFIG_MONITOR_BAUD_115200B 1
|
#define CONFIG_MONITOR_BAUD_115200B 1
|
||||||
#define CONFIG_LOG_BOOTLOADER_LEVEL 3
|
#define CONFIG_LOG_BOOTLOADER_LEVEL 3
|
||||||
#define CONFIG_SMP_ENABLE 1
|
#define CONFIG_SMP_ENABLE 1
|
||||||
#define CONFIG_ESPTOOLPY_BEFORE_RESET 1
|
#define CONFIG_ESPTOOLPY_BEFORE_RESET 1
|
||||||
#define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200
|
#define CONFIG_ESPTOOLPY_BAUD_OTHER_VAL 115200
|
||||||
#define CONFIG_ESP32_XTAL_FREQ_AUTO 1
|
#define CONFIG_ESP32_XTAL_FREQ_AUTO 1
|
||||||
#define CONFIG_TCP_MAXRTX 12
|
#define CONFIG_TCP_MAXRTX 12
|
||||||
#define CONFIG_ESPTOOLPY_AFTER "hard_reset"
|
#define CONFIG_ESPTOOLPY_AFTER "hard_reset"
|
||||||
#define CONFIG_DMA_TX_BUF_NUM 10
|
#define CONFIG_DMA_TX_BUF_NUM 10
|
||||||
#define CONFIG_ESP32_DEBUG_OCDAWARE 1
|
#define CONFIG_ESP32_DEBUG_OCDAWARE 1
|
||||||
#define CONFIG_TIMER_TASK_PRIORITY 1
|
#define CONFIG_TIMER_TASK_PRIORITY 1
|
||||||
#define CONFIG_BT_ENABLED 1
|
#define CONFIG_BT_ENABLED 1
|
||||||
#define CONFIG_MONITOR_BAUD 115200
|
#define CONFIG_MONITOR_BAUD 115200
|
||||||
#define CONFIG_FREERTOS_CORETIMER_0 1
|
#define CONFIG_FREERTOS_CORETIMER_0 1
|
||||||
#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv"
|
#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv"
|
||||||
#define CONFIG_MBEDTLS_HAVE_TIME 1
|
#define CONFIG_MBEDTLS_HAVE_TIME 1
|
||||||
#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1
|
#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1
|
||||||
#define CONFIG_GATTS_ENABLE 1
|
#define CONFIG_GATTS_ENABLE 1
|
||||||
#define CONFIG_FREERTOS_ISR_STACKSIZE 1536
|
#define CONFIG_FREERTOS_ISR_STACKSIZE 1536
|
||||||
#define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1
|
#define CONFIG_OPENSSL_ASSERT_DO_NOTHING 1
|
||||||
#define CONFIG_AWS_IOT_MQTT_HOST ""
|
#define CONFIG_AWS_IOT_MQTT_HOST ""
|
||||||
#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32
|
#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE 32
|
||||||
#define CONFIG_BT_ACL_CONNECTIONS 4
|
#define CONFIG_BT_ACL_CONNECTIONS 4
|
||||||
#define CONFIG_FATFS_MAX_LFN 255
|
#define CONFIG_FATFS_MAX_LFN 255
|
||||||
#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1
|
#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1
|
||||||
#define CONFIG_APP_OFFSET 0x10000
|
#define CONFIG_APP_OFFSET 0x10000
|
||||||
#define CONFIG_MEMMAP_SMP 1
|
#define CONFIG_MEMMAP_SMP 1
|
||||||
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
|
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
|
||||||
#define CONFIG_MONITOR_BAUD_OTHER_VAL 115200
|
#define CONFIG_MONITOR_BAUD_OTHER_VAL 115200
|
||||||
#define CONFIG_ESPTOOLPY_PORT "/dev/ttyUSB0"
|
#define CONFIG_ESPTOOLPY_PORT "/dev/ttyUSB0"
|
||||||
#define CONFIG_OPTIMIZATION_LEVEL_RELEASE 1
|
#define CONFIG_OPTIMIZATION_LEVEL_RELEASE 1
|
||||||
|
|||||||
+453
-453
@@ -1,453 +1,453 @@
|
|||||||
/*####COPYRIGHTBEGIN####
|
/*####COPYRIGHTBEGIN####
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
Copyright (C) 2016 Steve Karg
|
Copyright (C) 2016 Steve Karg
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
as published by the Free Software Foundation; either version 2
|
as published by the Free Software Foundation; either version 2
|
||||||
of the License, or (at your option) any later version.
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to:
|
along with this program; if not, write to:
|
||||||
The Free Software Foundation, Inc.
|
The Free Software Foundation, Inc.
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA.
|
Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
As a special exception, if other files instantiate templates or
|
As a special exception, if other files instantiate templates or
|
||||||
use macros or inline functions from this file, or you compile
|
use macros or inline functions from this file, or you compile
|
||||||
this file and link it with other works to produce a work based
|
this file and link it with other works to produce a work based
|
||||||
on this file, this file does not by itself cause the resulting
|
on this file, this file does not by itself cause the resulting
|
||||||
work to be covered by the GNU General Public License. However
|
work to be covered by the GNU General Public License. However
|
||||||
the source code for this file must still be made available in
|
the source code for this file must still be made available in
|
||||||
accordance with section (3) of the GNU General Public License.
|
accordance with section (3) of the GNU General Public License.
|
||||||
|
|
||||||
This exception does not invalidate any other reasons why a work
|
This exception does not invalidate any other reasons why a work
|
||||||
based on this file might be covered by the GNU General Public
|
based on this file might be covered by the GNU General Public
|
||||||
License.
|
License.
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
####COPYRIGHTEND####*/
|
####COPYRIGHTEND####*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
||||||
#include <stdbool.h> /* for the standard bool type. */
|
#include <stdbool.h> /* for the standard bool type. */
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "bip6.h"
|
#include "bip6.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
|
|
||||||
static void debug_print_ipv6(const char *str, const struct in6_addr * addr) {
|
static void debug_print_ipv6(const char *str, const struct in6_addr * addr) {
|
||||||
debug_printf( "BIP6: %s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
debug_printf( "BIP6: %s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
|
||||||
str,
|
str,
|
||||||
(int)addr->s6_addr[0], (int)addr->s6_addr[1],
|
(int)addr->s6_addr[0], (int)addr->s6_addr[1],
|
||||||
(int)addr->s6_addr[2], (int)addr->s6_addr[3],
|
(int)addr->s6_addr[2], (int)addr->s6_addr[3],
|
||||||
(int)addr->s6_addr[4], (int)addr->s6_addr[5],
|
(int)addr->s6_addr[4], (int)addr->s6_addr[5],
|
||||||
(int)addr->s6_addr[6], (int)addr->s6_addr[7],
|
(int)addr->s6_addr[6], (int)addr->s6_addr[7],
|
||||||
(int)addr->s6_addr[8], (int)addr->s6_addr[9],
|
(int)addr->s6_addr[8], (int)addr->s6_addr[9],
|
||||||
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
|
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
|
||||||
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
|
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
|
||||||
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
|
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @file linux/bip6.c Initializes BACnet/IPv6 interface (Linux). */
|
/** @file linux/bip6.c Initializes BACnet/IPv6 interface (Linux). */
|
||||||
|
|
||||||
/* unix socket */
|
/* unix socket */
|
||||||
static int BIP6_Socket = -1;
|
static int BIP6_Socket = -1;
|
||||||
/* local address - filled by init functions */
|
/* local address - filled by init functions */
|
||||||
static BACNET_IP6_ADDRESS BIP6_Addr;
|
static BACNET_IP6_ADDRESS BIP6_Addr;
|
||||||
static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
|
static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the interface name. On Linux, ifname is the /dev/ name of the interface.
|
* Set the interface name. On Linux, ifname is the /dev/ name of the interface.
|
||||||
*
|
*
|
||||||
* @param ifname - C string for name or text address
|
* @param ifname - C string for name or text address
|
||||||
*/
|
*/
|
||||||
void bip6_set_interface(
|
void bip6_set_interface(
|
||||||
char *ifname)
|
char *ifname)
|
||||||
{
|
{
|
||||||
struct ifaddrs *ifa, *ifa_tmp;
|
struct ifaddrs *ifa, *ifa_tmp;
|
||||||
struct sockaddr_in6 *sin;
|
struct sockaddr_in6 *sin;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
if (getifaddrs(&ifa) == -1) {
|
if (getifaddrs(&ifa) == -1) {
|
||||||
perror("BIP6: getifaddrs failed");
|
perror("BIP6: getifaddrs failed");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
ifa_tmp = ifa;
|
ifa_tmp = ifa;
|
||||||
debug_printf("BIP6: seeking interface: %s\n", ifname);
|
debug_printf("BIP6: seeking interface: %s\n", ifname);
|
||||||
while (ifa_tmp) {
|
while (ifa_tmp) {
|
||||||
if ((ifa_tmp->ifa_addr) &&
|
if ((ifa_tmp->ifa_addr) &&
|
||||||
(ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
|
(ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
|
||||||
debug_printf("BIP6: found interface: %s\n", ifa_tmp->ifa_name);
|
debug_printf("BIP6: found interface: %s\n", ifa_tmp->ifa_name);
|
||||||
}
|
}
|
||||||
if ((ifa_tmp->ifa_addr) &&
|
if ((ifa_tmp->ifa_addr) &&
|
||||||
(ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
|
(ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
|
||||||
(strcasecmp(ifa_tmp->ifa_name,ifname) == 0)) {
|
(strcasecmp(ifa_tmp->ifa_name,ifname) == 0)) {
|
||||||
sin = (struct sockaddr_in6*) ifa_tmp->ifa_addr;
|
sin = (struct sockaddr_in6*) ifa_tmp->ifa_addr;
|
||||||
bvlc6_address_set(&BIP6_Addr,
|
bvlc6_address_set(&BIP6_Addr,
|
||||||
ntohs(sin->sin6_addr.s6_addr16[0]),
|
ntohs(sin->sin6_addr.s6_addr16[0]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[1]),
|
ntohs(sin->sin6_addr.s6_addr16[1]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[2]),
|
ntohs(sin->sin6_addr.s6_addr16[2]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[3]),
|
ntohs(sin->sin6_addr.s6_addr16[3]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[4]),
|
ntohs(sin->sin6_addr.s6_addr16[4]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[5]),
|
ntohs(sin->sin6_addr.s6_addr16[5]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[6]),
|
ntohs(sin->sin6_addr.s6_addr16[6]),
|
||||||
ntohs(sin->sin6_addr.s6_addr16[7]));
|
ntohs(sin->sin6_addr.s6_addr16[7]));
|
||||||
debug_print_ipv6(ifname, (&sin->sin6_addr));
|
debug_print_ipv6(ifname, (&sin->sin6_addr));
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ifa_tmp = ifa_tmp->ifa_next;
|
ifa_tmp = ifa_tmp->ifa_next;
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
debug_printf("BIP6: unable to set interface: %s\n", ifname);
|
debug_printf("BIP6: unable to set interface: %s\n", ifname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the BACnet IPv6 UDP port number
|
* Set the BACnet IPv6 UDP port number
|
||||||
*
|
*
|
||||||
* @param port - IPv6 UDP port number
|
* @param port - IPv6 UDP port number
|
||||||
*/
|
*/
|
||||||
void bip6_set_port(
|
void bip6_set_port(
|
||||||
uint16_t port)
|
uint16_t port)
|
||||||
{
|
{
|
||||||
BIP6_Addr.port = port;
|
BIP6_Addr.port = port;
|
||||||
BIP6_Broadcast_Addr.port = port;
|
BIP6_Broadcast_Addr.port = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the BACnet IPv6 UDP port number
|
* Get the BACnet IPv6 UDP port number
|
||||||
*
|
*
|
||||||
* @return IPv6 UDP port number
|
* @return IPv6 UDP port number
|
||||||
*/
|
*/
|
||||||
uint16_t bip6_get_port(
|
uint16_t bip6_get_port(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
return BIP6_Addr.port;
|
return BIP6_Addr.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the BACnet broadcast address for my interface.
|
* Get the BACnet broadcast address for my interface.
|
||||||
* Used as dest address in messages sent as BROADCAST
|
* Used as dest address in messages sent as BROADCAST
|
||||||
*
|
*
|
||||||
* @param addr - IPv6 source address
|
* @param addr - IPv6 source address
|
||||||
*/
|
*/
|
||||||
void bip6_get_broadcast_address(
|
void bip6_get_broadcast_address(
|
||||||
BACNET_ADDRESS * addr)
|
BACNET_ADDRESS * addr)
|
||||||
{
|
{
|
||||||
if (addr) {
|
if (addr) {
|
||||||
addr->net = BACNET_BROADCAST_NETWORK;
|
addr->net = BACNET_BROADCAST_NETWORK;
|
||||||
addr->mac_len = 0;
|
addr->mac_len = 0;
|
||||||
addr->len = 0;
|
addr->len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IPv6 address for my interface. Used as src address in messages sent.
|
* Get the IPv6 address for my interface. Used as src address in messages sent.
|
||||||
*
|
*
|
||||||
* @param addr - IPv6 source address
|
* @param addr - IPv6 source address
|
||||||
*/
|
*/
|
||||||
void bip6_get_my_address(
|
void bip6_get_my_address(
|
||||||
BACNET_ADDRESS * addr)
|
BACNET_ADDRESS * addr)
|
||||||
{
|
{
|
||||||
uint32_t device_id = 0;
|
uint32_t device_id = 0;
|
||||||
|
|
||||||
if (addr) {
|
if (addr) {
|
||||||
device_id = Device_Object_Instance_Number();
|
device_id = Device_Object_Instance_Number();
|
||||||
bvlc6_vmac_address_set(addr, device_id);
|
bvlc6_vmac_address_set(addr, device_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the BACnet/IP address
|
* Set the BACnet/IP address
|
||||||
*
|
*
|
||||||
* @param addr - network IPv6 address
|
* @param addr - network IPv6 address
|
||||||
*/
|
*/
|
||||||
bool bip6_set_addr(
|
bool bip6_set_addr(
|
||||||
BACNET_IP6_ADDRESS *addr)
|
BACNET_IP6_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
return bvlc6_address_copy(&BIP6_Addr, addr);
|
return bvlc6_address_copy(&BIP6_Addr, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the BACnet/IP address
|
* Get the BACnet/IP address
|
||||||
*
|
*
|
||||||
* @return BACnet/IP address
|
* @return BACnet/IP address
|
||||||
*/
|
*/
|
||||||
bool bip6_get_addr(
|
bool bip6_get_addr(
|
||||||
BACNET_IP6_ADDRESS *addr)
|
BACNET_IP6_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
return bvlc6_address_copy(addr, &BIP6_Addr);
|
return bvlc6_address_copy(addr, &BIP6_Addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the BACnet/IP address
|
* Set the BACnet/IP address
|
||||||
*
|
*
|
||||||
* @param addr - network IPv6 address
|
* @param addr - network IPv6 address
|
||||||
*/
|
*/
|
||||||
bool bip6_set_broadcast_addr(
|
bool bip6_set_broadcast_addr(
|
||||||
BACNET_IP6_ADDRESS *addr)
|
BACNET_IP6_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
return bvlc6_address_copy(&BIP6_Broadcast_Addr, addr);
|
return bvlc6_address_copy(&BIP6_Broadcast_Addr, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the BACnet/IP address
|
* Get the BACnet/IP address
|
||||||
*
|
*
|
||||||
* @return BACnet/IP address
|
* @return BACnet/IP address
|
||||||
*/
|
*/
|
||||||
bool bip6_get_broadcast_addr(
|
bool bip6_get_broadcast_addr(
|
||||||
BACNET_IP6_ADDRESS *addr)
|
BACNET_IP6_ADDRESS *addr)
|
||||||
{
|
{
|
||||||
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
|
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The send function for BACnet/IPv6 driver layer
|
* The send function for BACnet/IPv6 driver layer
|
||||||
*
|
*
|
||||||
* @param dest - Points to a BACNET_IP6_ADDRESS structure containing the
|
* @param dest - Points to a BACNET_IP6_ADDRESS structure containing the
|
||||||
* destination address.
|
* destination address.
|
||||||
* @param mtu - the bytes of data to send
|
* @param mtu - the bytes of data to send
|
||||||
* @param mtu_len - the number of bytes of data to send
|
* @param mtu_len - the number of bytes of data to send
|
||||||
*
|
*
|
||||||
* @return Upon successful completion, returns the number of bytes sent.
|
* @return Upon successful completion, returns the number of bytes sent.
|
||||||
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
* Otherwise, -1 shall be returned and errno set to indicate the error.
|
||||||
*/
|
*/
|
||||||
int bip6_send_mpdu(
|
int bip6_send_mpdu(
|
||||||
BACNET_IP6_ADDRESS *dest,
|
BACNET_IP6_ADDRESS *dest,
|
||||||
uint8_t * mtu,
|
uint8_t * mtu,
|
||||||
uint16_t mtu_len)
|
uint16_t mtu_len)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 bvlc_dest = { 0 };
|
struct sockaddr_in6 bvlc_dest = { 0 };
|
||||||
uint16_t addr16[8];
|
uint16_t addr16[8];
|
||||||
|
|
||||||
/* assumes that the driver has already been initialized */
|
/* assumes that the driver has already been initialized */
|
||||||
if (BIP6_Socket < 0) {
|
if (BIP6_Socket < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* load destination IP address */
|
/* load destination IP address */
|
||||||
bvlc_dest.sin6_family = AF_INET6;
|
bvlc_dest.sin6_family = AF_INET6;
|
||||||
bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3],
|
bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3],
|
||||||
&addr16[4], &addr16[5], &addr16[6], &addr16[7]);
|
&addr16[4], &addr16[5], &addr16[6], &addr16[7]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]);
|
bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]);
|
bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]);
|
bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[3] = htons(addr16[3]);
|
bvlc_dest.sin6_addr.s6_addr16[3] = htons(addr16[3]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[4] = htons(addr16[4]);
|
bvlc_dest.sin6_addr.s6_addr16[4] = htons(addr16[4]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[5] = htons(addr16[5]);
|
bvlc_dest.sin6_addr.s6_addr16[5] = htons(addr16[5]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[6] = htons(addr16[6]);
|
bvlc_dest.sin6_addr.s6_addr16[6] = htons(addr16[6]);
|
||||||
bvlc_dest.sin6_addr.s6_addr16[7] = htons(addr16[7]);
|
bvlc_dest.sin6_addr.s6_addr16[7] = htons(addr16[7]);
|
||||||
bvlc_dest.sin6_port = htons(dest->port);
|
bvlc_dest.sin6_port = htons(dest->port);
|
||||||
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
|
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
|
||||||
/* Send the packet */
|
/* Send the packet */
|
||||||
return sendto(BIP6_Socket, (char *) mtu, mtu_len, 0,
|
return sendto(BIP6_Socket, (char *) mtu, mtu_len, 0,
|
||||||
(struct sockaddr *) &bvlc_dest, sizeof(bvlc_dest));
|
(struct sockaddr *) &bvlc_dest, sizeof(bvlc_dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BACnet/IP Datalink Receive handler.
|
* BACnet/IP Datalink Receive handler.
|
||||||
*
|
*
|
||||||
* @param src - returns the source address
|
* @param src - returns the source address
|
||||||
* @param npdu - returns the NPDU buffer
|
* @param npdu - returns the NPDU buffer
|
||||||
* @param max_npdu -maximum size of the NPDU buffer
|
* @param max_npdu -maximum size of the NPDU buffer
|
||||||
* @param timeout - number of milliseconds to wait for a packet
|
* @param timeout - number of milliseconds to wait for a packet
|
||||||
*
|
*
|
||||||
* @return Number of bytes received, or 0 if none or timeout.
|
* @return Number of bytes received, or 0 if none or timeout.
|
||||||
*/
|
*/
|
||||||
uint16_t bip6_receive(
|
uint16_t bip6_receive(
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
uint8_t * npdu,
|
uint8_t * npdu,
|
||||||
uint16_t max_npdu,
|
uint16_t max_npdu,
|
||||||
unsigned timeout)
|
unsigned timeout)
|
||||||
{
|
{
|
||||||
uint16_t npdu_len = 0; /* return value */
|
uint16_t npdu_len = 0; /* return value */
|
||||||
fd_set read_fds;
|
fd_set read_fds;
|
||||||
int max = 0;
|
int max = 0;
|
||||||
struct timeval select_timeout;
|
struct timeval select_timeout;
|
||||||
struct sockaddr_in6 sin = { 0 };
|
struct sockaddr_in6 sin = { 0 };
|
||||||
BACNET_IP6_ADDRESS addr = {{ 0 }};
|
BACNET_IP6_ADDRESS addr = {{ 0 }};
|
||||||
socklen_t sin_len = sizeof(sin);
|
socklen_t sin_len = sizeof(sin);
|
||||||
int received_bytes = 0;
|
int received_bytes = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
|
|
||||||
/* Make sure the socket is open */
|
/* Make sure the socket is open */
|
||||||
if (BIP6_Socket < 0) {
|
if (BIP6_Socket < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* we could just use a non-blocking socket, but that consumes all
|
/* we could just use a non-blocking socket, but that consumes all
|
||||||
the CPU time. We can use a timeout; it is only supported as
|
the CPU time. We can use a timeout; it is only supported as
|
||||||
a select. */
|
a select. */
|
||||||
if (timeout >= 1000) {
|
if (timeout >= 1000) {
|
||||||
select_timeout.tv_sec = timeout / 1000;
|
select_timeout.tv_sec = timeout / 1000;
|
||||||
select_timeout.tv_usec =
|
select_timeout.tv_usec =
|
||||||
1000 * (timeout - select_timeout.tv_sec * 1000);
|
1000 * (timeout - select_timeout.tv_sec * 1000);
|
||||||
} else {
|
} else {
|
||||||
select_timeout.tv_sec = 0;
|
select_timeout.tv_sec = 0;
|
||||||
select_timeout.tv_usec = 1000 * timeout;
|
select_timeout.tv_usec = 1000 * timeout;
|
||||||
}
|
}
|
||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
FD_SET(BIP6_Socket, &read_fds);
|
FD_SET(BIP6_Socket, &read_fds);
|
||||||
max = BIP6_Socket;
|
max = BIP6_Socket;
|
||||||
/* see if there is a packet for us */
|
/* see if there is a packet for us */
|
||||||
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
|
||||||
received_bytes =
|
received_bytes =
|
||||||
recvfrom(BIP6_Socket, (char *) &npdu[0], max_npdu, 0,
|
recvfrom(BIP6_Socket, (char *) &npdu[0], max_npdu, 0,
|
||||||
(struct sockaddr *) &sin, &sin_len);
|
(struct sockaddr *) &sin, &sin_len);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* See if there is a problem */
|
/* See if there is a problem */
|
||||||
if (received_bytes < 0) {
|
if (received_bytes < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* no problem, just no bytes */
|
/* no problem, just no bytes */
|
||||||
if (received_bytes == 0) {
|
if (received_bytes == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* the signature of a BACnet/IPv6 packet */
|
/* the signature of a BACnet/IPv6 packet */
|
||||||
if (npdu[0] != BVLL_TYPE_BACNET_IP6) {
|
if (npdu[0] != BVLL_TYPE_BACNET_IP6) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* pass the packet into the BBMD handler */
|
/* pass the packet into the BBMD handler */
|
||||||
debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
|
debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
|
||||||
bvlc6_address_set(&addr,
|
bvlc6_address_set(&addr,
|
||||||
ntohs(sin.sin6_addr.s6_addr16[0]),
|
ntohs(sin.sin6_addr.s6_addr16[0]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[1]),
|
ntohs(sin.sin6_addr.s6_addr16[1]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[2]),
|
ntohs(sin.sin6_addr.s6_addr16[2]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[3]),
|
ntohs(sin.sin6_addr.s6_addr16[3]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[4]),
|
ntohs(sin.sin6_addr.s6_addr16[4]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[5]),
|
ntohs(sin.sin6_addr.s6_addr16[5]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[6]),
|
ntohs(sin.sin6_addr.s6_addr16[6]),
|
||||||
ntohs(sin.sin6_addr.s6_addr16[7]));
|
ntohs(sin.sin6_addr.s6_addr16[7]));
|
||||||
addr.port = ntohs(sin.sin6_port);
|
addr.port = ntohs(sin.sin6_port);
|
||||||
offset = bvlc6_handler(&addr, src, npdu, received_bytes);
|
offset = bvlc6_handler(&addr, src, npdu, received_bytes);
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
npdu_len = received_bytes - offset;
|
npdu_len = received_bytes - offset;
|
||||||
if (npdu_len <= max_npdu) {
|
if (npdu_len <= max_npdu) {
|
||||||
/* shift the buffer to return a valid NPDU */
|
/* shift the buffer to return a valid NPDU */
|
||||||
for (i = 0; i < npdu_len; i++) {
|
for (i = 0; i < npdu_len; i++) {
|
||||||
npdu[i] = npdu[offset + i];
|
npdu[i] = npdu[offset + i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
npdu_len = 0;
|
npdu_len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return npdu_len;
|
return npdu_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cleanup and close out the BACnet/IP services by closing the socket.
|
/** Cleanup and close out the BACnet/IP services by closing the socket.
|
||||||
* @ingroup DLBIP6
|
* @ingroup DLBIP6
|
||||||
*/
|
*/
|
||||||
void bip6_cleanup(
|
void bip6_cleanup(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
if (BIP6_Socket != -1) {
|
if (BIP6_Socket != -1) {
|
||||||
close(BIP6_Socket);
|
close(BIP6_Socket);
|
||||||
}
|
}
|
||||||
BIP6_Socket = -1;
|
BIP6_Socket = -1;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Initialize the BACnet/IP services at the given interface.
|
/** Initialize the BACnet/IP services at the given interface.
|
||||||
* @ingroup DLBIP6
|
* @ingroup DLBIP6
|
||||||
* -# Gets the local IP address and local broadcast address from the system,
|
* -# Gets the local IP address and local broadcast address from the system,
|
||||||
* and saves it into the BACnet/IPv6 data structures.
|
* and saves it into the BACnet/IPv6 data structures.
|
||||||
* -# Opens a UDP socket
|
* -# Opens a UDP socket
|
||||||
* -# Configures the socket for sending and receiving
|
* -# Configures the socket for sending and receiving
|
||||||
* -# Configures the socket so it can send multicasts
|
* -# Configures the socket so it can send multicasts
|
||||||
* -# Binds the socket to the local IP address at the specified port for
|
* -# Binds the socket to the local IP address at the specified port for
|
||||||
* BACnet/IPv6 (by default, 0xBAC0 = 47808).
|
* BACnet/IPv6 (by default, 0xBAC0 = 47808).
|
||||||
*
|
*
|
||||||
* @note For Linux, ifname is eth0, ath0, arc0, and others.
|
* @note For Linux, ifname is eth0, ath0, arc0, and others.
|
||||||
*
|
*
|
||||||
* @param ifname [in] The named interface to use for the network layer.
|
* @param ifname [in] The named interface to use for the network layer.
|
||||||
* If NULL, the "eth0" interface is assigned.
|
* If NULL, the "eth0" interface is assigned.
|
||||||
* @return True if the socket is successfully opened for BACnet/IP,
|
* @return True if the socket is successfully opened for BACnet/IP,
|
||||||
* else False if the socket functions fail.
|
* else False if the socket functions fail.
|
||||||
*/
|
*/
|
||||||
bool bip6_init(
|
bool bip6_init(
|
||||||
char *ifname)
|
char *ifname)
|
||||||
{
|
{
|
||||||
int status = 0; /* return from socket lib calls */
|
int status = 0; /* return from socket lib calls */
|
||||||
struct sockaddr_in6 server = {0};
|
struct sockaddr_in6 server = {0};
|
||||||
struct in6_addr broadcast_address;
|
struct in6_addr broadcast_address;
|
||||||
struct ipv6_mreq join_request;
|
struct ipv6_mreq join_request;
|
||||||
int sockopt = 0;
|
int sockopt = 0;
|
||||||
|
|
||||||
if (ifname) {
|
if (ifname) {
|
||||||
bip6_set_interface(ifname);
|
bip6_set_interface(ifname);
|
||||||
} else {
|
} else {
|
||||||
bip6_set_interface("eth0");
|
bip6_set_interface("eth0");
|
||||||
}
|
}
|
||||||
if (BIP6_Addr.port == 0) {
|
if (BIP6_Addr.port == 0) {
|
||||||
bip6_set_port(0xBAC0);
|
bip6_set_port(0xBAC0);
|
||||||
}
|
}
|
||||||
debug_printf("BIP6: IPv6 UDP port: 0x%04X\n", htons(BIP6_Addr.port));
|
debug_printf("BIP6: IPv6 UDP port: 0x%04X\n", htons(BIP6_Addr.port));
|
||||||
if (BIP6_Broadcast_Addr.address[0] == 0) {
|
if (BIP6_Broadcast_Addr.address[0] == 0) {
|
||||||
bvlc6_address_set(&BIP6_Broadcast_Addr,
|
bvlc6_address_set(&BIP6_Broadcast_Addr,
|
||||||
BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
|
BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
|
||||||
BIP6_MULTICAST_GROUP_ID);
|
BIP6_MULTICAST_GROUP_ID);
|
||||||
}
|
}
|
||||||
/* assumes that the driver has already been initialized */
|
/* assumes that the driver has already been initialized */
|
||||||
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (BIP6_Socket < 0)
|
if (BIP6_Socket < 0)
|
||||||
return false;
|
return false;
|
||||||
/* Allow us to use the same socket for sending and receiving */
|
/* Allow us to use the same socket for sending and receiving */
|
||||||
/* This makes sure that the src port is correct when sending */
|
/* This makes sure that the src port is correct when sending */
|
||||||
sockopt = 1;
|
sockopt = 1;
|
||||||
status =
|
status =
|
||||||
setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt,
|
setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt,
|
||||||
sizeof(sockopt));
|
sizeof(sockopt));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
close(BIP6_Socket);
|
close(BIP6_Socket);
|
||||||
BIP6_Socket = -1;
|
BIP6_Socket = -1;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/* allow us to send a broadcast */
|
/* allow us to send a broadcast */
|
||||||
status =
|
status =
|
||||||
setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt,
|
setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt,
|
||||||
sizeof(sockopt));
|
sizeof(sockopt));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
close(BIP6_Socket);
|
close(BIP6_Socket);
|
||||||
BIP6_Socket = -1;
|
BIP6_Socket = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* subscribe to a multicast address */
|
/* subscribe to a multicast address */
|
||||||
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], IP6_ADDRESS_MAX);
|
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], IP6_ADDRESS_MAX);
|
||||||
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address, sizeof(struct in6_addr));
|
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address, sizeof(struct in6_addr));
|
||||||
/* Let system choose the interface */
|
/* Let system choose the interface */
|
||||||
join_request.ipv6mr_interface = 0;
|
join_request.ipv6mr_interface = 0;
|
||||||
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||||
&join_request, sizeof(join_request));
|
&join_request, sizeof(join_request));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
perror("BIP: setsockopt(IPV6_JOIN_GROUP)");
|
perror("BIP: setsockopt(IPV6_JOIN_GROUP)");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bind the socket to the local port number and IP address */
|
/* bind the socket to the local port number and IP address */
|
||||||
server.sin6_family = AF_INET6;
|
server.sin6_family = AF_INET6;
|
||||||
server.sin6_addr = in6addr_any;
|
server.sin6_addr = in6addr_any;
|
||||||
server.sin6_port = htons(BIP6_Addr.port);
|
server.sin6_port = htons(BIP6_Addr.port);
|
||||||
status = bind(BIP6_Socket, (const void*)&server, sizeof(server));
|
status = bind(BIP6_Socket, (const void*)&server, sizeof(server));
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
perror("BIP: bind");
|
perror("BIP: bind");
|
||||||
close(BIP6_Socket);
|
close(BIP6_Socket);
|
||||||
BIP6_Socket = -1;
|
BIP6_Socket = -1;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bvlc6_init();
|
bvlc6_init();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,98 +1,98 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
# Visual C++ Express 2010
|
# Visual C++ Express 2010
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet Stack Library", "BACnet Stack Library\BACnet Stack Library.vcxproj", "{E9A65567-B028-4278-881D-674604B2E126}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet Stack Library", "BACnet Stack Library\BACnet Stack Library.vcxproj", "{E9A65567-B028-4278-881D-674604B2E126}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet Object Definitions", "BACnet Object Definitions\BACnet Object Definitions.vcxproj", "{6A8668E1-F08E-496B-B624-D6C05001806D}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet Object Definitions", "BACnet Object Definitions\BACnet Object Definitions.vcxproj", "{6A8668E1-F08E-496B-B624-D6C05001806D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server\Server.vcxproj", "{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Server", "Server\Server.vcxproj", "{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacwi", "Who-Is\Who-Is.vcxproj", "{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacwi", "Who-Is\Who-Is.vcxproj", "{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacdcc", "dcc\dcc.vcxproj", "{CC217FCF-AEF6-4859-8452-1E222C393383}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacdcc", "dcc\dcc.vcxproj", "{CC217FCF-AEF6-4859-8452-1E222C393383}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet Handler Library", "BACnet Handler Library\BACnet Handler Library.vcxproj", "{9D4C3515-CA91-4C54-93DC-9962A3139A38}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet Handler Library", "BACnet Handler Library\BACnet Handler Library.vcxproj", "{9D4C3515-CA91-4C54-93DC-9962A3139A38}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacwp", "writeprop\writeprop.vcxproj", "{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacwp", "writeprop\writeprop.vcxproj", "{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
||||||
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacwir", "bacwir\bacwir.vcxproj", "{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacwir", "bacwir\bacwir.vcxproj", "{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacrp", "bacrp\bacrp.vcxproj", "{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacrp", "bacrp\bacrp.vcxproj", "{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38} = {9D4C3515-CA91-4C54-93DC-9962A3139A38}
|
||||||
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
{E9A65567-B028-4278-881D-674604B2E126} = {E9A65567-B028-4278-881D-674604B2E126}
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
{6A8668E1-F08E-496B-B624-D6C05001806D} = {6A8668E1-F08E-496B-B624-D6C05001806D}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacepics", "bacepics\bacepics.vcxproj", "{17BEB9AD-5DA8-4B49-9369-B6715831C381}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bacepics", "bacepics\bacepics.vcxproj", "{17BEB9AD-5DA8-4B49-9369-B6715831C381}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Win32 = Debug|Win32
|
Debug|Win32 = Debug|Win32
|
||||||
Release|Win32 = Release|Win32
|
Release|Win32 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{E9A65567-B028-4278-881D-674604B2E126}.Debug|Win32.ActiveCfg = Debug|Win32
|
{E9A65567-B028-4278-881D-674604B2E126}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{E9A65567-B028-4278-881D-674604B2E126}.Debug|Win32.Build.0 = Debug|Win32
|
{E9A65567-B028-4278-881D-674604B2E126}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{E9A65567-B028-4278-881D-674604B2E126}.Release|Win32.ActiveCfg = Release|Win32
|
{E9A65567-B028-4278-881D-674604B2E126}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{E9A65567-B028-4278-881D-674604B2E126}.Release|Win32.Build.0 = Release|Win32
|
{E9A65567-B028-4278-881D-674604B2E126}.Release|Win32.Build.0 = Release|Win32
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D}.Debug|Win32.ActiveCfg = Debug|Win32
|
{6A8668E1-F08E-496B-B624-D6C05001806D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D}.Debug|Win32.Build.0 = Debug|Win32
|
{6A8668E1-F08E-496B-B624-D6C05001806D}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D}.Release|Win32.ActiveCfg = Release|Win32
|
{6A8668E1-F08E-496B-B624-D6C05001806D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{6A8668E1-F08E-496B-B624-D6C05001806D}.Release|Win32.Build.0 = Release|Win32
|
{6A8668E1-F08E-496B-B624-D6C05001806D}.Release|Win32.Build.0 = Release|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|Win32.ActiveCfg = Debug|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|Win32.Build.0 = Debug|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|Win32.ActiveCfg = Release|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|Win32.Build.0 = Release|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|Win32.Build.0 = Release|Win32
|
||||||
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Debug|Win32.ActiveCfg = Debug|Win32
|
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Debug|Win32.Build.0 = Debug|Win32
|
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Release|Win32.ActiveCfg = Release|Win32
|
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Release|Win32.Build.0 = Release|Win32
|
{A6287B6E-0BCE-43FA-ADFB-9263DB069BA4}.Release|Win32.Build.0 = Release|Win32
|
||||||
{CC217FCF-AEF6-4859-8452-1E222C393383}.Debug|Win32.ActiveCfg = Debug|Win32
|
{CC217FCF-AEF6-4859-8452-1E222C393383}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{CC217FCF-AEF6-4859-8452-1E222C393383}.Debug|Win32.Build.0 = Debug|Win32
|
{CC217FCF-AEF6-4859-8452-1E222C393383}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{CC217FCF-AEF6-4859-8452-1E222C393383}.Release|Win32.ActiveCfg = Release|Win32
|
{CC217FCF-AEF6-4859-8452-1E222C393383}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{CC217FCF-AEF6-4859-8452-1E222C393383}.Release|Win32.Build.0 = Release|Win32
|
{CC217FCF-AEF6-4859-8452-1E222C393383}.Release|Win32.Build.0 = Release|Win32
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Debug|Win32.ActiveCfg = Debug|Win32
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Debug|Win32.Build.0 = Debug|Win32
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Release|Win32.ActiveCfg = Release|Win32
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Release|Win32.Build.0 = Release|Win32
|
{9D4C3515-CA91-4C54-93DC-9962A3139A38}.Release|Win32.Build.0 = Release|Win32
|
||||||
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Debug|Win32.ActiveCfg = Debug|Win32
|
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Debug|Win32.Build.0 = Debug|Win32
|
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Release|Win32.ActiveCfg = Release|Win32
|
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Release|Win32.Build.0 = Release|Win32
|
{826EF765-7828-44D3-B8AF-7AEDBAA8E0D2}.Release|Win32.Build.0 = Release|Win32
|
||||||
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Debug|Win32.ActiveCfg = Debug|Win32
|
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Debug|Win32.Build.0 = Debug|Win32
|
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Release|Win32.ActiveCfg = Release|Win32
|
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Release|Win32.Build.0 = Release|Win32
|
{7E30D4FE-B8A7-442D-B6FB-E8DC3129EFEB}.Release|Win32.Build.0 = Release|Win32
|
||||||
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Debug|Win32.ActiveCfg = Debug|Win32
|
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Debug|Win32.Build.0 = Debug|Win32
|
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Release|Win32.ActiveCfg = Release|Win32
|
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Release|Win32.Build.0 = Release|Win32
|
{2DED9AEF-13AB-408B-B914-F7F30AE15EC0}.Release|Win32.Build.0 = Release|Win32
|
||||||
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Debug|Win32.ActiveCfg = Debug|Win32
|
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Debug|Win32.Build.0 = Debug|Win32
|
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Release|Win32.ActiveCfg = Release|Win32
|
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Release|Win32.Build.0 = Release|Win32
|
{17BEB9AD-5DA8-4B49-9369-B6715831C381}.Release|Win32.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -1,57 +1,57 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 14
|
# Visual Studio 14
|
||||||
VisualStudioVersion = 14.0.24720.0
|
VisualStudioVersion = 14.0.24720.0
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet_Handler_Library", "BACnet_Handler_Library\BACnet_Handler_Library.vcxproj", "{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet_Handler_Library", "BACnet_Handler_Library\BACnet_Handler_Library.vcxproj", "{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet_Object_Definitions", "BACnet_Object_Definitions\BACnet_Object_Definitions.vcxproj", "{6D42B11A-84DA-46DB-9D08-319329D51473}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet_Object_Definitions", "BACnet_Object_Definitions\BACnet_Object_Definitions.vcxproj", "{6D42B11A-84DA-46DB-9D08-319329D51473}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet_Stack_Library", "BACnet_Stack_Library\BACnet_Stack_Library.vcxproj", "{D0875CC6-8B68-404C-ABD7-823FE0C084DD}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BACnet_Stack_Library", "BACnet_Stack_Library\BACnet_Stack_Library.vcxproj", "{D0875CC6-8B68-404C-ABD7-823FE0C084DD}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "Server\Server.vcxproj", "{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server", "Server\Server.vcxproj", "{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
Debug|x86 = Debug|x86
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x64.ActiveCfg = Debug|x64
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x64.Build.0 = Debug|x64
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x64.Build.0 = Debug|x64
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x86.ActiveCfg = Debug|Win32
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x86.Build.0 = Debug|Win32
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Debug|x86.Build.0 = Debug|Win32
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x64.ActiveCfg = Release|x64
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x64.ActiveCfg = Release|x64
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x64.Build.0 = Release|x64
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x64.Build.0 = Release|x64
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x86.ActiveCfg = Release|Win32
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x86.Build.0 = Release|Win32
|
{2001A15D-2D0E-4FFA-8B90-5E7938AE6ECF}.Release|x86.Build.0 = Release|Win32
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x64.ActiveCfg = Debug|x64
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x64.Build.0 = Debug|x64
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x64.Build.0 = Debug|x64
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x86.ActiveCfg = Debug|Win32
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x86.Build.0 = Debug|Win32
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Debug|x86.Build.0 = Debug|Win32
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x64.ActiveCfg = Release|x64
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x64.ActiveCfg = Release|x64
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x64.Build.0 = Release|x64
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x64.Build.0 = Release|x64
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x86.ActiveCfg = Release|Win32
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x86.Build.0 = Release|Win32
|
{6D42B11A-84DA-46DB-9D08-319329D51473}.Release|x86.Build.0 = Release|Win32
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x64.ActiveCfg = Debug|x64
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x64.Build.0 = Debug|x64
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x64.Build.0 = Debug|x64
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x86.ActiveCfg = Debug|Win32
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x86.Build.0 = Debug|Win32
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Debug|x86.Build.0 = Debug|Win32
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x64.ActiveCfg = Release|x64
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x64.ActiveCfg = Release|x64
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x64.Build.0 = Release|x64
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x64.Build.0 = Release|x64
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x86.ActiveCfg = Release|Win32
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x86.Build.0 = Release|Win32
|
{D0875CC6-8B68-404C-ABD7-823FE0C084DD}.Release|x86.Build.0 = Release|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x64.ActiveCfg = Debug|x64
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x64.Build.0 = Debug|x64
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x64.Build.0 = Debug|x64
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x86.ActiveCfg = Debug|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x86.Build.0 = Debug|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Debug|x86.Build.0 = Debug|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|x64.ActiveCfg = Release|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|x64.ActiveCfg = Release|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|x86.ActiveCfg = Release|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|x86.Build.0 = Release|Win32
|
{EF250061-B9E3-4EEF-8C87-4AB52AF30B3E}.Release|x86.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
+528
-528
File diff suppressed because it is too large
Load Diff
@@ -1,459 +1,459 @@
|
|||||||
# List of available make goals:
|
# List of available make goals:
|
||||||
#
|
#
|
||||||
# all Default target, builds the project
|
# all Default target, builds the project
|
||||||
# clean Clean up the project
|
# clean Clean up the project
|
||||||
# rebuild Rebuild the project
|
# rebuild Rebuild the project
|
||||||
#
|
#
|
||||||
# doc Build the documentation
|
# doc Build the documentation
|
||||||
# cleandoc Clean up the documentation
|
# cleandoc Clean up the documentation
|
||||||
# rebuilddoc Rebuild the documentation
|
# rebuilddoc Rebuild the documentation
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
|
# Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
|
||||||
#
|
#
|
||||||
# \asf_license_start
|
# \asf_license_start
|
||||||
#
|
#
|
||||||
# \page License
|
# \page License
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# modification, are permitted provided that the following conditions are met:
|
# modification, are permitted provided that the following conditions are met:
|
||||||
#
|
#
|
||||||
# 1. Redistributions of source code must retain the above copyright notice,
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer.
|
# this list of conditions and the following disclaimer.
|
||||||
#
|
#
|
||||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
# this list of conditions and the following disclaimer in the documentation
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
# and/or other materials provided with the distribution.
|
# and/or other materials provided with the distribution.
|
||||||
#
|
#
|
||||||
# 3. The name of Atmel may not be used to endorse or promote products derived
|
# 3. The name of Atmel may not be used to endorse or promote products derived
|
||||||
# from this software without specific prior written permission.
|
# from this software without specific prior written permission.
|
||||||
#
|
#
|
||||||
# 4. This software may only be redistributed and used in connection with an
|
# 4. This software may only be redistributed and used in connection with an
|
||||||
# Atmel microcontroller product.
|
# Atmel microcontroller product.
|
||||||
#
|
#
|
||||||
# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
# THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||||
# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
# EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
#
|
#
|
||||||
# \asf_license_stop
|
# \asf_license_stop
|
||||||
#
|
#
|
||||||
|
|
||||||
# Include the config.mk file from the current working path, e.g., where the
|
# Include the config.mk file from the current working path, e.g., where the
|
||||||
# user called make.
|
# user called make.
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
# Tool to use to generate documentation from the source code
|
# Tool to use to generate documentation from the source code
|
||||||
DOCGEN ?= doxygen
|
DOCGEN ?= doxygen
|
||||||
|
|
||||||
# Look for source files relative to the top-level source directory
|
# Look for source files relative to the top-level source directory
|
||||||
VPATH := $(PRJ_PATH)
|
VPATH := $(PRJ_PATH)
|
||||||
|
|
||||||
# Output target file
|
# Output target file
|
||||||
target := $(TARGET)
|
target := $(TARGET)
|
||||||
|
|
||||||
# Output project name (target name minus suffix)
|
# Output project name (target name minus suffix)
|
||||||
project := $(basename $(target))
|
project := $(basename $(target))
|
||||||
|
|
||||||
# Output target file (typically ELF or static library)
|
# Output target file (typically ELF or static library)
|
||||||
ifeq ($(suffix $(target)),.a)
|
ifeq ($(suffix $(target)),.a)
|
||||||
target_type := lib
|
target_type := lib
|
||||||
else
|
else
|
||||||
ifeq ($(suffix $(target)),.elf)
|
ifeq ($(suffix $(target)),.elf)
|
||||||
target_type := elf
|
target_type := elf
|
||||||
else
|
else
|
||||||
$(error "Target type $(target_type) is not supported")
|
$(error "Target type $(target_type) is not supported")
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Allow override of operating system detection. The user can add OS=Linux or
|
# Allow override of operating system detection. The user can add OS=Linux or
|
||||||
# OS=Windows on the command line to explicit set the host OS.
|
# OS=Windows on the command line to explicit set the host OS.
|
||||||
#
|
#
|
||||||
# This allows to work around broken uname utility on certain systems.
|
# This allows to work around broken uname utility on certain systems.
|
||||||
ifdef OS
|
ifdef OS
|
||||||
ifeq ($(strip $(OS)), Linux)
|
ifeq ($(strip $(OS)), Linux)
|
||||||
os_type := Linux
|
os_type := Linux
|
||||||
endif
|
endif
|
||||||
ifeq ($(strip $(OS)), Windows)
|
ifeq ($(strip $(OS)), Windows)
|
||||||
os_type := windows32_64
|
os_type := windows32_64
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
os_type ?= $(strip $(shell uname))
|
os_type ?= $(strip $(shell uname))
|
||||||
|
|
||||||
ifeq ($(os_type),windows32)
|
ifeq ($(os_type),windows32)
|
||||||
os := Windows
|
os := Windows
|
||||||
else
|
else
|
||||||
ifeq ($(os_type),windows64)
|
ifeq ($(os_type),windows64)
|
||||||
os := Windows
|
os := Windows
|
||||||
else
|
else
|
||||||
ifeq ($(os_type),windows32_64)
|
ifeq ($(os_type),windows32_64)
|
||||||
os ?= Windows
|
os ?= Windows
|
||||||
else
|
else
|
||||||
ifeq ($(os_type),)
|
ifeq ($(os_type),)
|
||||||
os := Windows
|
os := Windows
|
||||||
else
|
else
|
||||||
# Default to Linux style operating system. Both Cygwin and mingw are fully
|
# Default to Linux style operating system. Both Cygwin and mingw are fully
|
||||||
# compatible (for this Makefile) with Linux.
|
# compatible (for this Makefile) with Linux.
|
||||||
os := Linux
|
os := Linux
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Output documentation directory and configuration file.
|
# Output documentation directory and configuration file.
|
||||||
docdir := ../doxygen/html
|
docdir := ../doxygen/html
|
||||||
doccfg := ../doxygen/doxyfile.doxygen
|
doccfg := ../doxygen/doxyfile.doxygen
|
||||||
|
|
||||||
CROSS ?= avr-
|
CROSS ?= avr-
|
||||||
AR := $(CROSS)ar
|
AR := $(CROSS)ar
|
||||||
AS := $(CROSS)as
|
AS := $(CROSS)as
|
||||||
CC := $(CROSS)gcc
|
CC := $(CROSS)gcc
|
||||||
CPP := $(CROSS)gcc -E
|
CPP := $(CROSS)gcc -E
|
||||||
CXX := $(CROSS)g++
|
CXX := $(CROSS)g++
|
||||||
LD := $(CROSS)g++
|
LD := $(CROSS)g++
|
||||||
NM := $(CROSS)nm
|
NM := $(CROSS)nm
|
||||||
OBJCOPY := $(CROSS)objcopy
|
OBJCOPY := $(CROSS)objcopy
|
||||||
OBJDUMP := $(CROSS)objdump
|
OBJDUMP := $(CROSS)objdump
|
||||||
SIZE := $(CROSS)size
|
SIZE := $(CROSS)size
|
||||||
|
|
||||||
RM := rm
|
RM := rm
|
||||||
ifeq ($(os),Windows)
|
ifeq ($(os),Windows)
|
||||||
RMDIR := rmdir /S /Q
|
RMDIR := rmdir /S /Q
|
||||||
else
|
else
|
||||||
RMDIR := rmdir -p --ignore-fail-on-non-empty
|
RMDIR := rmdir -p --ignore-fail-on-non-empty
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Strings for beautifying output
|
# Strings for beautifying output
|
||||||
MSG_CLEAN_FILES = "RM *.o *.d"
|
MSG_CLEAN_FILES = "RM *.o *.d"
|
||||||
MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))"
|
MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))"
|
||||||
MSG_CLEAN_DOC = "RMDIR $(docdir)"
|
MSG_CLEAN_DOC = "RMDIR $(docdir)"
|
||||||
MSG_MKDIR = "MKDIR $(dir $@)"
|
MSG_MKDIR = "MKDIR $(dir $@)"
|
||||||
|
|
||||||
MSG_INFO = "INFO "
|
MSG_INFO = "INFO "
|
||||||
|
|
||||||
MSG_ARCHIVING = "AR $@"
|
MSG_ARCHIVING = "AR $@"
|
||||||
MSG_ASSEMBLING = "AS $@"
|
MSG_ASSEMBLING = "AS $@"
|
||||||
MSG_BINARY_IMAGE = "OBJCOPY $@"
|
MSG_BINARY_IMAGE = "OBJCOPY $@"
|
||||||
MSG_COMPILING = "CC $@"
|
MSG_COMPILING = "CC $@"
|
||||||
MSG_COMPILING_CXX = "CXX $@"
|
MSG_COMPILING_CXX = "CXX $@"
|
||||||
MSG_EEPROM_IMAGE = "OBJCOPY $@"
|
MSG_EEPROM_IMAGE = "OBJCOPY $@"
|
||||||
MSG_EXTENDED_LISTING = "OBJDUMP $@"
|
MSG_EXTENDED_LISTING = "OBJDUMP $@"
|
||||||
MSG_IHEX_IMAGE = "OBJCOPY $@"
|
MSG_IHEX_IMAGE = "OBJCOPY $@"
|
||||||
MSG_LINKING = "LN $@"
|
MSG_LINKING = "LN $@"
|
||||||
MSG_PREPROCESSING = "CPP $@"
|
MSG_PREPROCESSING = "CPP $@"
|
||||||
MSG_SIZE = "SIZE $@"
|
MSG_SIZE = "SIZE $@"
|
||||||
MSG_SYMBOL_TABLE = "NM $@"
|
MSG_SYMBOL_TABLE = "NM $@"
|
||||||
|
|
||||||
MSG_GENERATING_DOC = "DOXYGEN $(docdir)"
|
MSG_GENERATING_DOC = "DOXYGEN $(docdir)"
|
||||||
|
|
||||||
# Don't use make's built-in rules and variables
|
# Don't use make's built-in rules and variables
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
|
|
||||||
# Don't print 'Entering directory ...'
|
# Don't print 'Entering directory ...'
|
||||||
MAKEFLAGS += --no-print-directory
|
MAKEFLAGS += --no-print-directory
|
||||||
|
|
||||||
# Function for reversing the order of a list
|
# Function for reversing the order of a list
|
||||||
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
|
reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1))
|
||||||
|
|
||||||
# Hide command output by default, but allow the user to override this
|
# Hide command output by default, but allow the user to override this
|
||||||
# by adding V=1 on the command line.
|
# by adding V=1 on the command line.
|
||||||
#
|
#
|
||||||
# This is inspired by the Kbuild system used by the Linux kernel.
|
# This is inspired by the Kbuild system used by the Linux kernel.
|
||||||
ifdef V
|
ifdef V
|
||||||
ifeq ("$(origin V)", "command line")
|
ifeq ("$(origin V)", "command line")
|
||||||
VERBOSE = $(V)
|
VERBOSE = $(V)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifndef VERBOSE
|
ifndef VERBOSE
|
||||||
VERBOSE = 0
|
VERBOSE = 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(VERBOSE), 1)
|
ifeq ($(VERBOSE), 1)
|
||||||
Q =
|
Q =
|
||||||
else
|
else
|
||||||
Q = @
|
Q = @
|
||||||
endif
|
endif
|
||||||
|
|
||||||
arflags-gnu-y := $(ARFLAGS)
|
arflags-gnu-y := $(ARFLAGS)
|
||||||
asflags-gnu-y := $(ASFLAGS)
|
asflags-gnu-y := $(ASFLAGS)
|
||||||
cflags-gnu-y := $(CFLAGS)
|
cflags-gnu-y := $(CFLAGS)
|
||||||
cxxflags-gnu-y := $(CXXFLAGS)
|
cxxflags-gnu-y := $(CXXFLAGS)
|
||||||
cppflags-gnu-y := $(CPPFLAGS)
|
cppflags-gnu-y := $(CPPFLAGS)
|
||||||
cpuflags-gnu-y :=
|
cpuflags-gnu-y :=
|
||||||
dbgflags-gnu-y := $(DBGFLAGS)
|
dbgflags-gnu-y := $(DBGFLAGS)
|
||||||
libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB))
|
libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB))
|
||||||
ldflags-gnu-y := $(LDFLAGS)
|
ldflags-gnu-y := $(LDFLAGS)
|
||||||
flashflags-gnu-y := $(FLASHFLAGS)
|
flashflags-gnu-y := $(FLASHFLAGS)
|
||||||
eepromflags-gnu-y := $(EEPROMFLAGS)
|
eepromflags-gnu-y := $(EEPROMFLAGS)
|
||||||
clean-files :=
|
clean-files :=
|
||||||
clean-dirs :=
|
clean-dirs :=
|
||||||
|
|
||||||
clean-files += $(wildcard $(target) $(project).map)
|
clean-files += $(wildcard $(target) $(project).map)
|
||||||
clean-files += $(wildcard $(project).hex $(project).eep)
|
clean-files += $(wildcard $(project).hex $(project).eep)
|
||||||
clean-files += $(wildcard $(project).lss $(project).sym)
|
clean-files += $(wildcard $(project).lss $(project).sym)
|
||||||
clean-files += $(wildcard $(build))
|
clean-files += $(wildcard $(build))
|
||||||
|
|
||||||
# Use pipes instead of temporary files for communication between processes
|
# Use pipes instead of temporary files for communication between processes
|
||||||
cflags-gnu-y += -pipe
|
cflags-gnu-y += -pipe
|
||||||
asflags-gnu-y += -pipe
|
asflags-gnu-y += -pipe
|
||||||
ldflags-gnu-y += -pipe
|
ldflags-gnu-y += -pipe
|
||||||
|
|
||||||
# Archiver flags.
|
# Archiver flags.
|
||||||
arflags-gnu-y += rcs
|
arflags-gnu-y += rcs
|
||||||
|
|
||||||
# Always enable warnings. And be very careful about implicit
|
# Always enable warnings. And be very careful about implicit
|
||||||
# declarations.
|
# declarations.
|
||||||
cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes
|
cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes
|
||||||
cflags-gnu-y += -Werror-implicit-function-declaration
|
cflags-gnu-y += -Werror-implicit-function-declaration
|
||||||
cxxflags-gnu-y += -Wall
|
cxxflags-gnu-y += -Wall
|
||||||
# IAR doesn't allow arithmetic on void pointers, so warn about that.
|
# IAR doesn't allow arithmetic on void pointers, so warn about that.
|
||||||
cflags-gnu-y += -Wpointer-arith
|
cflags-gnu-y += -Wpointer-arith
|
||||||
cxxflags-gnu-y += -Wpointer-arith
|
cxxflags-gnu-y += -Wpointer-arith
|
||||||
|
|
||||||
# Preprocessor flags.
|
# Preprocessor flags.
|
||||||
cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC))
|
cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC))
|
||||||
asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)')
|
asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)')
|
||||||
|
|
||||||
# CPU specific flags.
|
# CPU specific flags.
|
||||||
cpuflags-gnu-y += -mmcu=$(MCU)
|
cpuflags-gnu-y += -mmcu=$(MCU)
|
||||||
|
|
||||||
# Dependency file flags.
|
# Dependency file flags.
|
||||||
depflags = -MD -MP -MQ $@
|
depflags = -MD -MP -MQ $@
|
||||||
|
|
||||||
# Debug specific flags.
|
# Debug specific flags.
|
||||||
ifdef BUILD_DEBUG_LEVEL
|
ifdef BUILD_DEBUG_LEVEL
|
||||||
dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL)
|
dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL)
|
||||||
else
|
else
|
||||||
dbgflags-gnu-y += -gdwarf-2
|
dbgflags-gnu-y += -gdwarf-2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Optimization specific flags.
|
# Optimization specific flags.
|
||||||
ifdef BUILD_OPTIMIZATION
|
ifdef BUILD_OPTIMIZATION
|
||||||
optflags-gnu-y = -O$(BUILD_OPTIMIZATION)
|
optflags-gnu-y = -O$(BUILD_OPTIMIZATION)
|
||||||
else
|
else
|
||||||
optflags-gnu-y = $(OPTIMIZATION)
|
optflags-gnu-y = $(OPTIMIZATION)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Relax compilation and linking.
|
# Relax compilation and linking.
|
||||||
cflags-gnu-y += -mrelax
|
cflags-gnu-y += -mrelax
|
||||||
cxxflags-gnu-y += -mrelax
|
cxxflags-gnu-y += -mrelax
|
||||||
asflags-gnu-y += -mrelax
|
asflags-gnu-y += -mrelax
|
||||||
ldflags-gnu-y += -Wl,--relax
|
ldflags-gnu-y += -Wl,--relax
|
||||||
|
|
||||||
# Always preprocess assembler files.
|
# Always preprocess assembler files.
|
||||||
asflags-gnu-y += -x assembler-with-cpp
|
asflags-gnu-y += -x assembler-with-cpp
|
||||||
# Compile C files using the GNU99 standard.
|
# Compile C files using the GNU99 standard.
|
||||||
cflags-gnu-y += -std=gnu99
|
cflags-gnu-y += -std=gnu99
|
||||||
# Compile C++ files using the GNU++98 standard.
|
# Compile C++ files using the GNU++98 standard.
|
||||||
cxxflags-gnu-y += -std=gnu++98
|
cxxflags-gnu-y += -std=gnu++98
|
||||||
|
|
||||||
# Use unsigned character type when compiling.
|
# Use unsigned character type when compiling.
|
||||||
cflags-gnu-y += -funsigned-char
|
cflags-gnu-y += -funsigned-char
|
||||||
cxxflags-gnu-y += -funsigned-char
|
cxxflags-gnu-y += -funsigned-char
|
||||||
|
|
||||||
# Don't use strict aliasing (very common in embedded applications).
|
# Don't use strict aliasing (very common in embedded applications).
|
||||||
cflags-gnu-y += -fno-strict-aliasing
|
cflags-gnu-y += -fno-strict-aliasing
|
||||||
cxxflags-gnu-y += -fno-strict-aliasing
|
cxxflags-gnu-y += -fno-strict-aliasing
|
||||||
|
|
||||||
# Separate each function and data into its own separate section to allow
|
# Separate each function and data into its own separate section to allow
|
||||||
# garbage collection of unused sections.
|
# garbage collection of unused sections.
|
||||||
cflags-gnu-y += -ffunction-sections -fdata-sections
|
cflags-gnu-y += -ffunction-sections -fdata-sections
|
||||||
cxxflags-gnu-y += -ffunction-sections -fdata-sections
|
cxxflags-gnu-y += -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
# Garbage collect unreferred sections when linking.
|
# Garbage collect unreferred sections when linking.
|
||||||
ldflags-gnu-y += -Wl,--gc-sections
|
ldflags-gnu-y += -Wl,--gc-sections
|
||||||
|
|
||||||
# Output a link map file and a cross reference table
|
# Output a link map file and a cross reference table
|
||||||
ldflags-gnu-y += -Wl,-Map=$(project).map,--cref
|
ldflags-gnu-y += -Wl,-Map=$(project).map,--cref
|
||||||
|
|
||||||
# Add library search paths relative to the top level directory.
|
# Add library search paths relative to the top level directory.
|
||||||
ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH))
|
ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH))
|
||||||
|
|
||||||
a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__
|
a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__
|
||||||
c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y)
|
c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y)
|
||||||
cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y)
|
cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y)
|
||||||
l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y)
|
l_flags = $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y)
|
||||||
ar_flags = $(arflags-gnu-y)
|
ar_flags = $(arflags-gnu-y)
|
||||||
|
|
||||||
# Intel Hex file production flags
|
# Intel Hex file production flags
|
||||||
flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table
|
flashflags-gnu-y += -R .eeprom -R .usb_descriptor_table
|
||||||
|
|
||||||
# Eeprom file production flags
|
# Eeprom file production flags
|
||||||
eepromflags-gnu-y += -j .eeprom
|
eepromflags-gnu-y += -j .eeprom
|
||||||
eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load"
|
eepromflags-gnu-y += --set-section-flags=.eeprom="alloc,load"
|
||||||
eepromflags-gnu-y += --change-section-lma .eeprom=0
|
eepromflags-gnu-y += --change-section-lma .eeprom=0
|
||||||
|
|
||||||
# Source files list and part informations must already be included before
|
# Source files list and part informations must already be included before
|
||||||
# running this makefile
|
# running this makefile
|
||||||
|
|
||||||
# If a custom build directory is specified, use it -- force trailing / in directory name.
|
# If a custom build directory is specified, use it -- force trailing / in directory name.
|
||||||
ifdef BUILD_DIR
|
ifdef BUILD_DIR
|
||||||
build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/)
|
build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/)
|
||||||
else
|
else
|
||||||
build-dir =
|
build-dir =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Create object files list from source files list.
|
# Create object files list from source files list.
|
||||||
obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS))))
|
obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS))))
|
||||||
|
|
||||||
# Create dependency files list from source files list.
|
# Create dependency files list from source files list.
|
||||||
dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d))
|
dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d))
|
||||||
|
|
||||||
clean-files += $(wildcard $(obj-y))
|
clean-files += $(wildcard $(obj-y))
|
||||||
clean-files += $(dep-files)
|
clean-files += $(dep-files)
|
||||||
|
|
||||||
clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y)))))
|
clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y)))))
|
||||||
|
|
||||||
# Default target.
|
# Default target.
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
ifeq ($(target_type),lib)
|
ifeq ($(target_type),lib)
|
||||||
all: $(target) $(project).lss $(project).sym
|
all: $(target) $(project).lss $(project).sym
|
||||||
else
|
else
|
||||||
ifeq ($(target_type),elf)
|
ifeq ($(target_type),elf)
|
||||||
all: $(target) $(project).hex $(project).lss $(project).sym
|
all: $(target) $(project).hex $(project).lss $(project).sym
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Clean up the project.
|
# Clean up the project.
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
@$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES))
|
@$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES))
|
||||||
$(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),)
|
$(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),)
|
||||||
@$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS))
|
@$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS))
|
||||||
# Remove created directories, and make sure we only remove existing
|
# Remove created directories, and make sure we only remove existing
|
||||||
# directories, since recursive rmdir might help us a bit on the way.
|
# directories, since recursive rmdir might help us a bit on the way.
|
||||||
ifeq ($(os),Windows)
|
ifeq ($(os),Windows)
|
||||||
$(Q)$(if $(strip $(clean-dirs)), \
|
$(Q)$(if $(strip $(clean-dirs)), \
|
||||||
$(RMDIR) $(strip $(subst /,\,$(clean-dirs))))
|
$(RMDIR) $(strip $(subst /,\,$(clean-dirs))))
|
||||||
else
|
else
|
||||||
$(Q)$(if $(strip $(clean-dirs)), \
|
$(Q)$(if $(strip $(clean-dirs)), \
|
||||||
for directory in $(strip $(clean-dirs)); do \
|
for directory in $(strip $(clean-dirs)); do \
|
||||||
if [ -d "$$directory" ]; then \
|
if [ -d "$$directory" ]; then \
|
||||||
$(RMDIR) $$directory; \
|
$(RMDIR) $$directory; \
|
||||||
fi \
|
fi \
|
||||||
done \
|
done \
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Rebuild the project.
|
# Rebuild the project.
|
||||||
.PHONY: rebuild
|
.PHONY: rebuild
|
||||||
rebuild: clean all
|
rebuild: clean all
|
||||||
|
|
||||||
.PHONY: objfiles
|
.PHONY: objfiles
|
||||||
objfiles: $(obj-y)
|
objfiles: $(obj-y)
|
||||||
|
|
||||||
# Create object files from C source files.
|
# Create object files from C source files.
|
||||||
$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk
|
$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk
|
||||||
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
||||||
ifeq ($(os),Windows)
|
ifeq ($(os),Windows)
|
||||||
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
||||||
else
|
else
|
||||||
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
||||||
endif
|
endif
|
||||||
@echo $(MSG_COMPILING)
|
@echo $(MSG_COMPILING)
|
||||||
$(Q)$(CC) $(c_flags) -c $< -o $@
|
$(Q)$(CC) $(c_flags) -c $< -o $@
|
||||||
|
|
||||||
# Create object files from C++ source files.
|
# Create object files from C++ source files.
|
||||||
$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk
|
$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk
|
||||||
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
||||||
ifeq ($(os),Windows)
|
ifeq ($(os),Windows)
|
||||||
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
||||||
else
|
else
|
||||||
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
||||||
endif
|
endif
|
||||||
@echo $(MSG_COMPILING_CXX)
|
@echo $(MSG_COMPILING_CXX)
|
||||||
$(Q)$(CXX) $(cxx_flags) -c $< -o $@
|
$(Q)$(CXX) $(cxx_flags) -c $< -o $@
|
||||||
|
|
||||||
# Preprocess and assemble: create object files from assembler source files.
|
# Preprocess and assemble: create object files from assembler source files.
|
||||||
$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk
|
$(build-dir)%.o: %.s $(MAKEFILE_PATH) config.mk
|
||||||
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
||||||
ifeq ($(os),Windows)
|
ifeq ($(os),Windows)
|
||||||
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
||||||
else
|
else
|
||||||
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
||||||
endif
|
endif
|
||||||
@echo $(MSG_ASSEMBLING)
|
@echo $(MSG_ASSEMBLING)
|
||||||
$(Q)$(CC) $(a_flags) -c $< -o $@
|
$(Q)$(CC) $(a_flags) -c $< -o $@
|
||||||
|
|
||||||
# Preprocess and assemble: create object files from assembler source files.
|
# Preprocess and assemble: create object files from assembler source files.
|
||||||
$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk
|
$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk
|
||||||
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
$(Q)test -d $(dir $@) || echo $(MSG_MKDIR)
|
||||||
ifeq ($(os),Windows)
|
ifeq ($(os),Windows)
|
||||||
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
$(Q)test -d $(dir $@) || mkdir $(subst /,\,$(dir $@))
|
||||||
else
|
else
|
||||||
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
$(Q)test -d $(dir $@) || mkdir -p $(dir $@)
|
||||||
endif
|
endif
|
||||||
@echo $(MSG_ASSEMBLING)
|
@echo $(MSG_ASSEMBLING)
|
||||||
$(Q)$(CC) $(a_flags) -c $< -o $@
|
$(Q)$(CC) $(a_flags) -c $< -o $@
|
||||||
|
|
||||||
# Include all dependency files to add depedency to all header files in use.
|
# Include all dependency files to add depedency to all header files in use.
|
||||||
include $(dep-files)
|
include $(dep-files)
|
||||||
|
|
||||||
ifeq ($(target_type),lib)
|
ifeq ($(target_type),lib)
|
||||||
# Archive object files into an archive
|
# Archive object files into an archive
|
||||||
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
|
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
|
||||||
@echo $(MSG_ARCHIVING)
|
@echo $(MSG_ARCHIVING)
|
||||||
$(Q)$(AR) $(ar_flags) $@ $(obj-y)
|
$(Q)$(AR) $(ar_flags) $@ $(obj-y)
|
||||||
@echo $(MSG_SIZE)
|
@echo $(MSG_SIZE)
|
||||||
$(Q)$(SIZE) -Bxt $@
|
$(Q)$(SIZE) -Bxt $@
|
||||||
else
|
else
|
||||||
ifeq ($(target_type),elf)
|
ifeq ($(target_type),elf)
|
||||||
# Link the object files into an ELF file. Also make sure the target is rebuilt
|
# Link the object files into an ELF file. Also make sure the target is rebuilt
|
||||||
# if the common Makefile.avr.in or project config.mk is changed.
|
# if the common Makefile.avr.in or project config.mk is changed.
|
||||||
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
|
$(target): $(MAKEFILE_PATH) config.mk $(obj-y)
|
||||||
@echo $(MSG_LINKING)
|
@echo $(MSG_LINKING)
|
||||||
$(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@
|
$(Q)$(CC) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@
|
||||||
@echo $(MSG_SIZE)
|
@echo $(MSG_SIZE)
|
||||||
$(Q)$(SIZE) -Ax $@
|
$(Q)$(SIZE) -Ax $@
|
||||||
$(Q)$(SIZE) -Bx $@
|
$(Q)$(SIZE) -Bx $@
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Create extended function listing from target output file.
|
# Create extended function listing from target output file.
|
||||||
%.lss: $(target)
|
%.lss: $(target)
|
||||||
@echo $(MSG_EXTENDED_LISTING)
|
@echo $(MSG_EXTENDED_LISTING)
|
||||||
$(Q)$(OBJDUMP) -h -S $< > $@
|
$(Q)$(OBJDUMP) -h -S $< > $@
|
||||||
|
|
||||||
# Create symbol table from target output file.
|
# Create symbol table from target output file.
|
||||||
%.sym: $(target)
|
%.sym: $(target)
|
||||||
@echo $(MSG_SYMBOL_TABLE)
|
@echo $(MSG_SYMBOL_TABLE)
|
||||||
$(Q)$(NM) -n $< > $@
|
$(Q)$(NM) -n $< > $@
|
||||||
|
|
||||||
# Create Intel HEX image from ELF output file.
|
# Create Intel HEX image from ELF output file.
|
||||||
%.hex: $(target)
|
%.hex: $(target)
|
||||||
@echo $(MSG_IHEX_IMAGE)
|
@echo $(MSG_IHEX_IMAGE)
|
||||||
$(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@
|
$(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@
|
||||||
|
|
||||||
# Create EEPROM Intel HEX image from ELF output file.
|
# Create EEPROM Intel HEX image from ELF output file.
|
||||||
%.eep: $(target)
|
%.eep: $(target)
|
||||||
@echo $(MSG_EEPROM_IMAGE)
|
@echo $(MSG_EEPROM_IMAGE)
|
||||||
$(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0
|
$(Q)$(OBJCOPY) $(eepromflags-gnu-y) -O ihex $< $@ || exit 0
|
||||||
|
|
||||||
# Provide information about the detected host operating system.
|
# Provide information about the detected host operating system.
|
||||||
.SECONDARY: info-os
|
.SECONDARY: info-os
|
||||||
info-os:
|
info-os:
|
||||||
@echo $(MSG_INFO)$(os) build host detected
|
@echo $(MSG_INFO)$(os) build host detected
|
||||||
|
|
||||||
# Build Doxygen generated documentation.
|
# Build Doxygen generated documentation.
|
||||||
.PHONY: doc
|
.PHONY: doc
|
||||||
doc:
|
doc:
|
||||||
@echo $(MSG_GENERATING_DOC)
|
@echo $(MSG_GENERATING_DOC)
|
||||||
$(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg))
|
$(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg))
|
||||||
|
|
||||||
# Clean Doxygen generated documentation.
|
# Clean Doxygen generated documentation.
|
||||||
.PHONY: cleandoc
|
.PHONY: cleandoc
|
||||||
cleandoc:
|
cleandoc:
|
||||||
@$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC))
|
@$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC))
|
||||||
$(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir))
|
$(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir))
|
||||||
|
|
||||||
# Rebuild the Doxygen generated documentation.
|
# Rebuild the Doxygen generated documentation.
|
||||||
.PHONY: rebuilddoc
|
.PHONY: rebuilddoc
|
||||||
rebuilddoc: cleandoc doc
|
rebuilddoc: cleandoc doc
|
||||||
|
|||||||
+2337
-2337
File diff suppressed because it is too large
Load Diff
+326
-326
@@ -1,326 +1,326 @@
|
|||||||
/*####COPYRIGHTBEGIN####
|
/*####COPYRIGHTBEGIN####
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
Copyright (C) 2015 Steve Karg
|
Copyright (C) 2015 Steve Karg
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
as published by the Free Software Foundation; either version 2
|
as published by the Free Software Foundation; either version 2
|
||||||
of the License, or (at your option) any later version.
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to:
|
along with this program; if not, write to:
|
||||||
The Free Software Foundation, Inc.
|
The Free Software Foundation, Inc.
|
||||||
59 Temple Place - Suite 330
|
59 Temple Place - Suite 330
|
||||||
Boston, MA 02111-1307, USA.
|
Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
As a special exception, if other files instantiate templates or
|
As a special exception, if other files instantiate templates or
|
||||||
use macros or inline functions from this file, or you compile
|
use macros or inline functions from this file, or you compile
|
||||||
this file and link it with other works to produce a work based
|
this file and link it with other works to produce a work based
|
||||||
on this file, this file does not by itself cause the resulting
|
on this file, this file does not by itself cause the resulting
|
||||||
work to be covered by the GNU General Public License. However
|
work to be covered by the GNU General Public License. However
|
||||||
the source code for this file must still be made available in
|
the source code for this file must still be made available in
|
||||||
accordance with section (3) of the GNU General Public License.
|
accordance with section (3) of the GNU General Public License.
|
||||||
|
|
||||||
This exception does not invalidate any other reasons why a work
|
This exception does not invalidate any other reasons why a work
|
||||||
based on this file might be covered by the GNU General Public
|
based on this file might be covered by the GNU General Public
|
||||||
License.
|
License.
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
####COPYRIGHTEND####*/
|
####COPYRIGHTEND####*/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "keylist.h"
|
#include "keylist.h"
|
||||||
/* me! */
|
/* me! */
|
||||||
#include "vmac.h"
|
#include "vmac.h"
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
Handle VMAC address binding */
|
Handle VMAC address binding */
|
||||||
|
|
||||||
/* This module is used to handle the virtual MAC address binding that */
|
/* This module is used to handle the virtual MAC address binding that */
|
||||||
/* occurs in BACnet for ZigBee or IPv6. */
|
/* occurs in BACnet for ZigBee or IPv6. */
|
||||||
|
|
||||||
/* 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 VMAC_List;
|
static OS_Keylist VMAC_List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of VMAC in the list
|
* Returns the number of VMAC in the list
|
||||||
*/
|
*/
|
||||||
unsigned int VMAC_Count(void)
|
unsigned int VMAC_Count(void)
|
||||||
{
|
{
|
||||||
return (unsigned int)Keylist_Count(VMAC_List);
|
return (unsigned int)Keylist_Count(VMAC_List);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a VMAC to the list
|
* Adds a VMAC to the list
|
||||||
*
|
*
|
||||||
* @param device_id - BACnet device object instance number
|
* @param device_id - BACnet device object instance number
|
||||||
* @param src - BACnet/IPv6 address
|
* @param src - BACnet/IPv6 address
|
||||||
*
|
*
|
||||||
* @return true if the device ID and MAC are added
|
* @return true if the device ID and MAC are added
|
||||||
*/
|
*/
|
||||||
bool VMAC_Add(uint32_t device_id, struct vmac_data *src)
|
bool VMAC_Add(uint32_t device_id, struct vmac_data *src)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
struct vmac_data *pVMAC = NULL;
|
struct vmac_data *pVMAC = NULL;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
pVMAC = Keylist_Data(VMAC_List, device_id);
|
pVMAC = Keylist_Data(VMAC_List, device_id);
|
||||||
if (!pVMAC) {
|
if (!pVMAC) {
|
||||||
pVMAC = calloc(1, sizeof(struct vmac_data));
|
pVMAC = calloc(1, sizeof(struct vmac_data));
|
||||||
if (pVMAC) {
|
if (pVMAC) {
|
||||||
/* copy the MAC into the data store */
|
/* copy the MAC into the data store */
|
||||||
for (i = 0; i < sizeof(pVMAC->mac); i++) {
|
for (i = 0; i < sizeof(pVMAC->mac); i++) {
|
||||||
if (i < src->mac_len) {
|
if (i < src->mac_len) {
|
||||||
pVMAC->mac[i] = src->mac[i];
|
pVMAC->mac[i] = src->mac[i];
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pVMAC->mac_len = src->mac_len;
|
pVMAC->mac_len = src->mac_len;
|
||||||
index = Keylist_Data_Add(VMAC_List, device_id, pVMAC);
|
index = Keylist_Data_Add(VMAC_List, device_id, pVMAC);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
status = true;
|
status = true;
|
||||||
printf("VMAC %u added.\n", (unsigned int)device_id);
|
printf("VMAC %u added.\n", (unsigned int)device_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a VMAC in the list by seeking the Device ID, and deletes it.
|
* Finds a VMAC in the list by seeking the Device ID, and deletes it.
|
||||||
*
|
*
|
||||||
* @param device_id - BACnet device object instance number
|
* @param device_id - BACnet device object instance number
|
||||||
*
|
*
|
||||||
* @return pointer to the VMAC data from the list - be sure to free() it!
|
* @return pointer to the VMAC data from the list - be sure to free() it!
|
||||||
*/
|
*/
|
||||||
bool VMAC_Delete(uint32_t device_id)
|
bool VMAC_Delete(uint32_t device_id)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
struct vmac_data *pVMAC;
|
struct vmac_data *pVMAC;
|
||||||
|
|
||||||
pVMAC = Keylist_Data_Delete(VMAC_List, device_id);
|
pVMAC = Keylist_Data_Delete(VMAC_List, device_id);
|
||||||
if (pVMAC) {
|
if (pVMAC) {
|
||||||
free(pVMAC);
|
free(pVMAC);
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a VMAC in the list by seeking the Device ID.
|
* Finds a VMAC in the list by seeking the Device ID.
|
||||||
*
|
*
|
||||||
* @param device_id - BACnet device object instance number
|
* @param device_id - BACnet device object instance number
|
||||||
*
|
*
|
||||||
* @return pointer to the VMAC data from the list
|
* @return pointer to the VMAC data from the list
|
||||||
*/
|
*/
|
||||||
struct vmac_data *VMAC_Find_By_Key(uint32_t device_id)
|
struct vmac_data *VMAC_Find_By_Key(uint32_t device_id)
|
||||||
{
|
{
|
||||||
return Keylist_Data(VMAC_List, device_id);
|
return Keylist_Data(VMAC_List, device_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compare the VMAC address
|
/** Compare the VMAC address
|
||||||
*
|
*
|
||||||
* @param vmac1 - VMAC address that will be compared to vmac2
|
* @param vmac1 - VMAC address that will be compared to vmac2
|
||||||
* @param vmac2 - VMAC address that will be compared to vmac1
|
* @param vmac2 - VMAC address that will be compared to vmac1
|
||||||
*
|
*
|
||||||
* @return true if the addresses are different
|
* @return true if the addresses are different
|
||||||
*/
|
*/
|
||||||
bool VMAC_Different(
|
bool VMAC_Different(
|
||||||
struct vmac_data *vmac1,
|
struct vmac_data *vmac1,
|
||||||
struct vmac_data *vmac2)
|
struct vmac_data *vmac2)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned int mac_len = VMAC_MAC_MAX;
|
unsigned int mac_len = VMAC_MAC_MAX;
|
||||||
|
|
||||||
if (vmac1 && vmac2) {
|
if (vmac1 && vmac2) {
|
||||||
if (vmac1->mac_len != vmac2->mac_len) {
|
if (vmac1->mac_len != vmac2->mac_len) {
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
if (vmac1->mac_len < mac_len) {
|
if (vmac1->mac_len < mac_len) {
|
||||||
mac_len = (unsigned int)vmac1->mac_len;
|
mac_len = (unsigned int)vmac1->mac_len;
|
||||||
}
|
}
|
||||||
for (i = 0; i < mac_len; i++) {
|
for (i = 0; i < mac_len; i++) {
|
||||||
if (vmac1->mac[i] != vmac2->mac[i]) {
|
if (vmac1->mac[i] != vmac2->mac[i]) {
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compare the VMAC address
|
/** Compare the VMAC address
|
||||||
*
|
*
|
||||||
* @param vmac1 - VMAC address that will be compared to vmac2
|
* @param vmac1 - VMAC address that will be compared to vmac2
|
||||||
* @param vmac2 - VMAC address that will be compared to vmac1
|
* @param vmac2 - VMAC address that will be compared to vmac1
|
||||||
*
|
*
|
||||||
* @return true if the addresses are the same
|
* @return true if the addresses are the same
|
||||||
*/
|
*/
|
||||||
bool VMAC_Match(
|
bool VMAC_Match(
|
||||||
struct vmac_data *vmac1,
|
struct vmac_data *vmac1,
|
||||||
struct vmac_data *vmac2)
|
struct vmac_data *vmac2)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned int mac_len = VMAC_MAC_MAX;
|
unsigned int mac_len = VMAC_MAC_MAX;
|
||||||
|
|
||||||
if (vmac1 && vmac2 && vmac1->mac_len) {
|
if (vmac1 && vmac2 && vmac1->mac_len) {
|
||||||
status = true;
|
status = true;
|
||||||
if (vmac1->mac_len != vmac2->mac_len) {
|
if (vmac1->mac_len != vmac2->mac_len) {
|
||||||
status = false;
|
status = false;
|
||||||
} else {
|
} else {
|
||||||
if (vmac1->mac_len < mac_len) {
|
if (vmac1->mac_len < mac_len) {
|
||||||
mac_len = (unsigned int)vmac1->mac_len;
|
mac_len = (unsigned int)vmac1->mac_len;
|
||||||
}
|
}
|
||||||
for (i = 0; i < mac_len; i++) {
|
for (i = 0; i < mac_len; i++) {
|
||||||
if (vmac1->mac[i] != vmac2->mac[i]) {
|
if (vmac1->mac[i] != vmac2->mac[i]) {
|
||||||
status = false;
|
status = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds a VMAC in the list by seeking a matching VMAC address
|
* Finds a VMAC in the list by seeking a matching VMAC address
|
||||||
*
|
*
|
||||||
* @param vmac - VMAC address that will be sought
|
* @param vmac - VMAC address that will be sought
|
||||||
* @param device_id - BACnet device object instance number
|
* @param device_id - BACnet device object instance number
|
||||||
*
|
*
|
||||||
* @return true if the VMAC address was found
|
* @return true if the VMAC address was found
|
||||||
*/
|
*/
|
||||||
bool VMAC_Find_By_Data(struct vmac_data *vmac, uint32_t *device_id)
|
bool VMAC_Find_By_Data(struct vmac_data *vmac, uint32_t *device_id)
|
||||||
{
|
{
|
||||||
bool status = false;
|
bool status = false;
|
||||||
struct vmac_data *list_vmac;
|
struct vmac_data *list_vmac;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
|
||||||
count = Keylist_Count(VMAC_List);
|
count = Keylist_Count(VMAC_List);
|
||||||
while (count) {
|
while (count) {
|
||||||
index = count - 1;
|
index = count - 1;
|
||||||
list_vmac = Keylist_Data_Index(VMAC_List, index);
|
list_vmac = Keylist_Data_Index(VMAC_List, index);
|
||||||
if (list_vmac) {
|
if (list_vmac) {
|
||||||
if (VMAC_Match(vmac, list_vmac)) {
|
if (VMAC_Match(vmac, list_vmac)) {
|
||||||
if (device_id) {
|
if (device_id) {
|
||||||
*device_id = Keylist_Key(VMAC_List, index);
|
*device_id = Keylist_Key(VMAC_List, index);
|
||||||
}
|
}
|
||||||
status = true;
|
status = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans up the memory used by the VMAC list data
|
* Cleans up the memory used by the VMAC list data
|
||||||
*/
|
*/
|
||||||
void VMAC_Cleanup(void)
|
void VMAC_Cleanup(void)
|
||||||
{
|
{
|
||||||
struct vmac_data *pVMAC;
|
struct vmac_data *pVMAC;
|
||||||
|
|
||||||
if (VMAC_List) {
|
if (VMAC_List) {
|
||||||
do {
|
do {
|
||||||
pVMAC = Keylist_Data_Pop(VMAC_List);
|
pVMAC = Keylist_Data_Pop(VMAC_List);
|
||||||
if (pVMAC) {
|
if (pVMAC) {
|
||||||
free(pVMAC);
|
free(pVMAC);
|
||||||
}
|
}
|
||||||
} while (pVMAC);
|
} while (pVMAC);
|
||||||
Keylist_Delete(VMAC_List);
|
Keylist_Delete(VMAC_List);
|
||||||
VMAC_List = NULL;
|
VMAC_List = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the VMAC list data
|
* Initializes the VMAC list data
|
||||||
*/
|
*/
|
||||||
void VMAC_Init(void)
|
void VMAC_Init(void)
|
||||||
{
|
{
|
||||||
VMAC_List = Keylist_Create();
|
VMAC_List = Keylist_Create();
|
||||||
if (VMAC_List) {
|
if (VMAC_List) {
|
||||||
atexit(VMAC_Cleanup);
|
atexit(VMAC_Cleanup);
|
||||||
printf("VMAC List initialized.\n");
|
printf("VMAC List initialized.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ctest.h"
|
#include "ctest.h"
|
||||||
|
|
||||||
void testVMAC(
|
void testVMAC(
|
||||||
Test * pTest)
|
Test * pTest)
|
||||||
{
|
{
|
||||||
uint32_t device_id = 123;
|
uint32_t device_id = 123;
|
||||||
uint32_t test_device_id = 0;
|
uint32_t test_device_id = 0;
|
||||||
struct vmac_data test_vmac_data;
|
struct vmac_data test_vmac_data;
|
||||||
struct vmac_data *pVMAC;
|
struct vmac_data *pVMAC;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
bool status = false;
|
bool status = false;
|
||||||
|
|
||||||
VMAC_Init();
|
VMAC_Init();
|
||||||
for (i = 0; i < VMAC_MAC_MAX; i++) {
|
for (i = 0; i < VMAC_MAC_MAX; i++) {
|
||||||
test_vmac_data.mac[i] = 1 + i;
|
test_vmac_data.mac[i] = 1 + i;
|
||||||
}
|
}
|
||||||
test_vmac_data.mac_len = VMAC_MAC_MAX;
|
test_vmac_data.mac_len = VMAC_MAC_MAX;
|
||||||
status = VMAC_Add(device_id, &test_vmac_data);
|
status = VMAC_Add(device_id, &test_vmac_data);
|
||||||
ct_test(pTest, status);
|
ct_test(pTest, status);
|
||||||
pVMAC = VMAC_Find_By_Key(0);
|
pVMAC = VMAC_Find_By_Key(0);
|
||||||
ct_test(pTest, pVMAC == NULL);
|
ct_test(pTest, pVMAC == NULL);
|
||||||
pVMAC = VMAC_Find_By_Key(device_id);
|
pVMAC = VMAC_Find_By_Key(device_id);
|
||||||
ct_test(pTest, pVMAC);
|
ct_test(pTest, pVMAC);
|
||||||
status = VMAC_Different(pVMAC, &test_vmac_data);
|
status = VMAC_Different(pVMAC, &test_vmac_data);
|
||||||
ct_test(pTest, !status);
|
ct_test(pTest, !status);
|
||||||
status = VMAC_Match(pVMAC, &test_vmac_data);
|
status = VMAC_Match(pVMAC, &test_vmac_data);
|
||||||
ct_test(pTest, status);
|
ct_test(pTest, status);
|
||||||
status = VMAC_Find_By_Data(&test_vmac_data, &test_device_id);
|
status = VMAC_Find_By_Data(&test_vmac_data, &test_device_id);
|
||||||
ct_test(pTest, status);
|
ct_test(pTest, status);
|
||||||
ct_test(pTest, test_device_id == device_id);
|
ct_test(pTest, test_device_id == device_id);
|
||||||
status = VMAC_Delete(device_id);
|
status = VMAC_Delete(device_id);
|
||||||
ct_test(pTest, status);
|
ct_test(pTest, status);
|
||||||
pVMAC = VMAC_Find_By_Key(device_id);
|
pVMAC = VMAC_Find_By_Key(device_id);
|
||||||
ct_test(pTest, pVMAC == NULL);
|
ct_test(pTest, pVMAC == NULL);
|
||||||
VMAC_Cleanup();
|
VMAC_Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST_VMAC
|
#ifdef TEST_VMAC
|
||||||
int main(
|
int main(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
Test *pTest;
|
Test *pTest;
|
||||||
bool rc;
|
bool rc;
|
||||||
|
|
||||||
pTest = ct_create("BACnet VMAC", NULL);
|
pTest = ct_create("BACnet VMAC", NULL);
|
||||||
/* individual tests */
|
/* individual tests */
|
||||||
rc = ct_addTestFunction(pTest, testVMAC);
|
rc = ct_addTestFunction(pTest, testVMAC);
|
||||||
assert(rc);
|
assert(rc);
|
||||||
|
|
||||||
ct_setStream(pTest, stdout);
|
ct_setStream(pTest, stdout);
|
||||||
ct_run(pTest);
|
ct_run(pTest);
|
||||||
(void) ct_report(pTest);
|
(void) ct_report(pTest);
|
||||||
ct_destroy(pTest);
|
ct_destroy(pTest);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user