updated BACnet-IP for the Borland C++ compiler, and added a makefile to make the demo.
This commit is contained in:
@@ -0,0 +1,130 @@
|
|||||||
|
#
|
||||||
|
# Simple makefile to build an RTB executable for RTOS-32
|
||||||
|
#
|
||||||
|
# This makefile assumes Borland bcc32 development environment
|
||||||
|
# on Windows NT/9x/2000/XP
|
||||||
|
#
|
||||||
|
|
||||||
|
!ifndef BORLAND_DIR
|
||||||
|
BORLAND_DIR_Not_Defined:
|
||||||
|
@echo .
|
||||||
|
@echo You must define environment variable BORLAND_DIR to compile.
|
||||||
|
!endif
|
||||||
|
|
||||||
|
PRODUCT = bacnet
|
||||||
|
PRODUCT_EXE = $(PRODUCT).exe
|
||||||
|
|
||||||
|
# Choose the Data Link Layer to Enable
|
||||||
|
DEFINES = -DBACDL_BIP=1
|
||||||
|
|
||||||
|
SRCS = main.c bip-init.c \
|
||||||
|
..\..\bip.c \
|
||||||
|
..\..\handlers.c \
|
||||||
|
..\..\bacdcode.c \
|
||||||
|
..\..\bigend.c \
|
||||||
|
..\..\whois.c \
|
||||||
|
..\..\iam.c \
|
||||||
|
..\..\rp.c \
|
||||||
|
..\..\wp.c \
|
||||||
|
..\..\arf.c \
|
||||||
|
..\..\awf.c \
|
||||||
|
..\..\bacfile.c \
|
||||||
|
..\..\device.c \
|
||||||
|
..\..\ai.c \
|
||||||
|
..\..\ao.c \
|
||||||
|
..\..\datalink.c \
|
||||||
|
..\..\tsm.c \
|
||||||
|
..\..\address.c \
|
||||||
|
..\..\abort.c \
|
||||||
|
..\..\reject.c \
|
||||||
|
..\..\bacerror.c \
|
||||||
|
..\..\apdu.c \
|
||||||
|
..\..\npdu.c
|
||||||
|
|
||||||
|
OBJS = $(SRCS:.c=.obj)
|
||||||
|
|
||||||
|
# Compiler definitions
|
||||||
|
#
|
||||||
|
CC = $(BORLAND_DIR)\bin\bcc32 +bcc32.cfg
|
||||||
|
LINK = $(BORLAND_DIR)\bin\tlink32
|
||||||
|
TLIB = $(BORLAND_DIR)\bin\tlib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Include directories
|
||||||
|
#
|
||||||
|
CC_DIR = $(BORLAND_DIR)\BIN
|
||||||
|
INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;.
|
||||||
|
|
||||||
|
CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES)
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
#
|
||||||
|
C_LIB_DIR = $(BORLAND_DIR)\lib
|
||||||
|
|
||||||
|
LIBDIR = $(C_LIB_DIR)
|
||||||
|
|
||||||
|
LIBS = $(C_LIB_DIR)\IMPORT32.lib \
|
||||||
|
$(C_LIB_DIR)\CW32MT.lib
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main target
|
||||||
|
#
|
||||||
|
# This should be the first one in the makefile
|
||||||
|
|
||||||
|
all : bcc32.cfg $(PRODUCT_EXE)
|
||||||
|
|
||||||
|
# Linker specific: the link below is for BCC linker/compiler. If you link
|
||||||
|
# with a different linker - please change accordingly.
|
||||||
|
#
|
||||||
|
|
||||||
|
# need a temp response file (@&&) because command line is too long
|
||||||
|
$(PRODUCT_EXE) : $(OBJS)
|
||||||
|
@echo Running Linker for $(PRODUCT_EXE)
|
||||||
|
$(LINK) -L$(LINKER_LIB) -m -c -s -v @&&| # temp response file, starts with |
|
||||||
|
$(BORLAND_DIR)\lib\c0x32.obj $** # $** lists each dependency
|
||||||
|
$<
|
||||||
|
$*.map
|
||||||
|
$(LIBS)
|
||||||
|
| # end of temp response file
|
||||||
|
|
||||||
|
#
|
||||||
|
# Utilities
|
||||||
|
|
||||||
|
clean :
|
||||||
|
@echo Deleting obj files, $(PRODUCT_EXE) and map files.
|
||||||
|
del *.obj
|
||||||
|
del ..\..\*.obj
|
||||||
|
del $(PRODUCT_EXE)
|
||||||
|
del *.map
|
||||||
|
del bcc32.cfg
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generic rules
|
||||||
|
#
|
||||||
|
.SUFFIXES: .cpp .c .sbr .obj
|
||||||
|
|
||||||
|
#
|
||||||
|
# cc generic rule
|
||||||
|
#
|
||||||
|
.c.obj:
|
||||||
|
$(CC) -o$@ $<
|
||||||
|
|
||||||
|
# Compiler configuration file
|
||||||
|
bcc32.cfg :
|
||||||
|
Copy &&|
|
||||||
|
$(CFLAGS)
|
||||||
|
-c
|
||||||
|
-y #include line numbers in OBJ's
|
||||||
|
-v #include debug info
|
||||||
|
-w+ #turn on all warnings
|
||||||
|
-Od #disable all optimizations
|
||||||
|
#-a4 #32 bit data alignment
|
||||||
|
#-M # generate link map
|
||||||
|
#-ls # linker options
|
||||||
|
#-WM- #not multithread
|
||||||
|
-WM #multithread
|
||||||
|
-w-aus # ignore warning assigned a value that is never used
|
||||||
|
-w-sig # ignore warning conversion may lose sig digits
|
||||||
|
| $@
|
||||||
|
|
||||||
|
# EOF: makefile
|
||||||
@@ -43,12 +43,74 @@
|
|||||||
#include "bip.h"
|
#include "bip.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
|
/* To fill a need, we invent the gethostaddr() function. */
|
||||||
|
static long gethostaddr(void)
|
||||||
|
{
|
||||||
|
struct hostent *host_ent;
|
||||||
|
char host_name[255];
|
||||||
|
|
||||||
|
if (gethostname(host_name, sizeof(host_name)) != 0)
|
||||||
|
return -1;
|
||||||
|
printf("host name: %s\n",host_name);
|
||||||
|
if ((host_ent = gethostbyname(host_name)) == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return *(long *)host_ent->h_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_broadcast_address(uint32_t net_address)
|
||||||
|
{
|
||||||
|
long broadcast_address = 0;
|
||||||
|
long mask = 0;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
bip_set_broadcast_addr(INADDR_BROADCAST);
|
||||||
|
#else
|
||||||
|
if (IN_CLASSA(ntohl(net_address)))
|
||||||
|
broadcast_address = (ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
|
||||||
|
else if (IN_CLASSB(ntohl(net_address)))
|
||||||
|
broadcast_address = (ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
|
||||||
|
else if (IN_CLASSC(ntohl(net_address)))
|
||||||
|
broadcast_address = (ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
|
||||||
|
else if (IN_CLASSD(ntohl(net_address)))
|
||||||
|
broadcast_address = (ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
|
||||||
|
else
|
||||||
|
broadcast_address = INADDR_BROADCAST;
|
||||||
|
bip_set_broadcast_addr(htonl(broadcast_address));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool bip_init(void)
|
bool bip_init(void)
|
||||||
{
|
{
|
||||||
int rv = 0; // return from socket lib calls
|
int rv = 0; // return from socket lib calls
|
||||||
struct sockaddr_in sin = {-1};
|
struct sockaddr_in sin = {-1};
|
||||||
int value = 1;
|
int value = 1;
|
||||||
int sock_fd = -1;
|
int sock_fd = -1;
|
||||||
|
int Result;
|
||||||
|
int Code;
|
||||||
|
WSADATA wd;
|
||||||
|
struct in_addr address;
|
||||||
|
|
||||||
|
Result = WSAStartup(MAKEWORD(2,2), &wd);
|
||||||
|
|
||||||
|
if (Result != 0)
|
||||||
|
{
|
||||||
|
Code = WSAGetLastError();
|
||||||
|
printf("TCP/IP stack initialization failed, error code: %i\n",
|
||||||
|
Code);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
address.s_addr = gethostaddr();
|
||||||
|
if (address.s_addr == (unsigned)-1)
|
||||||
|
{
|
||||||
|
Code = WSAGetLastError();
|
||||||
|
printf("Get host address failed, error code: %i\n",
|
||||||
|
Code);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("host address: %s\n",inet_ntoa(address));
|
||||||
|
bip_set_addr(address.s_addr);
|
||||||
|
set_broadcast_address(address.s_addr);
|
||||||
|
|
||||||
// assumes that the driver has already been initialized
|
// assumes that the driver has already been initialized
|
||||||
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "apdu.h"
|
#include "apdu.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "handlers.h"
|
#include "handlers.h"
|
||||||
#include "bip.h"
|
#include "datalink.h"
|
||||||
|
|
||||||
// buffer used for receive
|
// buffer used for receive
|
||||||
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
static uint8_t Rx_Buf[MAX_MPDU] = {0};
|
||||||
@@ -166,50 +166,21 @@ static void Init_Service_Handlers(void)
|
|||||||
ReadPropertyAckHandler);
|
ReadPropertyAckHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To fill a need, we invent the gethostaddr() function. */
|
static void print_address(
|
||||||
long gethostaddr(void)
|
char *name,
|
||||||
|
BACNET_ADDRESS *dest) // destination address
|
||||||
{
|
{
|
||||||
struct hostent *host_ent;
|
int i = 0; // counter
|
||||||
char host_name[255];
|
|
||||||
|
|
||||||
if (gethostname(host_name, sizeof(host_name)) == 0)
|
if (dest)
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((host_ent = gethostbyname(host_name)) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return *(long *)host_ent->h_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern void bip_set_addr(struct in_addr *net_address);
|
|
||||||
|
|
||||||
extern void bip_set_ipv4_broadcast_s_addr(
|
|
||||||
unsigned long address);
|
|
||||||
|
|
||||||
static void NetInitialize(void)
|
|
||||||
// initialize the TCP/IP stack
|
|
||||||
{
|
|
||||||
int Result;
|
|
||||||
int Code;
|
|
||||||
WSADATA wd;
|
|
||||||
struct in_addr address;
|
|
||||||
|
|
||||||
|
|
||||||
Result = WSAStartup(MAKEWORD(2,2), &wd);
|
|
||||||
|
|
||||||
if (Result != 0)
|
|
||||||
{
|
{
|
||||||
Code = WSAGetLastError();
|
printf("%s: ",name);
|
||||||
printf("TCP/IP stack initialization failed, error code: %i\n",
|
for (i = 0; i < dest->mac_len; i++)
|
||||||
Code);
|
{
|
||||||
exit(1);
|
printf("%02X",dest->mac[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
address.s_addr = gethostaddr();
|
|
||||||
bip_set_addr(address.s_addr);
|
|
||||||
/* local broadcast address */
|
|
||||||
bip_set_broadcast_addr(INADDR_BROADCAST);
|
|
||||||
/* configure standard BACnet/IP port */
|
|
||||||
bip_set_port(0xBAC0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -217,16 +188,23 @@ int main(int argc, char *argv[])
|
|||||||
BACNET_ADDRESS src = {0}; // address where message came from
|
BACNET_ADDRESS src = {0}; // address where message came from
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
unsigned timeout = 100; // milliseconds
|
unsigned timeout = 100; // milliseconds
|
||||||
|
BACNET_ADDRESS my_address, broadcast_address;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
Init_Device_Parameters();
|
Init_Device_Parameters();
|
||||||
Init_Service_Handlers();
|
Init_Service_Handlers();
|
||||||
// init the data link layer
|
// init the data link layer
|
||||||
NetInitialize();
|
/* configure standard BACnet/IP port */
|
||||||
|
bip_set_port(0xBAC0);
|
||||||
if (!bip_init())
|
if (!bip_init())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
datalink_get_broadcast_address(&broadcast_address);
|
||||||
|
print_address("Broadcast",&broadcast_address);
|
||||||
|
datalink_get_my_address(&my_address);
|
||||||
|
print_address("Address",&my_address);
|
||||||
|
|
||||||
printf("BACnet stack running...\n");
|
printf("BACnet stack running...\n");
|
||||||
// loop forever
|
// loop forever
|
||||||
for (;;)
|
for (;;)
|
||||||
@@ -259,6 +237,9 @@ int main(int argc, char *argv[])
|
|||||||
Who_Is_Request = false;
|
Who_Is_Request = false;
|
||||||
Send_WhoIs();
|
Send_WhoIs();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Read_Properties();
|
||||||
|
|
||||||
// output
|
// output
|
||||||
|
|
||||||
// blink LEDs, Turn on or off outputs, etc
|
// blink LEDs, Turn on or off outputs, etc
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
set BORLAND_DIR=\bc5
|
||||||
|
|
||||||
Reference in New Issue
Block a user