Set the EOL-style to native for most files using svn propset command. Some files also had inconsistent line endings. Seems that subversion doesn't set the eol-style automatically when files are created unless it is configured for autoprops. The autoprops setting is local to the subversion installation and not the project.

This commit is contained in:
skarg
2007-06-18 16:22:24 +00:00
parent a2a4220723
commit a18d338f00
41 changed files with 6673 additions and 6670 deletions
+580 -580
View File
File diff suppressed because it is too large Load Diff
+76 -76
View File
@@ -1,76 +1,76 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2006 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#ifndef BACNET_H
#define BACNET_H
/* This file is designed to reference the entire BACnet stack library */
/* core files */
#include "config.h"
#include "address.h"
#include "apdu.h"
#include "bacapp.h"
#include "bacdcode.h"
#include "bacdef.h"
#include "bacenum.h"
#include "bacerror.h"
#include "bacstr.h"
#include "bactext.h"
#include "datalink.h"
#include "indtext.h"
#include "npdu.h"
#include "reject.h"
#include "tsm.h"
/* services */
#include "arf.h"
#include "awf.h"
#include "cov.h"
#include "dcc.h"
#include "iam.h"
#include "ihave.h"
#include "rd.h"
#include "rp.h"
#include "rpm.h"
#include "timesync.h"
#include "whohas.h"
#include "whois.h"
#include "wp.h"
/* required object - note: developer must supply the device.c file
since it is not included in the library. However, the library
references the device.c members via the device.h API. */
#include "device.h"
#endif
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2006 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#ifndef BACNET_H
#define BACNET_H
/* This file is designed to reference the entire BACnet stack library */
/* core files */
#include "config.h"
#include "address.h"
#include "apdu.h"
#include "bacapp.h"
#include "bacdcode.h"
#include "bacdef.h"
#include "bacenum.h"
#include "bacerror.h"
#include "bacstr.h"
#include "bactext.h"
#include "datalink.h"
#include "indtext.h"
#include "npdu.h"
#include "reject.h"
#include "tsm.h"
/* services */
#include "arf.h"
#include "awf.h"
#include "cov.h"
#include "dcc.h"
#include "iam.h"
#include "ihave.h"
#include "rd.h"
#include "rp.h"
#include "rpm.h"
#include "timesync.h"
#include "whohas.h"
#include "whois.h"
#include "wp.h"
/* required object - note: developer must supply the device.c file
since it is not included in the library. However, the library
references the device.c members via the device.h API. */
#include "device.h"
#endif
+731 -731
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -49,4 +49,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*
#endif /* */
+3 -3
View File
@@ -840,9 +840,9 @@ void testCOVSubscribeData(Test * pTest,
test_data->monitoredObjectIdentifier.instance ==
data->monitoredObjectIdentifier.instance);
ct_test(pTest,
test_data->cancellationRequest == data->cancellationRequest);
if (test_data->cancellationRequest != data->cancellationRequest) {
printf("cancellation request failed!\n");
test_data->cancellationRequest == data->cancellationRequest);
if (test_data->cancellationRequest != data->cancellationRequest) {
printf("cancellation request failed!\n");
}
if (!test_data->cancellationRequest) {
ct_test(pTest,
+2 -2
View File
@@ -354,7 +354,7 @@ bool datetime_wildcard(BACNET_DATE_TIME * bdatetime)
return wildcard_present;
}
void datetime_date_wildcard_set(BACNET_DATE * bdate)
{
if (bdate) {
@@ -364,7 +364,7 @@ void datetime_date_wildcard_set(BACNET_DATE * bdate)
bdate->wday = 0xFF;
}
}
void datetime_time_wildcard_set(BACNET_TIME * btime)
{
if (btime) {
+1 -1
View File
@@ -104,7 +104,7 @@ extern "C" {
/* date and time wildcards */
bool datetime_wildcard(BACNET_DATE_TIME * bdatetime);
void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime);
void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime);
void datetime_date_wildcard_set(BACNET_DATE * bdate);
void datetime_time_wildcard_set(BACNET_TIME * btime);
+158 -158
View File
@@ -400,15 +400,15 @@ void Load_Control_State_Machine(int object_index)
{
unsigned i = 0; /* loop counter */
int diff = 0; /* used for datetime comparison */
/* is the state machine enabled? */
if (!Load_Control_Enable[object_index]) {
if (!Load_Control_Enable[object_index]) {
Load_Control_State[object_index] = SHED_INACTIVE;
return;
}
}
switch (Load_Control_State[object_index]) {
case SHED_REQUEST_PENDING:
case SHED_REQUEST_PENDING:
if (Load_Control_Request_Written[object_index]) {
Load_Control_Request_Written[object_index] = false;
/* request to cancel using default values? */
@@ -996,195 +996,195 @@ static void Load_Control_WriteProperty_Request_Shed_Percent(Test * pTest,
int instance, unsigned percent)
{
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
value.context_specific = true;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = percent;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
value.context_specific = true;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = percent;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
ct_test(pTest, status == true);
}
#endif
#endif
static void Load_Control_WriteProperty_Request_Shed_Level(Test * pTest,
int instance, unsigned level)
{
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
value.context_specific = true;
value.context_tag = 1;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = level;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
value.context_specific = true;
value.context_tag = 1;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = level;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
}
ct_test(pTest, status == true);
}
#if 0
static void Load_Control_WriteProperty_Request_Shed_Amount(Test * pTest,
int instance, float amount)
{
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
value.context_specific = true;
value.context_tag = 2;
value.tag = BACNET_APPLICATION_TAG_REAL;
value.type.Real = amount;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
value.context_specific = true;
value.context_tag = 2;
value.tag = BACNET_APPLICATION_TAG_REAL;
value.type.Real = amount;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
ct_test(pTest, status == true);
}
#endif
#endif
static void Load_Control_WriteProperty_Enable(Test * pTest, int instance,
bool enable)
{
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
/* Set Enable=TRUE */
wp_data.object_property = PROP_ENABLE;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_BOOLEAN;
value.type.Boolean = enable;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
/* Set Enable=TRUE */
wp_data.object_property = PROP_ENABLE;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_BOOLEAN;
value.type.Boolean = enable;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
}
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Shed_Duration(Test * pTest,
int instance, unsigned duration)
{
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_SHED_DURATION;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = duration;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_SHED_DURATION;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = duration;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
}
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Duty_Window(Test * pTest,
int instance, unsigned duration)
{
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_DUTY_WINDOW;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = duration;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_DUTY_WINDOW;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
value.type.Unsigned_Int = duration;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
}
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Start_Time_Wildcards(Test * pTest,
int instance)
{
int len = 0;
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_START_TIME;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_DATE;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_START_TIME;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_DATE;
datetime_date_wildcard_set(&value.type.Date);
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
len = wp_data.application_data_len;
value.tag = BACNET_APPLICATION_TAG_TIME;
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
len = wp_data.application_data_len;
value.tag = BACNET_APPLICATION_TAG_TIME;
datetime_time_wildcard_set(&value.type.Time);
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[len], &value);
ct_test(pTest, wp_data.application_data_len > 0);
wp_data.application_data_len += len;
status = Load_Control_Write_Property(&wp_data,
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[len], &value);
ct_test(pTest, wp_data.application_data_len > 0);
wp_data.application_data_len += len;
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
}
ct_test(pTest, status == true);
}
static void Load_Control_WriteProperty_Start_Time(Test * pTest, int instance,
uint16_t year, uint8_t month, uint8_t day,
@@ -1192,38 +1192,38 @@ static void Load_Control_WriteProperty_Start_Time(Test * pTest, int instance,
{
int len = 0;
bool status = false;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_APPLICATION_DATA_VALUE value;
BACNET_WRITE_PROPERTY_DATA wp_data;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
wp_data.object_type = OBJECT_LOAD_CONTROL;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_START_TIME;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_DATE;
wp_data.object_instance = instance;
wp_data.array_index = BACNET_ARRAY_ALL;
wp_data.priority = BACNET_NO_PRIORITY;
wp_data.object_property = PROP_START_TIME;
value.context_specific = false;
value.context_tag = 0;
value.tag = BACNET_APPLICATION_TAG_DATE;
datetime_set_date(&value.type.Date, year, month, day);
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
len = wp_data.application_data_len;
value.tag = BACNET_APPLICATION_TAG_TIME;
bacapp_encode_data(&wp_data.application_data[0], &value);
ct_test(pTest, wp_data.application_data_len > 0);
len = wp_data.application_data_len;
value.tag = BACNET_APPLICATION_TAG_TIME;
datetime_set_time(&value.type.Time, hour, minute, seconds, hundredths);
wp_data.application_data_len =
bacapp_encode_data(&wp_data.application_data[len], &value);
ct_test(pTest, wp_data.application_data_len > 0);
wp_data.application_data_len += len;
status = Load_Control_Write_Property(&wp_data,
bacapp_encode_data(&wp_data.application_data[len], &value);
ct_test(pTest, wp_data.application_data_len > 0);
wp_data.application_data_len += len;
status = Load_Control_Write_Property(&wp_data,
&error_class, &error_code);
ct_test(pTest, status == true);
}
ct_test(pTest, status == true);
}
void testLoadControlStateMachine(Test * pTest)
{
unsigned i = 0, j = 0;
unsigned i = 0, j = 0;
uint8_t level = 0;
Load_Control_Init();
@@ -1233,13 +1233,13 @@ void testLoadControlStateMachine(Test * pTest)
for (i = 0; i < MAX_LOAD_CONTROLS; i++) {
ct_test(pTest, Load_Control_State[i] == SHED_INACTIVE);
}
}
/* SHED_REQUEST_PENDING */
/* CancelShed - Start time has wildcards */
Load_Control_WriteProperty_Enable(pTest, 0, true);
Load_Control_WriteProperty_Shed_Duration(pTest, 0, 60);
Load_Control_WriteProperty_Start_Time_Wildcards(pTest, 0);
Load_Control_State_Machine(0);
}
/* SHED_REQUEST_PENDING */
/* CancelShed - Start time has wildcards */
Load_Control_WriteProperty_Enable(pTest, 0, true);
Load_Control_WriteProperty_Shed_Duration(pTest, 0, 60);
Load_Control_WriteProperty_Start_Time_Wildcards(pTest, 0);
Load_Control_State_Machine(0);
ct_test(pTest, Load_Control_State[0] == SHED_REQUEST_PENDING);
Load_Control_State_Machine(0);
ct_test(pTest, Load_Control_State[0] == SHED_INACTIVE);
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -159,7 +159,8 @@ int Life_Safety_Point_Encode_Property_APDU(uint8_t * apdu,
unsigned object_index = 0;
bool state = false;
BACNET_RELIABILITY reliability = RELIABILITY_NO_FAULT_DETECTED;
(void) array_index; /* currently not used */
Life_Safety_Point_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
@@ -354,3 +355,4 @@ int main(void)
}
#endif /* TEST_LIFE_SAFETY_POINT */
#endif /* TEST */
File diff suppressed because it is too large Load Diff
+88 -88
View File
@@ -1,88 +1,88 @@
#Makefile to build BACnet Application for the Linux Port
CC = gcc
BASEDIR = .
#CFLAGS = -Wall -I.
# -g for debugging with gdb
#CFLAGS = -Wall -I. -O2 -g
# Note: you can strip out symbols using the strip command
# to get an idea of how big the compile really is.
# Configure the BACnet Datalink Layer
#BACDL_DEFINE=-DBACDL_ETHERNET=1
#BACDL_DEFINE=-DBACDL_ARCNET=1
BACDL_DEFINE=-DBACDL_BIP=1
BACNET_DEFINES=-DBACFILE=1 -DTSM_ENABLED=0 -DBIG_ENDIAN=0 -DPRINT_ENABLED=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
BACNET_PORT = ../../ports/linux
BACNET_OBJECT = ../object
BACNET_HANDLER = ../handler
BACNET_ROOT = ../..
INCLUDES = -I$(BACNET_ROOT) -I$(BACNET_PORT) -I$(BACNET_OBJECT) -I$(BACNET_HANDLER)
CFLAGS = -Wall -g $(INCLUDES) $(DEFINES)
TARGET = bacucov
SRCS = main.c \
$(BACNET_PORT)/bip-init.c \
$(BACNET_PORT)/ethernet.c \
$(BACNET_PORT)/arcnet.c \
$(BACNET_ROOT)/bip.c \
$(BACNET_HANDLER)/txbuf.c \
$(BACNET_HANDLER)/noserv.c \
$(BACNET_HANDLER)/h_whois.c \
$(BACNET_HANDLER)/h_rp.c \
$(BACNET_HANDLER)/h_iam.c \
$(BACNET_OBJECT)/device.c \
$(BACNET_OBJECT)/ai.c \
$(BACNET_OBJECT)/ao.c \
$(BACNET_OBJECT)/av.c \
$(BACNET_OBJECT)/bi.c \
$(BACNET_OBJECT)/bo.c \
$(BACNET_OBJECT)/bv.c \
$(BACNET_OBJECT)/lc.c \
$(BACNET_OBJECT)/lsp.c \
$(BACNET_OBJECT)/mso.c \
$(BACNET_OBJECT)/bacfile.c \
$(BACNET_ROOT)/filename.c \
$(BACNET_ROOT)/rp.c \
$(BACNET_ROOT)/wp.c \
$(BACNET_ROOT)/bacdcode.c \
$(BACNET_ROOT)/bacapp.c \
$(BACNET_ROOT)/bacprop.c \
$(BACNET_ROOT)/bacstr.c \
$(BACNET_ROOT)/bactext.c \
$(BACNET_ROOT)/indtext.c \
$(BACNET_ROOT)/datetime.c \
$(BACNET_ROOT)/whois.c \
$(BACNET_ROOT)/iam.c \
$(BACNET_ROOT)/address.c \
$(BACNET_ROOT)/arf.c \
$(BACNET_ROOT)/cov.c \
$(BACNET_ROOT)/dcc.c \
$(BACNET_ROOT)/abort.c \
$(BACNET_ROOT)/reject.c \
$(BACNET_ROOT)/bacerror.c \
$(BACNET_ROOT)/apdu.c \
$(BACNET_ROOT)/npdu.c
OBJS = ${SRCS:.c=.o}
all: ${TARGET}
${TARGET}: ${OBJS}
${CC} -o $@ ${OBJS}
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET} $(OBJS) *.bak ports/linux/*.bak *.1 *.ini
include: .depend
#Makefile to build BACnet Application for the Linux Port
CC = gcc
BASEDIR = .
#CFLAGS = -Wall -I.
# -g for debugging with gdb
#CFLAGS = -Wall -I. -O2 -g
# Note: you can strip out symbols using the strip command
# to get an idea of how big the compile really is.
# Configure the BACnet Datalink Layer
#BACDL_DEFINE=-DBACDL_ETHERNET=1
#BACDL_DEFINE=-DBACDL_ARCNET=1
BACDL_DEFINE=-DBACDL_BIP=1
BACNET_DEFINES=-DBACFILE=1 -DTSM_ENABLED=0 -DBIG_ENDIAN=0 -DPRINT_ENABLED=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
BACNET_PORT = ../../ports/linux
BACNET_OBJECT = ../object
BACNET_HANDLER = ../handler
BACNET_ROOT = ../..
INCLUDES = -I$(BACNET_ROOT) -I$(BACNET_PORT) -I$(BACNET_OBJECT) -I$(BACNET_HANDLER)
CFLAGS = -Wall -g $(INCLUDES) $(DEFINES)
TARGET = bacucov
SRCS = main.c \
$(BACNET_PORT)/bip-init.c \
$(BACNET_PORT)/ethernet.c \
$(BACNET_PORT)/arcnet.c \
$(BACNET_ROOT)/bip.c \
$(BACNET_HANDLER)/txbuf.c \
$(BACNET_HANDLER)/noserv.c \
$(BACNET_HANDLER)/h_whois.c \
$(BACNET_HANDLER)/h_rp.c \
$(BACNET_HANDLER)/h_iam.c \
$(BACNET_OBJECT)/device.c \
$(BACNET_OBJECT)/ai.c \
$(BACNET_OBJECT)/ao.c \
$(BACNET_OBJECT)/av.c \
$(BACNET_OBJECT)/bi.c \
$(BACNET_OBJECT)/bo.c \
$(BACNET_OBJECT)/bv.c \
$(BACNET_OBJECT)/lc.c \
$(BACNET_OBJECT)/lsp.c \
$(BACNET_OBJECT)/mso.c \
$(BACNET_OBJECT)/bacfile.c \
$(BACNET_ROOT)/filename.c \
$(BACNET_ROOT)/rp.c \
$(BACNET_ROOT)/wp.c \
$(BACNET_ROOT)/bacdcode.c \
$(BACNET_ROOT)/bacapp.c \
$(BACNET_ROOT)/bacprop.c \
$(BACNET_ROOT)/bacstr.c \
$(BACNET_ROOT)/bactext.c \
$(BACNET_ROOT)/indtext.c \
$(BACNET_ROOT)/datetime.c \
$(BACNET_ROOT)/whois.c \
$(BACNET_ROOT)/iam.c \
$(BACNET_ROOT)/address.c \
$(BACNET_ROOT)/arf.c \
$(BACNET_ROOT)/cov.c \
$(BACNET_ROOT)/dcc.c \
$(BACNET_ROOT)/abort.c \
$(BACNET_ROOT)/reject.c \
$(BACNET_ROOT)/bacerror.c \
$(BACNET_ROOT)/apdu.c \
$(BACNET_ROOT)/npdu.c
OBJS = ${SRCS:.c=.o}
all: ${TARGET}
${TARGET}: ${OBJS}
${CC} -o $@ ${OBJS}
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET} $(OBJS) *.bak ports/linux/*.bak *.1 *.ini
include: .depend
+3 -3
View File
@@ -204,9 +204,9 @@ int main(int argc, char *argv[])
}
/* setup my info */
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
if (!datalink_init(NULL))
return 1;
Init_Service_Handlers();
if (!datalink_init(NULL))
return 1;
/* only one value in our value list */
cov_data.listOfValues.next = NULL;
ucov_notify_send(&Handler_Transmit_Buffer[0], &cov_data);
+153 -153
View File
@@ -1,153 +1,153 @@
#
# Simple makefile to build an executable for Win32
#
# 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 = bacucov
PRODUCT_EXE = $(PRODUCT).exe
# Choose the Data Link Layer to Enable
DEFINES = -DBACDL_BIP=1;TSM_ENABLED=0;BIG_ENDIAN=0;PRINT_ENABLED=1
SRCS = main.c \
..\..\ports\win32\bip-init.c \
..\..\filename.c \
..\..\bip.c \
..\..\demo\handler\txbuf.c \
..\..\demo\handler\noserv.c \
..\..\demo\handler\h_whois.c \
..\..\demo\handler\h_iam.c \
..\..\demo\handler\h_rp.c \
..\..\bacdcode.c \
..\..\bacapp.c \
..\..\bacstr.c \
..\..\bactext.c \
..\..\indtext.c \
..\..\datetime.c \
..\..\whois.c \
..\..\iam.c \
..\..\rp.c \
..\..\wp.c \
..\..\arf.c \
..\..\awf.c \
..\..\cov.c \
..\..\dcc.c \
..\..\demo\object\bacfile.c \
..\..\demo\object\device.c \
..\..\demo\object\ai.c \
..\..\demo\object\ao.c \
..\..\demo\object\av.c \
..\..\demo\object\bi.c \
..\..\demo\object\bo.c \
..\..\demo\object\bv.c \
..\..\demo\object\lc.c \
..\..\demo\object\lsp.c \
..\..\demo\object\mso.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
LINK = $(BORLAND_DIR)\bin\ilink32
TLIB = $(BORLAND_DIR)\bin\tlib
#
# Include directories
#
CC_DIR = $(BORLAND_DIR)\BIN
INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\object\;..\..\demo\handler\;..\..\ports\win32\;.
CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES)
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
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)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\utils\$(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$(C_LIB_DIR) -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 $(OBJS) # command too long, bummer!
del *.obj
del ..\..\*.obj
del ..\..\demo\handler\*.obj
del ..\..\demo\object\*.obj
del ..\..\ports\win32\*.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
#
# Simple makefile to build an executable for Win32
#
# 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 = bacucov
PRODUCT_EXE = $(PRODUCT).exe
# Choose the Data Link Layer to Enable
DEFINES = -DBACDL_BIP=1;TSM_ENABLED=0;BIG_ENDIAN=0;PRINT_ENABLED=1
SRCS = main.c \
..\..\ports\win32\bip-init.c \
..\..\filename.c \
..\..\bip.c \
..\..\demo\handler\txbuf.c \
..\..\demo\handler\noserv.c \
..\..\demo\handler\h_whois.c \
..\..\demo\handler\h_iam.c \
..\..\demo\handler\h_rp.c \
..\..\bacdcode.c \
..\..\bacapp.c \
..\..\bacstr.c \
..\..\bactext.c \
..\..\indtext.c \
..\..\datetime.c \
..\..\whois.c \
..\..\iam.c \
..\..\rp.c \
..\..\wp.c \
..\..\arf.c \
..\..\awf.c \
..\..\cov.c \
..\..\dcc.c \
..\..\demo\object\bacfile.c \
..\..\demo\object\device.c \
..\..\demo\object\ai.c \
..\..\demo\object\ao.c \
..\..\demo\object\av.c \
..\..\demo\object\bi.c \
..\..\demo\object\bo.c \
..\..\demo\object\bv.c \
..\..\demo\object\lc.c \
..\..\demo\object\lsp.c \
..\..\demo\object\mso.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
LINK = $(BORLAND_DIR)\bin\ilink32
TLIB = $(BORLAND_DIR)\bin\tlib
#
# Include directories
#
CC_DIR = $(BORLAND_DIR)\BIN
INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\object\;..\..\demo\handler\;..\..\ports\win32\;.
CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES)
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
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)
install: $(PRODUCT_EXE)
copy $(PRODUCT_EXE) ..\..\utils\$(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$(C_LIB_DIR) -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 $(OBJS) # command too long, bummer!
del *.obj
del ..\..\*.obj
del ..\..\demo\handler\*.obj
del ..\..\demo\object\*.obj
del ..\..\ports\win32\*.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
+2 -2
View File
@@ -310,8 +310,8 @@ int main(int argc, char *argv[])
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
address_init();
Init_Service_Handlers();
if (!datalink_init(NULL))
return 1;
if (!datalink_init(NULL))
return 1;
/* configure the timeout values */
last_seconds = time(NULL);
timeout_seconds = (Device_APDU_Timeout() / 1000) *
+10 -10
View File
@@ -1,10 +1,10 @@
BACnet Stack @ SourceForge.net
Build using Code Blocks
Q1: GNU GCC Compiler, undefined reference to closesocket
A1: Under Project->Build Options->Linker settings,
add "ws2_32" to Link Libraries.
BACnet Stack @ SourceForge.net
Build using Code Blocks
Q1: GNU GCC Compiler, undefined reference to closesocket
A1: Under Project->Build Options->Linker settings,
add "ws2_32" to Link Libraries.
+7 -7
View File
@@ -1,7 +1,7 @@
BACnet Stack - SourceForge.net
Build for Visual Studio 2005 Express Edition
Q1: Cannot open include file: 'winsock2.h'
A1: Install the Microsoft Platform SDK:
http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/default.aspx
BACnet Stack - SourceForge.net
Build for Visual Studio 2005 Express Edition
Q1: Cannot open include file: 'winsock2.h'
A1: Install the Microsoft Platform SDK:
http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/default.aspx
+27 -27
View File
@@ -1,27 +1,27 @@
To Do List - BACnet Stack at SourceForge
For this release, here are some things to do:
1. Change bip_init to datalink_init in demos (done, STK)
2. Change demos main file to main.c (done, STK)
3. Add parameter passing for IP address or interface for
multi homed systems. (done, STK)
4. Validate the unit tests compile after BIG_ENDIAN change. (done,STK)
5. Add arcnet.c and ethernet.c to all the linux Makefiles (done, STK)
6. Refactor Makefile DEFINES like demo/server/Makefile. (done, STK)
For a later release, here are some things to do:
1. Finish demo/epics/main.c - EPICS demo
2. Finish demo/object/lo.c - Lighting Output object demo
3. Complete bvlc.c and use it instead of or in compliment to bip.c
4. Complete demo for ReadPropertyMultiple from rpm.c
5. Add HTTP demo like bacnet4linux
6. Add subscribe to change of value support in server demo
7. Add hooks to increment Database_Revision property
8. Add BBMD and FD support to server example for BACnet/IP.
9. Add Foreign Device registration options to client examples.
A. Change bip.c to not use extra buffer (shift data)
B. Finish subscribe COV support in server demo.
C. Add Visual Studio 2005 makefiles or projects for demos.
D. Add Code::Blocks projects for demos.
To Do List - BACnet Stack at SourceForge
For this release, here are some things to do:
1. Change bip_init to datalink_init in demos (done, STK)
2. Change demos main file to main.c (done, STK)
3. Add parameter passing for IP address or interface for
multi homed systems. (done, STK)
4. Validate the unit tests compile after BIG_ENDIAN change. (done,STK)
5. Add arcnet.c and ethernet.c to all the linux Makefiles (done, STK)
6. Refactor Makefile DEFINES like demo/server/Makefile. (done, STK)
For a later release, here are some things to do:
1. Finish demo/epics/main.c - EPICS demo
2. Finish demo/object/lo.c - Lighting Output object demo
3. Complete bvlc.c and use it instead of or in compliment to bip.c
4. Complete demo for ReadPropertyMultiple from rpm.c
5. Add HTTP demo like bacnet4linux
6. Add subscribe to change of value support in server demo
7. Add hooks to increment Database_Revision property
8. Add BBMD and FD support to server example for BACnet/IP.
9. Add Foreign Device registration options to client examples.
A. Change bip.c to not use extra buffer (shift data)
B. Finish subscribe COV support in server demo.
C. Add Visual Studio 2005 makefiles or projects for demos.
D. Add Code::Blocks projects for demos.
+482 -482
View File
@@ -1,436 +1,436 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
<TITLE>BACnet stack - open source BACnet protocol stack</TITLE>
</HEAD>
<BODY LANG="en-US">
<h1>BACnet Stack</h1>
<h2>An open source BACnet protocol stack for embedded systems</h2>
<hr>
<h2>About this Project</h2>
<P><a href="http://sourceforge.net/projects/bacnet/">This BACnet protocol stack library</a>
provides a BACnet application layer, network layer and media access (MAC)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
<TITLE>BACnet stack - open source BACnet protocol stack</TITLE>
</HEAD>
<BODY LANG="en-US">
<h1>BACnet Stack</h1>
<h2>An open source BACnet protocol stack for embedded systems</h2>
<hr>
<h2>About this Project</h2>
<P><a href="http://sourceforge.net/projects/bacnet/">This BACnet protocol stack library</a>
provides a BACnet application layer, network layer and media access (MAC)
layer communications services. It is an open source, royalty-free library
for an embedded system, Windows, Linux, or other operating system. Example
BACnet client and server applications are included.</p>
<P>BACnet - A Data Communication Protocol for Building
Automation and Control Networks - see <a
href="http://www.bacnet.org/">bacnet.org</a>. BACnet is a standard data
communication protocol for Building Automation and Control Networks. BACnet
is an open protocol, which means anyone can contribute to the standard, and
anyone may use it. The only caveat is that the BACnet standard document
itself is copyrighted by ASHRAE, and they sell the document to help defray
costs of developing and maintaining the standard (just like IEEE or ANSI or
ISO).</P>
<P>For software developers, the BACnet protocol is a standard way to send and
receive messages on the wire containing data that is understood by other
BACnet compliant devices. The BACnet standard defines a standard way to
communicate over a number of wires, known as Data Link/Physical Layers:
Ethernet, EIA-485, EIA-232, ARCNET, and LonTalk. The BACnet standard also
defines a standard way to communicate using UDP, IP and HTTP (Web
Services).</P>
There are other open source projects for BACnet:</p>
<ul>
<li><a href="http://vts.sourceforge.net/">VTS</a> - visual test shell for
Win32, used for Visually testing a BACnet implementation. It also includes
a detailed network sniffer for BACnet messages, and the ability to send
any BACnet services. The source code is in the public domain. </li>
<li><a href="http://www.wireshark.org/">Wireshark</a> - an open source,
cross platform protocol analyzer with BACnet support. The detailed BACnet
support began in version 0.10.11 released on May 4, 2005 when Wireshark
was known as Ethereal.</li>
<li><a href="http://bacnet4linux.sourceforge.net/">BACnet4Linux</a> - an
LGPL BACnet application that requires Linux as the OS.</li>
<li><a href="http://bfr.sourceforge.net/">BACnet Firewall Router</a> -an
application that combines BACnet routing capability with traffic management
functions to carefully control access to building automation and control
networks.</li>
<li><a href="http://bacpypes.sourceforge.net/">BACpypes</a> - a
BACnet stack written in Python.</li>
</ul>
<p>There are also commercial BACnet protocol source code libraries for BACnet
that are designed for embedded use:</p>
<ul>
<li><a href="http://www.cimetrics.com">Cimetrics</a><font
size="-2"><sup>TM</sup></font> - has a source library
called BACstac/32 as part of their BACNet Protocol Stack SDK.</li>
<li><a href="http://www.polarsoft.biz">Polarsoft</a> - has a
protocol stack source library for embedded use called FreeRange<font
size="-2"><sup>TM</sup></font> and PolarSoft&#174; FreeRange VSB (Very
Small BACnet stack).</li>
<li><a href="http://www.scadaengine.com/">SCADA Engine</a> - The BACnet
Linux Server is a complete BACnet Device running on the linux platform.
The entire source code is available for custom applications and has been
written in ANSI C which has been succesfully ported to Unix,
VxWorks etc. </li>
</ul>
<h2>Licensing</h2>
<p>Our BACnet protocol stack implementation is specifically designed for the
embedded BACnet appliance, using a GPL with exception license (like <a
href="http://ecos.sourceware.org/">eCos</a>),
which means that any changes to the core code that are distributed are
made available, but the BACnet library can be linked to
proprietary code without it becoming licensed under the GPL.
BACnet client and server applications are included.</p>
<P>BACnet - A Data Communication Protocol for Building
Automation and Control Networks - see <a
href="http://www.bacnet.org/">bacnet.org</a>. BACnet is a standard data
communication protocol for Building Automation and Control Networks. BACnet
is an open protocol, which means anyone can contribute to the standard, and
anyone may use it. The only caveat is that the BACnet standard document
itself is copyrighted by ASHRAE, and they sell the document to help defray
costs of developing and maintaining the standard (just like IEEE or ANSI or
ISO).</P>
<P>For software developers, the BACnet protocol is a standard way to send and
receive messages on the wire containing data that is understood by other
BACnet compliant devices. The BACnet standard defines a standard way to
communicate over a number of wires, known as Data Link/Physical Layers:
Ethernet, EIA-485, EIA-232, ARCNET, and LonTalk. The BACnet standard also
defines a standard way to communicate using UDP, IP and HTTP (Web
Services).</P>
There are other open source projects for BACnet:</p>
<ul>
<li><a href="http://vts.sourceforge.net/">VTS</a> - visual test shell for
Win32, used for Visually testing a BACnet implementation. It also includes
a detailed network sniffer for BACnet messages, and the ability to send
any BACnet services. The source code is in the public domain. </li>
<li><a href="http://www.wireshark.org/">Wireshark</a> - an open source,
cross platform protocol analyzer with BACnet support. The detailed BACnet
support began in version 0.10.11 released on May 4, 2005 when Wireshark
was known as Ethereal.</li>
<li><a href="http://bacnet4linux.sourceforge.net/">BACnet4Linux</a> - an
LGPL BACnet application that requires Linux as the OS.</li>
<li><a href="http://bfr.sourceforge.net/">BACnet Firewall Router</a> -an
application that combines BACnet routing capability with traffic management
functions to carefully control access to building automation and control
networks.</li>
<li><a href="http://bacpypes.sourceforge.net/">BACpypes</a> - a
BACnet stack written in Python.</li>
</ul>
<p>There are also commercial BACnet protocol source code libraries for BACnet
that are designed for embedded use:</p>
<ul>
<li><a href="http://www.cimetrics.com">Cimetrics</a><font
size="-2"><sup>TM</sup></font> - has a source library
called BACstac/32 as part of their BACNet Protocol Stack SDK.</li>
<li><a href="http://www.polarsoft.biz">Polarsoft</a> - has a
protocol stack source library for embedded use called FreeRange<font
size="-2"><sup>TM</sup></font> and PolarSoft&#174; FreeRange VSB (Very
Small BACnet stack).</li>
<li><a href="http://www.scadaengine.com/">SCADA Engine</a> - The BACnet
Linux Server is a complete BACnet Device running on the linux platform.
The entire source code is available for custom applications and has been
written in ANSI C which has been succesfully ported to Unix,
VxWorks etc. </li>
</ul>
<h2>Licensing</h2>
<p>Our BACnet protocol stack implementation is specifically designed for the
embedded BACnet appliance, using a GPL with exception license (like <a
href="http://ecos.sourceware.org/">eCos</a>),
which means that any changes to the core code that are distributed are
made available, but the BACnet library can be linked to
proprietary code without it becoming licensed under the GPL.
See the <a href="http://ecos.sourceware.org/license-overview.html">eCos license overview</a> for
easy to read details about this exception to the GPL.
The license does <i>not</i> require users to release the source code of any
easy to read details about this exception to the GPL.
The license does <i>not</i> require users to release the source code of any
<i>applications</i> that are developed with this BACnet stack - only portions of
the BACnet stack that have been modified. Note that those files in this
BACnet stack that are expected to be modified are licensed using the
<a href="http://en.wikipedia.org/wiki/MIT_License">MIT License</a>.<p>
<p>The text of the GPL exception included in each source file is as
follows:</p>
<blockquote>
<p>"As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License."<p>
</blockquote>
<h2>The source code</h2>
<p>The source code is written in C for portability, and includes
unit tests (PC based unit tests) and example application code.
Since the code is designed to be
portable, it compiles with GCC as well as other compilers,
such as Borland C++, Visual C++, MinGW, Code Warrior, or MicroChip C18.
The source code is also designed to be readable, understandable,
and most importantly, easy to use.</p>
<p>The BACnet protocol is an ASHRAE/ANSI/ISO standard, so this library
adheres to that standard. BACnet has no royalties or licensing restrictions,
and <a href="http://www.bacnet.org/VendorID/">registration for a BACnet
vendor ID</a> is free.</p>
<h2>What the code does</h2>
<p>The BACnet stack comes with example applications
that can be run under Linux, Win32, RTOS-32, and just about any embedded
microcontroller.</p>
<p>The BACnet stack includes unit tests can be run in a command shell on Linux using the
unittest.sh script, or using individual .mak files. They were tested under
<a href="http://www.debian.org/">Debian GNU/Linux</a> and <a href="http://www.ubuntu.com/">Ubuntu Linux</a>.</p>
<p>The BACnet stack was functionally tested
using <a href="http://vts.sourceforge.net/">VTS (Visual Test Shell)</a>,
another project hosted on SourceForge, as well as various BACnet controllers,
BACnet workstations, and through BACnet routers.<p>
<p>Using a master Makefile in the project root directory, a dozen or so
demo applications can be created that run under Linux or Win32.
Linux supports BACnet Ethernet, BACnet/IP, or ARCNET data link layer
for communication, and BACnet/IP is supported under Win32. BACnet Ethernet
can also be used under Win32 with the <a href="http://www.winpcap.org/">WinPcap library</a>.
Root priveleges are required to run the Ethernet or ARCNET interfaces
on Linux, but not needed to run BACnet/IP.</p>
<code>
$ make clean all<br>
$ demo/server/bacsrv 123<br>
BACnet Server Demo - Device #123<br>
<br>
$ demo/readprop/bacrp<br>
bacrp device-instance object-type object-instance property [index]<br>
<br>
$ demo/writeprop/bacwp<br>
bacwp device-instance object-type object-instance property tag value [priority] [index]<br>
<br>
$ demo/readfile/bacarf<br>
bacarf device-instance file-instance local-name<br>
<br>
$ demo/writefile/bacawf<br>
bacawf device-instance file-instance local-name<br>
<br>
$ demo/reinit/bacrd<br>
Usage: bacrd device-instance state [password]<br>
Send BACnet ReinitializeDevice service to device.<br>
<br>
$ demo/whohas/bacwh<br>
Usage: bacwh object-type object-instance | object-name<br>
Send BACnet WhoHas request to devices, and wait for responses.<br>
<br>
$ demo/dcc/bacdcc<br>
Usage: bacdcc device-instance state timeout [password]<br>
Send BACnet DeviceCommunicationControl service to device.<br>
<br>
$ demo/timesync/bacts<br>
Received TimeSyncronization Request<br>
2006/8/30 07:10:45.00<br>
<br>
$ demo/ucov/bacucov<br>
Usage: bacucov pid device-id object-type object-instance time property tag value [priority] [index]<br>
<br>
$ demo/whois/bacwi<br>
Usage: bacwi device-instance | device-instance-min device-instance-max<br>
Send BACnet WhoIs request to devices, and wait for responses.<br>
<br>
The device-instance can be 0 to 4194303, or -1 for ALL.<br>
The device-instance can also be specified as a range.<br>
<br>
</code>
<p>The demos can be compiled under Win32 using <a href="http://www.borland.com/bcppbuilder/freecompiler/">Borland C++</a> or
<a href="http://msdn.microsoft.com/visualc/vctoolkit2003/">Microsoft Visual C++</a>, both of which
are free (as in beer) command line compilers. Be sure to pick up the free
<a href="http://info.borland.com/devsupport/bcppbuilder/patches/#freecompiler55">patches (service packs) for the Borland C++ compiler</a> (<a href="http://info.borland.com/devsupport/bcppbuilder/patches/bcc55/bcc55sp1.zip">SP1</a>, <a href="http://info.borland.com/devsupport/bcppbuilder/patches/bcc55/bcc55sp2.exe">SP2</a>), as well as the free turbo debugger. It might also be possible to create Win32 projects using the free <a href="http://msdn.microsoft.com/vstudio/express/">Visual Studio Express Edition</a> or <a href="http://www.mingw.org/">MinGW - Minimalist GNU for Windows</a>, but I have haven't tried it. I have used <a href="http://codeblocks.org/">Code::Blocks</a> for compiling the unit tests using the MinGW compiler, but have not tried to get the demos working with MinGW. I have used <a href="http://codeblocks.org/">Code::Blocks</a> with the Borland C++ compiler and it successfully compiles the code.</p>
<p>There is a Makefile in the ports/rtos32 directory, and a sample
application that runs under <a href="http://www.on-time.com/">RTOS-32</a>.
It currently uses the BACnet/IP data link layer for communication, and also
has an MS/TP datalink layer sample application.
It compiles using <a href="http://borland.com/">Borland C++</a>.</p>
<p>There is a project in the ports/pic18f6720 directory, and a sample
application that can be build using <a href="http://microchip.com">MP-Lab</a>
<a href="http://en.wikipedia.org/wiki/MIT_License">MIT License</a>.<p>
<p>The text of the GPL exception included in each source file is as
follows:</p>
<blockquote>
<p>"As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License."<p>
</blockquote>
<h2>The source code</h2>
<p>The source code is written in C for portability, and includes
unit tests (PC based unit tests) and example application code.
Since the code is designed to be
portable, it compiles with GCC as well as other compilers,
such as Borland C++, Visual C++, MinGW, Code Warrior, or MicroChip C18.
The source code is also designed to be readable, understandable,
and most importantly, easy to use.</p>
<p>The BACnet protocol is an ASHRAE/ANSI/ISO standard, so this library
adheres to that standard. BACnet has no royalties or licensing restrictions,
and <a href="http://www.bacnet.org/VendorID/">registration for a BACnet
vendor ID</a> is free.</p>
<h2>What the code does</h2>
<p>The BACnet stack comes with example applications
that can be run under Linux, Win32, RTOS-32, and just about any embedded
microcontroller.</p>
<p>The BACnet stack includes unit tests can be run in a command shell on Linux using the
unittest.sh script, or using individual .mak files. They were tested under
<a href="http://www.debian.org/">Debian GNU/Linux</a> and <a href="http://www.ubuntu.com/">Ubuntu Linux</a>.</p>
<p>The BACnet stack was functionally tested
using <a href="http://vts.sourceforge.net/">VTS (Visual Test Shell)</a>,
another project hosted on SourceForge, as well as various BACnet controllers,
BACnet workstations, and through BACnet routers.<p>
<p>Using a master Makefile in the project root directory, a dozen or so
demo applications can be created that run under Linux or Win32.
Linux supports BACnet Ethernet, BACnet/IP, or ARCNET data link layer
for communication, and BACnet/IP is supported under Win32. BACnet Ethernet
can also be used under Win32 with the <a href="http://www.winpcap.org/">WinPcap library</a>.
Root priveleges are required to run the Ethernet or ARCNET interfaces
on Linux, but not needed to run BACnet/IP.</p>
<code>
$ make clean all<br>
$ demo/server/bacsrv 123<br>
BACnet Server Demo - Device #123<br>
<br>
$ demo/readprop/bacrp<br>
bacrp device-instance object-type object-instance property [index]<br>
<br>
$ demo/writeprop/bacwp<br>
bacwp device-instance object-type object-instance property tag value [priority] [index]<br>
<br>
$ demo/readfile/bacarf<br>
bacarf device-instance file-instance local-name<br>
<br>
$ demo/writefile/bacawf<br>
bacawf device-instance file-instance local-name<br>
<br>
$ demo/reinit/bacrd<br>
Usage: bacrd device-instance state [password]<br>
Send BACnet ReinitializeDevice service to device.<br>
<br>
$ demo/whohas/bacwh<br>
Usage: bacwh object-type object-instance | object-name<br>
Send BACnet WhoHas request to devices, and wait for responses.<br>
<br>
$ demo/dcc/bacdcc<br>
Usage: bacdcc device-instance state timeout [password]<br>
Send BACnet DeviceCommunicationControl service to device.<br>
<br>
$ demo/timesync/bacts<br>
Received TimeSyncronization Request<br>
2006/8/30 07:10:45.00<br>
<br>
$ demo/ucov/bacucov<br>
Usage: bacucov pid device-id object-type object-instance time property tag value [priority] [index]<br>
<br>
$ demo/whois/bacwi<br>
Usage: bacwi device-instance | device-instance-min device-instance-max<br>
Send BACnet WhoIs request to devices, and wait for responses.<br>
<br>
The device-instance can be 0 to 4194303, or -1 for ALL.<br>
The device-instance can also be specified as a range.<br>
<br>
</code>
<p>The demos can be compiled under Win32 using <a href="http://www.borland.com/bcppbuilder/freecompiler/">Borland C++</a> or
<a href="http://msdn.microsoft.com/visualc/vctoolkit2003/">Microsoft Visual C++</a>, both of which
are free (as in beer) command line compilers. Be sure to pick up the free
<a href="http://info.borland.com/devsupport/bcppbuilder/patches/#freecompiler55">patches (service packs) for the Borland C++ compiler</a> (<a href="http://info.borland.com/devsupport/bcppbuilder/patches/bcc55/bcc55sp1.zip">SP1</a>, <a href="http://info.borland.com/devsupport/bcppbuilder/patches/bcc55/bcc55sp2.exe">SP2</a>), as well as the free turbo debugger. It might also be possible to create Win32 projects using the free <a href="http://msdn.microsoft.com/vstudio/express/">Visual Studio Express Edition</a> or <a href="http://www.mingw.org/">MinGW - Minimalist GNU for Windows</a>, but I have haven't tried it. I have used <a href="http://codeblocks.org/">Code::Blocks</a> for compiling the unit tests using the MinGW compiler, but have not tried to get the demos working with MinGW. I have used <a href="http://codeblocks.org/">Code::Blocks</a> with the Borland C++ compiler and it successfully compiles the code.</p>
<p>There is a Makefile in the ports/rtos32 directory, and a sample
application that runs under <a href="http://www.on-time.com/">RTOS-32</a>.
It currently uses the BACnet/IP data link layer for communication, and also
has an MS/TP datalink layer sample application.
It compiles using <a href="http://borland.com/">Borland C++</a>.</p>
<p>There is a project in the ports/pic18f6720 directory, and a sample
application that can be build using <a href="http://microchip.com">MP-Lab</a>
and the Microchip compiler MCC18. The datalink layer uses BACnet MS/TP
and the example uses several different objects and services.</p>
<TABLE border="1" width="100%" cellpadding="1" cellspacing="0"
summary="BACnet services supported matrix">
<TBODY>
<TR><H2>BACnet services supported matrix</H2>
<p>The BACnet stack currently implements the following services listed in the
the table. We plan to add the rest of the services as we go.
With the services that are implemented, you could build a BACnet device
that meets the standardized profile for a BACnet Smart Sensor,
BACnet Smart Actuator, or a BACnet Application Specific Controller.</p></TR>
<TR>
<TD bgcolor="#CCF6F6" width="50%" valign="top"><b>BACnet Service</b></td>
<TD bgcolor="#CCF6F6" width="25%" align="center" valign="top"><b>Initiate</b></td>
<TD bgcolor="#CCF6F6" width="25%" align="center" valign="top"><b>Execute</b></td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Who Is</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">I Am</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Who Has</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">I Have</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Property</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Write Property</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Device Communication Control</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">ReinitializeDevice</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Atomic Read File</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Atomic Write File</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Time Synchronization</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">UTC Time Synchronization</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Subscribe COV</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed COV Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed COV Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Property Multiple</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Property Conditional</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Range</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Write Property Multiple</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Get Alarm Summary</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Get Event Information</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Get Enrollment Summary</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Acknowledge Alarm</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed Event Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed Event Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed Text Message</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed Text Message</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Add List Element</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Remove List Element</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Create Object</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Delete Object</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed Private Transfer</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed Private Transfer</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">VT Open</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">VT Data</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">VT Close</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
</TBODY>
</TABLE>
<h2>BACnet Objects</h2>
<p>The BACnet stack currently implements a Device Object, and
handles all of the ReadProperty inquiries for the required
Device Object properties. The stack handles Who-Is inquiries
with an I-Am, WhoHas with I-Have, and handles reject messages for
services not currently supported. There is built in handling for
DeviceCommunicationControl.</p>
<p>The example handlers interact with example objects, including
Analog Input, Analog Output, Analog Value, Binary Input,
Binary Output, Binary Value, Load Control, Life Safety Point,
and Multi-state Output objects.
The objects can be accessed using WriteProperty,
ReadProperty, or Who-Has services. Adding other BACnet objects
is only a matter of setting up ReadProperty, WriteProperty, or
I-Have handling for the required properties and any other
properties that you want to support.</p>
<p>File Objects are conditionally included in the demonstation
applications. The files can be access using WriteProperty,
ReadProperty, Who-Has, AtomicWriteFile, or AtomicReadFile services.</p>
<h2>Getting Involved</h2>
<p>If you want to help out on this project, join the <a href="http://lists.sourceforge.net/mailman/listinfo/bacnet-developers">developers mailing list</a>, introduce yourself, and tell us what you would like to do.
If you are trying to implement a BACnet device or service using this project,
you are welcome to join the <a href="http://lists.sourceforge.net/mailman/listinfo/bacnet-developers">developers mailing list</a> as well.</p>
<p>More details about the project can be found on
the <a href="http://sourceforge.net/projects/bacnet/">BACnet Source Forge Project Page</a></p>
<p>There is documentation that <a href="http://sourceforge.net/docman/display_doc.php?docid=33182&group_id=117598">describes the mechanisms in the BACnet Stack</a>.
I wrote up some <a href="http://sourceforge.net/docman/display_doc.php?docid=35583&group_id=117598">answers to some frequently asked questions</a>. Of course,
there are a handful of text files in the doc directory of the project.</p>
<p><a
href="http://sourceforge.net/project/showfiles.php?group_id=117598&package_id=140172">BACnet
and the example uses several different objects and services.</p>
<TABLE border="1" width="100%" cellpadding="1" cellspacing="0"
summary="BACnet services supported matrix">
<TBODY>
<TR><H2>BACnet services supported matrix</H2>
<p>The BACnet stack currently implements the following services listed in the
the table. We plan to add the rest of the services as we go.
With the services that are implemented, you could build a BACnet device
that meets the standardized profile for a BACnet Smart Sensor,
BACnet Smart Actuator, or a BACnet Application Specific Controller.</p></TR>
<TR>
<TD bgcolor="#CCF6F6" width="50%" valign="top"><b>BACnet Service</b></td>
<TD bgcolor="#CCF6F6" width="25%" align="center" valign="top"><b>Initiate</b></td>
<TD bgcolor="#CCF6F6" width="25%" align="center" valign="top"><b>Execute</b></td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Who Is</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">I Am</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Who Has</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">I Have</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Property</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Write Property</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Device Communication Control</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">ReinitializeDevice</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Atomic Read File</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Atomic Write File</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Time Synchronization</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">UTC Time Synchronization</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Subscribe COV</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed COV Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed COV Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">Yes</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Property Multiple</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Property Conditional</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Read Range</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Write Property Multiple</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Get Alarm Summary</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Get Event Information</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Get Enrollment Summary</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Acknowledge Alarm</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed Event Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed Event Notification</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed Text Message</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed Text Message</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Add List Element</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Remove List Element</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Create Object</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Delete Object</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Unconfirmed Private Transfer</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">Confirmed Private Transfer</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">VT Open</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">VT Data</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
<TR>
<TD bgcolor="#FFFFDD" width="50%" valign="top">VT Close</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
<TD bgcolor="#FFFFDD" width="25%" align="center" valign="top">-</td>
</TR>
</TBODY>
</TABLE>
<h2>BACnet Objects</h2>
<p>The BACnet stack currently implements a Device Object, and
handles all of the ReadProperty inquiries for the required
Device Object properties. The stack handles Who-Is inquiries
with an I-Am, WhoHas with I-Have, and handles reject messages for
services not currently supported. There is built in handling for
DeviceCommunicationControl.</p>
<p>The example handlers interact with example objects, including
Analog Input, Analog Output, Analog Value, Binary Input,
Binary Output, Binary Value, Load Control, Life Safety Point,
and Multi-state Output objects.
The objects can be accessed using WriteProperty,
ReadProperty, or Who-Has services. Adding other BACnet objects
is only a matter of setting up ReadProperty, WriteProperty, or
I-Have handling for the required properties and any other
properties that you want to support.</p>
<p>File Objects are conditionally included in the demonstation
applications. The files can be access using WriteProperty,
ReadProperty, Who-Has, AtomicWriteFile, or AtomicReadFile services.</p>
<h2>Getting Involved</h2>
<p>If you want to help out on this project, join the <a href="http://lists.sourceforge.net/mailman/listinfo/bacnet-developers">developers mailing list</a>, introduce yourself, and tell us what you would like to do.
If you are trying to implement a BACnet device or service using this project,
you are welcome to join the <a href="http://lists.sourceforge.net/mailman/listinfo/bacnet-developers">developers mailing list</a> as well.</p>
<p>More details about the project can be found on
the <a href="http://sourceforge.net/projects/bacnet/">BACnet Source Forge Project Page</a></p>
<p>There is documentation that <a href="http://sourceforge.net/docman/display_doc.php?docid=33182&group_id=117598">describes the mechanisms in the BACnet Stack</a>.
I wrote up some <a href="http://sourceforge.net/docman/display_doc.php?docid=35583&group_id=117598">answers to some frequently asked questions</a>. Of course,
there are a handful of text files in the doc directory of the project.</p>
<p><a
href="http://sourceforge.net/project/showfiles.php?group_id=117598&package_id=140172">BACnet
Stack released files download</a></p>
<p>You can get the latest BACnet protocol stack source code using
@@ -449,64 +449,64 @@
or<br />
<code>svn co https://bacnet.svn.sourceforge.net/svnroot/bacnet/tags/bacnet-stack-0-3-0/</code>
</blockquote>
<h2>BACnet Developer Resources</h2>
There are a number of resources that can help you develop a BACnet product or project.
<ul>
<li><a href="http://vts.sourceforge.net/">VTS</a> - visual test shell for
Win32, used for Visually testing a BACnet implementation. It also includes
a detailed network sniffer for BACnet messages, and the ability to send
any BACnet services. The source code is in the public domain. </li>
<li><a href="http://www.wireshark.org/">Wireshark</a> - an open source,
cross platform protocol analyzer with BACnet support. The detailed BACnet
support in began in version 0.10.11 released on May 4, 2005 when Wireshark
was known as Ethereal.</li>
<li><a href="http://www.ubuntu.com/">Ubuntu Linux</a> or
<a href="http://www.debian.org/">Debian Linux</a> - my
development platforms of choice.
Linux makes a great development platform
because all the necessary development tools are included.</li>
<li><a href="http://www.codeblocks.org/">Code::Blocks</a> - a free cross-platform
<h2>BACnet Developer Resources</h2>
There are a number of resources that can help you develop a BACnet product or project.
<ul>
<li><a href="http://vts.sourceforge.net/">VTS</a> - visual test shell for
Win32, used for Visually testing a BACnet implementation. It also includes
a detailed network sniffer for BACnet messages, and the ability to send
any BACnet services. The source code is in the public domain. </li>
<li><a href="http://www.wireshark.org/">Wireshark</a> - an open source,
cross platform protocol analyzer with BACnet support. The detailed BACnet
support in began in version 0.10.11 released on May 4, 2005 when Wireshark
was known as Ethereal.</li>
<li><a href="http://www.ubuntu.com/">Ubuntu Linux</a> or
<a href="http://www.debian.org/">Debian Linux</a> - my
development platforms of choice.
Linux makes a great development platform
because all the necessary development tools are included.</li>
<li><a href="http://www.codeblocks.org/">Code::Blocks</a> - a free cross-platform
open source C/C++ IDE. Includes the MinGW compiler for Win32.</li>
<li>Win32 development can use <a href="http://www.borland.com/bcppbuilder/freecompiler/">Borland C++</a> or
<li>Win32 development can use <a href="http://www.borland.com/bcppbuilder/freecompiler/">Borland C++</a> or
<a href="http://msdn.microsoft.com/visualc/vctoolkit2003/">Microsoft Visual C++</a>,
both of which are free (as in beer) command line compilers. Be sure to pick up the free
both of which are free (as in beer) command line compilers. Be sure to pick up the free
<a href="http://info.borland.com/devsupport/bcppbuilder/patches/#freecompiler55">patches (service packs) for the Borland C++ compiler</a>
(<a href="http://info.borland.com/devsupport/bcppbuilder/patches/bcc55/bcc55sp1.zip">SP1</a>,
<a href="http://info.borland.com/devsupport/bcppbuilder/patches/bcc55/bcc55sp2.exe">SP2</a>),
as well as the free turbo debugger.</li>
</ul>
<p><a href="http://www.bacnet.org/Developer/index.html">BACnet Developer Help</a></p>
<p><a href="http://www.bacnetassociation.org/DevRes.htm">BACnet International Developer Resources</a></p>
<h2>Products and Projects that use this BACnet Stack</h2>
<p>Did you develop a product using this BACnet stack? <a href="mailto:skarg@users.sourceforge.net">Let us know</a>, and you
can get a little recognition for your hard work!</p>
<p><a href="http://sensors.scinterface.com/">SCInterface&trade; = Sensor Control Interface</a> - middleware
platform for managing legacy and modern-day sensors through a centralized
interface</p>
<p><a href="http://sourceforge.net/projects/bacnet-sim/">BACnetSim</a> - a
portable implementation of the BACnet data communication protocol.
BACnetSim is meant for embedded devices and use MS/TP as the media
access layer. BACnetSim is a fork of bacnet-stack-0.0.1</p>
<hr>
<A href="http://sourceforge.net"> <IMG
src="http://sourceforge.net/sflogo.php?group_id=117598&amp;type=5"
width="210" height="62" border="0" alt="SourceForge.net Logo" /></A>
<p><font size="-2"><b>ASHRAE<sup>&reg;</sup></b> and
<b>BACnet<sup>&reg;</sup></b> are registered trademarks of the American
Society of Heating, Refrigerating and Air-Conditioning Engineers, Inc.,
1791 Tullie Circle NE, Atlanta, GA 30329.</font> </p>
<p>Website updated 2-Apr-2007 by <a href="mailto:skarg@users.sourceforge.net">Steve Karg</a></p>
</BODY>
</HTML>
as well as the free turbo debugger.</li>
</ul>
<p><a href="http://www.bacnet.org/Developer/index.html">BACnet Developer Help</a></p>
<p><a href="http://www.bacnetassociation.org/DevRes.htm">BACnet International Developer Resources</a></p>
<h2>Products and Projects that use this BACnet Stack</h2>
<p>Did you develop a product using this BACnet stack? <a href="mailto:skarg@users.sourceforge.net">Let us know</a>, and you
can get a little recognition for your hard work!</p>
<p><a href="http://sensors.scinterface.com/">SCInterface&trade; = Sensor Control Interface</a> - middleware
platform for managing legacy and modern-day sensors through a centralized
interface</p>
<p><a href="http://sourceforge.net/projects/bacnet-sim/">BACnetSim</a> - a
portable implementation of the BACnet data communication protocol.
BACnetSim is meant for embedded devices and use MS/TP as the media
access layer. BACnetSim is a fork of bacnet-stack-0.0.1</p>
<hr>
<A href="http://sourceforge.net"> <IMG
src="http://sourceforge.net/sflogo.php?group_id=117598&amp;type=5"
width="210" height="62" border="0" alt="SourceForge.net Logo" /></A>
<p><font size="-2"><b>ASHRAE<sup>&reg;</sup></b> and
<b>BACnet<sup>&reg;</sup></b> are registered trademarks of the American
Society of Heating, Refrigerating and Air-Conditioning Engineers, Inc.,
1791 Tullie Circle NE, Atlanta, GA 30329.</font> </p>
<p>Website updated 2-Apr-2007 by <a href="mailto:skarg@users.sourceforge.net">Steve Karg</a></p>
</BODY>
</HTML>
+200 -200
View File
@@ -1,200 +1,200 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Input Objects customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h"
/* Analog Input = Photocell */
#define MAX_ANALOG_INPUTS 2
static uint8_t Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_INPUTS)
return true;
return false;
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Count(void)
{
return MAX_ANALOG_INPUTS;
}
/* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance(unsigned index)
{
return index;
}
char *Analog_Input_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_ANALOG_INPUTS) {
sprintf(text_string, "AI-%lu", object_instance);
return text_string;
}
return NULL;
}
static float Analog_Input_Present_Value(uint32_t object_instance)
{
float value = 0.0;
if (object_instance < MAX_ANALOG_INPUTS)
value = Present_Value[object_instance];
return value;
}
/* return apdu length, or -1 on error */
/* assumption - object has already exists */
int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
(void) array_index;
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0],
OBJECT_ANALOG_INPUT);
break;
case PROP_PRESENT_VALUE:
apdu_len = encode_tagged_real(&apdu[0],
Analog_Input_Present_Value(object_instance));
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_UNITS:
apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
void testAnalogInput(Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_OUTPUT;
uint32_t decoded_instance = 0;
uint32_t instance = 123;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
/* FIXME: we should do a lot more testing here... */
len = Analog_Input_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len >= 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = decode_object_id(&apdu[len],
(int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_ANALOG_INPUT);
ct_test(pTest, decoded_instance == instance);
return;
}
#ifdef TEST_ANALOG_INPUT
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet Analog Input", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testAnalogInput);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_ANALOG_INPUT */
#endif /* TEST */
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Input Objects customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h"
/* Analog Input = Photocell */
#define MAX_ANALOG_INPUTS 2
static uint8_t Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_INPUTS)
return true;
return false;
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Count(void)
{
return MAX_ANALOG_INPUTS;
}
/* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance(unsigned index)
{
return index;
}
char *Analog_Input_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_ANALOG_INPUTS) {
sprintf(text_string, "AI-%lu", object_instance);
return text_string;
}
return NULL;
}
static float Analog_Input_Present_Value(uint32_t object_instance)
{
float value = 0.0;
if (object_instance < MAX_ANALOG_INPUTS)
value = Present_Value[object_instance];
return value;
}
/* return apdu length, or -1 on error */
/* assumption - object has already exists */
int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
(void) array_index;
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0],
OBJECT_ANALOG_INPUT);
break;
case PROP_PRESENT_VALUE:
apdu_len = encode_tagged_real(&apdu[0],
Analog_Input_Present_Value(object_instance));
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_UNITS:
apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
void testAnalogInput(Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_OUTPUT;
uint32_t decoded_instance = 0;
uint32_t instance = 123;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
/* FIXME: we should do a lot more testing here... */
len = Analog_Input_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len >= 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = decode_object_id(&apdu[len],
(int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_ANALOG_INPUT);
ct_test(pTest, decoded_instance == instance);
return;
}
#ifdef TEST_ANALOG_INPUT
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet Analog Input", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testAnalogInput);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_ANALOG_INPUT */
#endif /* TEST */
+8 -8
View File
@@ -186,16 +186,16 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
#if 0
#if 0
object_index = Analog_Value_Instance_To_Index(object_instance);
state = Analog_Value_Out_Of_Service[object_index];
state = Analog_Value_Out_Of_Service[object_index];
#endif
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_UNITS:
apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT);
break;
#if 0
#if 0
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
@@ -247,7 +247,7 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
real_value = ANALOG_RELINQUISH_DEFAULT;
apdu_len = encode_tagged_real(&apdu[0], real_value);
break;
#endif
#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
@@ -312,7 +312,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
#if 0
#if 0
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = ANALOG_LEVEL_NULL;
object_index =
@@ -332,13 +332,13 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
#endif
#endif
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
#if 0
#if 0
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
@@ -350,7 +350,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
#endif
#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
+231 -231
View File
@@ -1,232 +1,232 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Input Objects customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h"
#define MAX_BINARY_INPUTS 8
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
static void Binary_Input_Initialize(void)
{
static bool initialized = false;
unsigned i;
if (!initialized) {
initialized = true;
for (i = 0; i < MAX_BINARY_INPUTS; i++) {
Present_Value[i] = BINARY_INACTIVE;
}
}
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Input Objects customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h"
#define MAX_BINARY_INPUTS 8
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
static void Binary_Input_Initialize(void)
{
static bool initialized = false;
unsigned i;
if (!initialized) {
initialized = true;
for (i = 0; i < MAX_BINARY_INPUTS; i++) {
Present_Value[i] = BINARY_INACTIVE;
}
}
}
/* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_INPUTS)
return true;
return false;
}
/* we simply have 0-n object instances. */
unsigned Binary_Input_Count(void)
{
return MAX_BINARY_INPUTS;
}
/* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_INPUTS;
if (object_instance < MAX_BINARY_INPUTS)
index = object_instance;
return index;
}
static BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t
object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0;
Binary_Input_Initialize();
index = Binary_Input_Instance_To_Index(object_instance);
if (index < MAX_BINARY_INPUTS) {
value = Present_Value[index];
}
return value;
}
char *Binary_Input_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_BINARY_INPUTS) {
sprintf(text_string, "BI-%lu", object_instance);
return text_string;
}
return NULL;
}
/* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_POLARITY polarity = POLARITY_NORMAL;
BACNET_BINARY_PV value = BINARY_INACTIVE;
(void) array_index;
Binary_Input_Initialize();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_INPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* note: object name must be unique in our device */
characterstring_init_ansi(&char_string,
Binary_Input_Name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
break;
case PROP_PRESENT_VALUE:
value = Binary_Input_Present_Value(object_instance);
apdu_len = encode_tagged_enumerated(&apdu[0],value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_POLARITY:
apdu_len = encode_tagged_enumerated(&apdu[0], polarity);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
void testBinaryInput(Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_OUTPUT;
uint32_t decoded_instance = 0;
uint32_t instance = 123;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
/* FIXME: we should do a lot more testing here... */
len = Binary_Input_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len >= 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = decode_object_id(&apdu[len],
(int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_BINARY_INPUT);
ct_test(pTest, decoded_instance == instance);
return;
}
#ifdef TEST_BINARY_INPUT
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet Binary Input", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testBinaryInput);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
/* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_INPUTS)
return true;
return false;
}
/* we simply have 0-n object instances. */
unsigned Binary_Input_Count(void)
{
return MAX_BINARY_INPUTS;
}
/* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_INPUTS;
if (object_instance < MAX_BINARY_INPUTS)
index = object_instance;
return index;
}
static BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t
object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0;
Binary_Input_Initialize();
index = Binary_Input_Instance_To_Index(object_instance);
if (index < MAX_BINARY_INPUTS) {
value = Present_Value[index];
}
return value;
}
char *Binary_Input_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_BINARY_INPUTS) {
sprintf(text_string, "BI-%lu", object_instance);
return text_string;
}
return NULL;
}
/* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_POLARITY polarity = POLARITY_NORMAL;
BACNET_BINARY_PV value = BINARY_INACTIVE;
(void) array_index;
Binary_Input_Initialize();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_INPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* note: object name must be unique in our device */
characterstring_init_ansi(&char_string,
Binary_Input_Name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
break;
case PROP_PRESENT_VALUE:
value = Binary_Input_Present_Value(object_instance);
apdu_len = encode_tagged_enumerated(&apdu[0],value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_POLARITY:
apdu_len = encode_tagged_enumerated(&apdu[0], polarity);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
void testBinaryInput(Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_OUTPUT;
uint32_t decoded_instance = 0;
uint32_t instance = 123;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
/* FIXME: we should do a lot more testing here... */
len = Binary_Input_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len >= 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = decode_object_id(&apdu[len],
(int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_BINARY_INPUT);
ct_test(pTest, decoded_instance == instance);
return;
}
#ifdef TEST_BINARY_INPUT
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet Binary Input", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testBinaryInput);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
+320 -320
View File
@@ -1,338 +1,338 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Value Objects - customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_BINARY_VALUES 8
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Binary Value Objects - customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_BINARY_VALUES 8
static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
static void Binary_Value_Initialize(void)
{
static bool initialized = false;
unsigned i;
if (!initialized) {
initialized = true;
for (i = 0; i < MAX_BINARY_VALUES; i++) {
Present_Value[i] = BINARY_INACTIVE;
}
}
static void Binary_Value_Initialize(void)
{
static bool initialized = false;
unsigned i;
if (!initialized) {
initialized = true;
for (i = 0; i < MAX_BINARY_VALUES; i++) {
Present_Value[i] = BINARY_INACTIVE;
}
}
}
/* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_VALUES)
return true;
return false;
}
/* we simply have 0-n object instances. */
unsigned Binary_Value_Count(void)
{
return MAX_BINARY_VALUES;
}
/* we simply have 0-n object instances. */
uint32_t Binary_Value_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. */
unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_VALUES;
if (object_instance < MAX_BINARY_VALUES)
index = object_instance;
return index;
}
static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t
object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
Binary_Value_Initialize();
if (object_instance < MAX_BINARY_VALUES) {
value = Present_Value[object_instance];
}
return value;
}
/* note: the object name must be unique within this device */
char *Binary_Value_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_BINARY_VALUES) {
sprintf(text_string, "BV-%lu", object_instance);
return text_string;
}
return NULL;
}
/* return apdu len, or -1 on error */
int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
BACNET_POLARITY polarity = POLARITY_NORMAL;
unsigned object_index = 0;
unsigned i = 0;
bool state = false;
Binary_Value_Initialize();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_VALUE,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Value_Name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break;
case PROP_PRESENT_VALUE:
present_value = Binary_Value_Present_Value(object_instance);
apdu_len = encode_tagged_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_POLARITY:
/* FIXME: figure out the polarity */
apdu_len = encode_tagged_enumerated(&apdu[0], polarity);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
unsigned int priority = 0;
BACNET_BINARY_PV level = BINARY_NULL;
/* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance(uint32_t object_instance)
{
if (object_instance < MAX_BINARY_VALUES)
return true;
return false;
}
/* we simply have 0-n object instances. */
unsigned Binary_Value_Count(void)
{
return MAX_BINARY_VALUES;
}
/* we simply have 0-n object instances. */
uint32_t Binary_Value_Index_To_Instance(unsigned index)
{
return index;
}
/* we simply have 0-n object instances. */
unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
{
unsigned index = MAX_BINARY_VALUES;
if (object_instance < MAX_BINARY_VALUES)
index = object_instance;
return index;
}
static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t
object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
Binary_Value_Initialize();
if (object_instance < MAX_BINARY_VALUES) {
value = Present_Value[object_instance];
}
return value;
}
/* note: the object name must be unique within this device */
char *Binary_Value_Name(uint32_t object_instance)
{
static char text_string[16] = ""; /* okay for single thread */
if (object_instance < MAX_BINARY_VALUES) {
sprintf(text_string, "BV-%lu", object_instance);
return text_string;
}
return NULL;
}
/* return apdu len, or -1 on error */
int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
BACNET_POLARITY polarity = POLARITY_NORMAL;
unsigned object_index = 0;
unsigned i = 0;
bool state = false;
Binary_Value_Initialize();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_BINARY_VALUE,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Value_Name(object_instance));
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break;
case PROP_PRESENT_VALUE:
present_value = Binary_Value_Present_Value(object_instance);
apdu_len = encode_tagged_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_tagged_boolean(&apdu[0], false);
break;
case PROP_POLARITY:
/* FIXME: figure out the polarity */
apdu_len = encode_tagged_enumerated(&apdu[0], polarity);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
unsigned int priority = 0;
BACNET_BINARY_PV level = BINARY_NULL;
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
if (!Binary_Value_Valid_Instance(wp_data->object_instance)) {
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false;
}
/* decode the some of the request */
if (!Binary_Value_Valid_Instance(wp_data->object_instance)) {
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false;
}
/* decode the some of the request */
len = bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = value.type.Enumerated;
object_index =
Binary_Value_Instance_To_Index(wp_data->
object_instance);
priority--;
object_index =
Binary_Value_Instance_To_Index(wp_data->
object_instance);
priority--;
/* NOTE: this Binary value has no priority array */
Present_Value[object_index] = level;
Present_Value[object_index] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
#if 0
/* NOTE: this Binary Value has no priority array */
level = BINARY_NULL;
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
#else
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
#endif
#if 0
/* NOTE: this Binary Value has no priority array */
level = BINARY_NULL;
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
#else
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
#endif
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
#if 0
case PROP_OUT_OF_SERVICE:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
#if 0
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
Binary_Value_Out_Of_Service[object_index] = value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
void testBinary_Value(Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_VALUE;
uint32_t decoded_instance = 0;
uint32_t instance = 123;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
len = Binary_Value_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = decode_object_id(&apdu[len],
(int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE);
ct_test(pTest, decoded_instance == instance);
return;
}
#ifdef TEST_BINARY_VALUE
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet Binary_Value", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testBinary_Value);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_BINARY_VALUE */
#endif /* TEST */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
#endif
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
void testBinary_Value(Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
uint32_t len_value = 0;
uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_BINARY_VALUE;
uint32_t decoded_instance = 0;
uint32_t instance = 123;
BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code;
len = Binary_Value_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = decode_object_id(&apdu[len],
(int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE);
ct_test(pTest, decoded_instance == instance);
return;
}
#ifdef TEST_BINARY_VALUE
int main(void)
{
Test *pTest;
bool rc;
pTest = ct_create("BACnet Binary_Value", NULL);
/* individual tests */
rc = ct_addTestFunction(pTest, testBinary_Value);
assert(rc);
ct_setStream(pTest, stdout);
ct_run(pTest);
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif /* TEST_BINARY_VALUE */
#endif /* TEST */
+5 -5
View File
@@ -186,7 +186,7 @@ bool Device_Object_List_Identifier(unsigned array_index,
/* normalize the index since
we know it is not the previous objects */
/* array index starts at 1 */
object_index = array_index - 1;
object_index = array_index - 1;
/* 1 for the device object */
object_count = 1;
/* FIXME: add objects as needed */
@@ -538,10 +538,10 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
if (len <= 20) {
/* FIXME: set the name */
/* Display_Set_Name(
characterstring_value(&value.type.Character_String)); */
/* FIXME: All the object names in a device must be unique.
Disallow setting the Device Object Name to any objects in
the device. */
characterstring_value(&value.type.Character_String)); */
/* FIXME: All the object names in a device must be unique.
Disallow setting the Device Object Name to any objects in
the device. */
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
+72 -72
View File
@@ -98,78 +98,78 @@ void handler_read_property(uint8_t * service_request,
}
}
break;
case OBJECT_ANALOG_INPUT:
if (Analog_Input_Valid_Instance(data.object_instance)) {
len = Analog_Input_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_BINARY_INPUT:
if (Binary_Input_Valid_Instance(data.object_instance)) {
len = Binary_Input_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_BINARY_VALUE:
if (Binary_Value_Valid_Instance(data.object_instance)) {
len = Binary_Value_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_ANALOG_VALUE:
if (Analog_Value_Valid_Instance(data.object_instance)) {
len = Analog_Value_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_ANALOG_INPUT:
if (Analog_Input_Valid_Instance(data.object_instance)) {
len = Analog_Input_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_BINARY_INPUT:
if (Binary_Input_Valid_Instance(data.object_instance)) {
len = Binary_Input_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_BINARY_VALUE:
if (Binary_Value_Valid_Instance(data.object_instance)) {
len = Binary_Value_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
case OBJECT_ANALOG_VALUE:
if (Analog_Value_Valid_Instance(data.object_instance)) {
len = Analog_Value_Encode_Property_APDU(&Temp_Buf[0],
data.object_instance,
data.object_property,
data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */
len =
rp_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
error = false;
}
}
break;
default:
break;
}
+3 -3
View File
@@ -770,7 +770,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
mstp_port->DataLength);
break;
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
/*mstp_port->ReplyPostponedTimer = 0;
/*mstp_port->ReplyPostponedTimer = 0; */
/* indicate successful reception to the higher layers */
dlmstp_put_receive(mstp_port->SourceAddress,
(uint8_t *) & mstp_port->InputBuffer[0],
@@ -1217,12 +1217,12 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
mstp_port->ReceivedValidFrame = false;
mstp_port->RetryCount = 0;
mstp_port->SilenceTimer = 0;
mstp_port->SilenceTimer = 0;
/* mstp_port->ReplyPostponedTimer = 0; */
mstp_port->SoleMaster = false;
mstp_port->SourceAddress = 0;
mstp_port->TokenCount = 0;
#if 0
mstp_port->TokenCount = 0;
/* these are adjustable, so should already be set */
mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES;
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
#endif
+1 -1
View File
@@ -162,7 +162,7 @@ struct mstp_port_struct_t {
/* Machine when a Data Expecting Reply Answer activity is completed. */
/* note: we always send a reply postponed since a message other than
the reply may be in the transmit queue */
/* uint16_t ReplyPostponedTimer;
/* uint16_t ReplyPostponedTimer; */
/* Used to store the Source Address of a received frame. */
uint8_t SourceAddress;
+408 -408
View File
@@ -1,408 +1,408 @@
PICS 0
BACnet Protocol Implementation Conformance Statement
--
--
-- BACnet Stack Demo
-- bacnet.sourceforge.net
-- Author: Steve Karg
--
--
Vendor Name: "ASHRAE"
Product Name: "PIC18F6720 Device"
Product Model Number: "GNU Demo"
Product Description: "BACnet Demo"
BIBBs Supported:
{
-- The BIBBs may be any of:
-- DS-RP-A
DS-RP-B
-- DS-RPM-A DS-RPM-B
-- DS-RPC-A DS-RPC-B
-- DS-WP-A
DS-WP-B
-- DS-WPM-A DS-WPM-B
-- DS-COV-A DS-COV-B
-- DS-COVP-A DS-COVP-B
-- DS-COVU-A DS-COVU-B
-- AE-N-A AE-N-I-B AE-N-E-B
-- AE-ACK-A AE-ACK-B
-- AE-ASUM-A AE-ASUM-B
-- AE-ESUM-A AE-ESUM-B
-- AE-INFO-A AE-INFO-B
-- AE-LS-A AE-LS-B
-- SCHED-A SCHED-I-B SCHED-E-B
-- T-VMT-A T-VMT-I-B T-VMT-E-B
-- T-ATR-A T-ATR-B
-- DM-DDB-A
DM-DDB-B
-- DM-DOB-A
-- DM-DOB-B
-- DM-DCC-A
DM-DCC-B
-- DM-PT-A DM-PT-B
-- DM-TM-A DM-TM-B
-- DM-TS-A
-- DM-TS-B
-- DM-UTC-A
-- DM-UTC-B
-- DM-RD-A
DM-RD-B
-- DM-BR-A DM-BR-B
-- DM-R-A DM-R-B
-- DM-LM-A DM-LM-B
-- DM-OCD-A DM-OCD-B
-- DM-VT-A DM-VT-B
-- NM-CE-A NM-CE-B
-- NM-RC-A NM-RC-B
}
BACnet Standard Application Services Supported:
{
-- AcknowledgeAlarm Initiate Execute
-- ConfirmedCOVNotification Initiate Execute
-- UnconfirmedCOVNotification Initiate
-- ConfirmedEventNotification Initiate Execute
-- UnconfirmedEventNotification Initiate Execute
-- GetAlarmSummary Initiate Execute
-- GetEnrollmentSummary Initiate Execute
-- AtomicReadFile Initiate Execute
-- AtomicWriteFile Initiate Execute
-- AddListElement Initiate Execute
-- RemoveListElement Initiate Execute
-- CreateObject Initiate Execute
-- DeleteObject Initiate Execute
ReadProperty Execute
-- ReadpropertyConditional Initiate Execute
-- ReadPropertyMultiple Initiate Execute
-- SubscribeCOV Initiate Execute
WriteProperty Execute
-- WritePropertyMultiple Initiate Execute
DeviceCommunicationControl Execute
-- ConfirmedPrivateTransfer Initiate Execute
-- UnconfirmedPrivateTransfer Initiate Execute
-- TimeSynchronization Initiate Execute
-- Who-Has Execute
-- I-Have Initiate
Who-Is Execute
I-Am Initiate
-- VT-Open Initiate Execute
-- VT-Close Initiate Execute
-- VT-Data Initiate Execute
-- ConfirmedTextMessage Initiate Execute
-- UnconfirmedTextMessage Initiate Execute
ReinitializeDevice Execute
-- RequestKey Initiate Execute
-- Authenticate Initiate Execute
-- UTCTimeSynchronization Initiate Execute
-- ReadRange Initiate Execute
-- GetEventInformation Initiate Execute
-- LifeSafetyOperation Initiate Execute
-- SubscribeCOVProperty Initiate Execute
-- RequestKey Initiate Execute
-- Authenticate Initiate Execute
}
Standard Object-Types Supported:
{
Analog Input
-- Analog Output
Analog Value
-- Averaging Createable Deleteable
Binary Input
-- Binary Output
Binary Value
-- Calendar Createable Deleteable
-- Command Createable Deleteable
Device
-- Event Enrollment Createable Deleteable
-- File
-- Group Createable Deleteable
-- Loop Createable Deleteable
-- Multi-state Input Createable Deleteable
-- Multi-state Output
-- Multi-state Value Createable Deleteable
-- Notification Class Createable Deleteable
-- Program Createable Deleteable
-- Schedule Createable Deleteable
-- Life Safety Point
-- Life Safety Zone Createable Deleteable
-- Trend Log Createable Deleteable
-- Load Control
}
Data Link Layer Option:
{
-- ISO 8802-3, 10BASE5
-- ISO 8802-3, 10BASE2
-- ISO 8802-3, 10BASET
-- ISO 8802-3, Fiber
-- ARCNET, coax star
-- ARCNET, coax bus
-- ARCNET, twisted pair star
-- ARCNET, twisted pair bus
-- ARCNET, fiber star
MS/TP master. Baud rate(s): 9600, 19200, 38400, 76800
-- MS/TP slave. Baud rate(s): 9600
-- Point-To-Point. Modem, Baud rate(s): 14.4k
-- Point-To-Point. Modem, Autobaud range: 9600 to 28.8k
-- BACnet/IP, 'DIX' Ethernet
-- BACnet/IP, PPP
-- Other
}
Character Sets Supported:
{
ANSI X3.4
-- Other Character Sets not supported
-- IBM/Microsoft DBCS
-- JIS C 6226
-- ISO 10646 (ICS-4)
-- ISO 10646 (UCS2)
}
Special Functionality:
{
Maximum APDU size in octets: 50
-- Maximum APDU size in octets: 480
-- Segmented Requests Supported, window size: 1
-- Segmented Responses Supported, window size: 1
-- Router
}
List of Objects in test device:
{
{
object-identifier: (device,12345)
object-name: "PIC18F6720 Device"
object-type: device
system-status: operational
vendor-name: "ASHRAE"
vendor-identifier: 0
model-name: "GNU Demo"
firmware-revision: "1.00"
application-software-version: "1.00"
location: "USA"
description: "BACnet Demo"
protocol-version: 1
protocol-conformance-class: 1
protocol-services-supported: (T,F,F,F,F,F,F,F,F,F,F,F,T,F,F,T,F,T,F,F,T,F,F,
F,F,F,F,F,F,F,F,F,F,F,T,F,F,F,F,F)
protocol-object-types-supported: (T,F,T,T,F,T,F,F,T,F,F,F,F,F,F,F,F,F,F,F,F,
F,F,F,F,F,F,F,F,F,F,F)
max-apdu-length-accepted: 50
segmentation-supported: no-segmentation
local-time: ?
local-date: ?
utc-offset: ?
daylight-savings-status: ?
database-revision: ?
apdu-timeout: 60000
number-of-apdu-retries: 0
max-master: 127
max-info-frames: 1
device-address-binding: ?
object-list: {
(device,12345),(binary-value,0),(binary-value,1),
(binary-value,2),(binary-value,3),(binary-value,4),
(binary-value,5),(binary-value,6),(binary-value,7),
(analog-value,0),(analog-value,1),(analog-value,2),
(analog-value,3),(analog-input,0),(analog-input,1),
(binary-input,0),(binary-input,1),(binary-input,2),
(binary-input,3)
}
},
{
object-identifier: (binary-value,0)
object-name: "BV-0"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-0"
},
{
object-identifier: (binary-value,1)
object-name: "BV-1"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-1"
},
{
object-identifier: (binary-value,2)
object-name: "BV-2"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-2"
},
{
object-identifier: (binary-value,3)
object-name: "BV-3"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-3"
},
{
object-identifier: (binary-value,4)
object-name: "BV-4"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-4"
},
{
object-identifier: (binary-value,5)
object-name: "BV-5"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-5"
},
{
object-identifier: (binary-value,6)
object-name: "BV-6"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-6"
},
{
object-identifier: (binary-value,7)
object-name: "BV-7"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-7"
},
{
object-identifier: (analog-value,0)
object-name: "AV-0"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-0"
},
{
object-identifier: (analog-value,1)
object-name: "AV-1"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-1"
},
{
object-identifier: (analog-value,2)
object-name: "AV-2"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-2"
},
{
object-identifier: (analog-value,3)
object-name: "AV-3"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-3"
},
{
object-identifier: (analog-input,0)
object-name: "AI-0"
object-type: analog-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AI-0"
},
{
object-identifier: (analog-input,1)
object-name: "AI-1"
object-type: analog-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AI-1"
},
{
object-identifier: (binary-input,0)
object-name: "BI-0"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-0"
},
{
object-identifier: (binary-input,1)
object-name: "BI-1"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-1"
},
{
object-identifier: (binary-input,2)
object-name: "BI-2"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-2"
},
{
object-identifier: (binary-input,3)
object-name: "BI-3"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-3"
}
}
End of BACnet Protocol Implementation Conformance Statement
PICS 0
BACnet Protocol Implementation Conformance Statement
--
--
-- BACnet Stack Demo
-- bacnet.sourceforge.net
-- Author: Steve Karg
--
--
Vendor Name: "ASHRAE"
Product Name: "PIC18F6720 Device"
Product Model Number: "GNU Demo"
Product Description: "BACnet Demo"
BIBBs Supported:
{
-- The BIBBs may be any of:
-- DS-RP-A
DS-RP-B
-- DS-RPM-A DS-RPM-B
-- DS-RPC-A DS-RPC-B
-- DS-WP-A
DS-WP-B
-- DS-WPM-A DS-WPM-B
-- DS-COV-A DS-COV-B
-- DS-COVP-A DS-COVP-B
-- DS-COVU-A DS-COVU-B
-- AE-N-A AE-N-I-B AE-N-E-B
-- AE-ACK-A AE-ACK-B
-- AE-ASUM-A AE-ASUM-B
-- AE-ESUM-A AE-ESUM-B
-- AE-INFO-A AE-INFO-B
-- AE-LS-A AE-LS-B
-- SCHED-A SCHED-I-B SCHED-E-B
-- T-VMT-A T-VMT-I-B T-VMT-E-B
-- T-ATR-A T-ATR-B
-- DM-DDB-A
DM-DDB-B
-- DM-DOB-A
-- DM-DOB-B
-- DM-DCC-A
DM-DCC-B
-- DM-PT-A DM-PT-B
-- DM-TM-A DM-TM-B
-- DM-TS-A
-- DM-TS-B
-- DM-UTC-A
-- DM-UTC-B
-- DM-RD-A
DM-RD-B
-- DM-BR-A DM-BR-B
-- DM-R-A DM-R-B
-- DM-LM-A DM-LM-B
-- DM-OCD-A DM-OCD-B
-- DM-VT-A DM-VT-B
-- NM-CE-A NM-CE-B
-- NM-RC-A NM-RC-B
}
BACnet Standard Application Services Supported:
{
-- AcknowledgeAlarm Initiate Execute
-- ConfirmedCOVNotification Initiate Execute
-- UnconfirmedCOVNotification Initiate
-- ConfirmedEventNotification Initiate Execute
-- UnconfirmedEventNotification Initiate Execute
-- GetAlarmSummary Initiate Execute
-- GetEnrollmentSummary Initiate Execute
-- AtomicReadFile Initiate Execute
-- AtomicWriteFile Initiate Execute
-- AddListElement Initiate Execute
-- RemoveListElement Initiate Execute
-- CreateObject Initiate Execute
-- DeleteObject Initiate Execute
ReadProperty Execute
-- ReadpropertyConditional Initiate Execute
-- ReadPropertyMultiple Initiate Execute
-- SubscribeCOV Initiate Execute
WriteProperty Execute
-- WritePropertyMultiple Initiate Execute
DeviceCommunicationControl Execute
-- ConfirmedPrivateTransfer Initiate Execute
-- UnconfirmedPrivateTransfer Initiate Execute
-- TimeSynchronization Initiate Execute
-- Who-Has Execute
-- I-Have Initiate
Who-Is Execute
I-Am Initiate
-- VT-Open Initiate Execute
-- VT-Close Initiate Execute
-- VT-Data Initiate Execute
-- ConfirmedTextMessage Initiate Execute
-- UnconfirmedTextMessage Initiate Execute
ReinitializeDevice Execute
-- RequestKey Initiate Execute
-- Authenticate Initiate Execute
-- UTCTimeSynchronization Initiate Execute
-- ReadRange Initiate Execute
-- GetEventInformation Initiate Execute
-- LifeSafetyOperation Initiate Execute
-- SubscribeCOVProperty Initiate Execute
-- RequestKey Initiate Execute
-- Authenticate Initiate Execute
}
Standard Object-Types Supported:
{
Analog Input
-- Analog Output
Analog Value
-- Averaging Createable Deleteable
Binary Input
-- Binary Output
Binary Value
-- Calendar Createable Deleteable
-- Command Createable Deleteable
Device
-- Event Enrollment Createable Deleteable
-- File
-- Group Createable Deleteable
-- Loop Createable Deleteable
-- Multi-state Input Createable Deleteable
-- Multi-state Output
-- Multi-state Value Createable Deleteable
-- Notification Class Createable Deleteable
-- Program Createable Deleteable
-- Schedule Createable Deleteable
-- Life Safety Point
-- Life Safety Zone Createable Deleteable
-- Trend Log Createable Deleteable
-- Load Control
}
Data Link Layer Option:
{
-- ISO 8802-3, 10BASE5
-- ISO 8802-3, 10BASE2
-- ISO 8802-3, 10BASET
-- ISO 8802-3, Fiber
-- ARCNET, coax star
-- ARCNET, coax bus
-- ARCNET, twisted pair star
-- ARCNET, twisted pair bus
-- ARCNET, fiber star
MS/TP master. Baud rate(s): 9600, 19200, 38400, 76800
-- MS/TP slave. Baud rate(s): 9600
-- Point-To-Point. Modem, Baud rate(s): 14.4k
-- Point-To-Point. Modem, Autobaud range: 9600 to 28.8k
-- BACnet/IP, 'DIX' Ethernet
-- BACnet/IP, PPP
-- Other
}
Character Sets Supported:
{
ANSI X3.4
-- Other Character Sets not supported
-- IBM/Microsoft DBCS
-- JIS C 6226
-- ISO 10646 (ICS-4)
-- ISO 10646 (UCS2)
}
Special Functionality:
{
Maximum APDU size in octets: 50
-- Maximum APDU size in octets: 480
-- Segmented Requests Supported, window size: 1
-- Segmented Responses Supported, window size: 1
-- Router
}
List of Objects in test device:
{
{
object-identifier: (device,12345)
object-name: "PIC18F6720 Device"
object-type: device
system-status: operational
vendor-name: "ASHRAE"
vendor-identifier: 0
model-name: "GNU Demo"
firmware-revision: "1.00"
application-software-version: "1.00"
location: "USA"
description: "BACnet Demo"
protocol-version: 1
protocol-conformance-class: 1
protocol-services-supported: (T,F,F,F,F,F,F,F,F,F,F,F,T,F,F,T,F,T,F,F,T,F,F,
F,F,F,F,F,F,F,F,F,F,F,T,F,F,F,F,F)
protocol-object-types-supported: (T,F,T,T,F,T,F,F,T,F,F,F,F,F,F,F,F,F,F,F,F,
F,F,F,F,F,F,F,F,F,F,F)
max-apdu-length-accepted: 50
segmentation-supported: no-segmentation
local-time: ?
local-date: ?
utc-offset: ?
daylight-savings-status: ?
database-revision: ?
apdu-timeout: 60000
number-of-apdu-retries: 0
max-master: 127
max-info-frames: 1
device-address-binding: ?
object-list: {
(device,12345),(binary-value,0),(binary-value,1),
(binary-value,2),(binary-value,3),(binary-value,4),
(binary-value,5),(binary-value,6),(binary-value,7),
(analog-value,0),(analog-value,1),(analog-value,2),
(analog-value,3),(analog-input,0),(analog-input,1),
(binary-input,0),(binary-input,1),(binary-input,2),
(binary-input,3)
}
},
{
object-identifier: (binary-value,0)
object-name: "BV-0"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-0"
},
{
object-identifier: (binary-value,1)
object-name: "BV-1"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-1"
},
{
object-identifier: (binary-value,2)
object-name: "BV-2"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-2"
},
{
object-identifier: (binary-value,3)
object-name: "BV-3"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-3"
},
{
object-identifier: (binary-value,4)
object-name: "BV-4"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-4"
},
{
object-identifier: (binary-value,5)
object-name: "BV-5"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-5"
},
{
object-identifier: (binary-value,6)
object-name: "BV-6"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-6"
},
{
object-identifier: (binary-value,7)
object-name: "BV-7"
object-type: binary-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
description: "BV-7"
},
{
object-identifier: (analog-value,0)
object-name: "AV-0"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-0"
},
{
object-identifier: (analog-value,1)
object-name: "AV-1"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-1"
},
{
object-identifier: (analog-value,2)
object-name: "AV-2"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-2"
},
{
object-identifier: (analog-value,3)
object-name: "AV-3"
object-type: analog-value
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AV-3"
},
{
object-identifier: (analog-input,0)
object-name: "AI-0"
object-type: analog-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AI-0"
},
{
object-identifier: (analog-input,1)
object-name: "AI-1"
object-type: analog-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
units: percent
description: "AI-1"
},
{
object-identifier: (binary-input,0)
object-name: "BI-0"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-0"
},
{
object-identifier: (binary-input,1)
object-name: "BI-1"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-1"
},
{
object-identifier: (binary-input,2)
object-name: "BI-2"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-2"
},
{
object-identifier: (binary-input,3)
object-name: "BI-3"
object-type: binary-input
present-value: ?
status-flags: (F,F,F,F)
event-state: normal
out-of-service: F
polarity: normal
description: "BI-3"
}
}
End of BACnet Protocol Implementation Conformance Statement
+44 -44
View File
@@ -1,44 +1,44 @@
BACnet Stack - SourceForge.net
Build for MPLAB IDE
These are some settings that are important when building
the BACnet Stack using MPLAB IDE and MCC18 Compiler,
1. Add the files to the project that you need:
abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c,
bacstr.c, crc.c, datetime.c, dcc.c, iam.c,
npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c
From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c
From demo/object/: device.c or dev_tiny.c
objects as needed: ai.c, ao.c, etc.
From demo/handler/: txbuf.c, h_dcc.c, h_rd.c, h_rp.c or h_rp_tiny.c
Additional handlers as needed: h_wp.c
2. Project->Options->Project
General Tab: Include Path:
C:\code\bacnet-stack\;C:\code\bacnet-stack\demo\handler\;C:\code\bacnet-stack\demo\object\;C:\code\bacnet-stack\ports\pic18f6720\
MPLAB C18 Tab: Memory Model:
Code: Large Code Model
Data: Large Data Model
Stack: Multi-bank Model
MPLAB C18 Tab: General: Macro Definitions:
PRINT_ENABLED=0
BACDL_MSTP=1
TSM_ENABLED=0
BIG_ENDIAN=0
3. The linker script must reserve some extra stack space.
//DATABANK NAME=gpr12 START=0xC00 END=0xCFF
//DATABANK NAME=gpr13 START=0xD00 END=0xDFF
DATABANK NAME=stackreg START=0xC00 END=0xDFF PROTECTED
//STACK SIZE=0x100 RAM=gpr13
STACK SIZE=0x200 RAM=stackreg
BACnet Stack - SourceForge.net
Build for MPLAB IDE
These are some settings that are important when building
the BACnet Stack using MPLAB IDE and MCC18 Compiler,
1. Add the files to the project that you need:
abort.c, apdu.c, bacapp.c, bacdcode.c, bacerror.c,
bacstr.c, crc.c, datetime.c, dcc.c, iam.c,
npdu.c, rd.c, reject.c, rp.c, whois.c, wp.c
From ports/picxx: isr.c, main.c, rs485.c, mstp.c, dlmstp.c
From demo/object/: device.c or dev_tiny.c
objects as needed: ai.c, ao.c, etc.
From demo/handler/: txbuf.c, h_dcc.c, h_rd.c, h_rp.c or h_rp_tiny.c
Additional handlers as needed: h_wp.c
2. Project->Options->Project
General Tab: Include Path:
C:\code\bacnet-stack\;C:\code\bacnet-stack\demo\handler\;C:\code\bacnet-stack\demo\object\;C:\code\bacnet-stack\ports\pic18f6720\
MPLAB C18 Tab: Memory Model:
Code: Large Code Model
Data: Large Data Model
Stack: Multi-bank Model
MPLAB C18 Tab: General: Macro Definitions:
PRINT_ENABLED=0
BACDL_MSTP=1
TSM_ENABLED=0
BIG_ENDIAN=0
3. The linker script must reserve some extra stack space.
//DATABANK NAME=gpr12 START=0xC00 END=0xCFF
//DATABANK NAME=gpr13 START=0xD00 END=0xDFF
DATABANK NAME=stackreg START=0xC00 END=0xDFF PROTECTED
//STACK SIZE=0x100 RAM=gpr13
STACK SIZE=0x200 RAM=stackreg
+1 -1
View File
@@ -43,7 +43,7 @@ static uint8_t PDU_Buffer[MAX_MPDU];
static volatile struct mstp_port_struct_t MSTP_Port;
void dlmstp_init(char *ifname)
{
{
(void)ifname;
/* initialize buffer */
Receive_Buffer.ready = false;
+151 -151
View File
@@ -1,151 +1,151 @@
#
# 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;TSM_ENABLED=1;BIG_ENDIAN=0
SRCS = main.c bip-init.c \
..\..\bip.c \
..\..\demo\handler\h_iam.c \
..\..\demo\handler\h_whois.c \
..\..\demo\handler\h_wp.c \
..\..\demo\handler\h_rp.c \
..\..\demo\handler\h_rp_a.c \
..\..\demo\handler\noserv.c \
..\..\demo\handler\txbuf.c \
..\..\demo\handler\s_rp.c \
..\..\demo\handler\s_whois.c \
..\..\bacdcode.c \
..\..\bacapp.c \
..\..\bacstr.c \
..\..\bactext.c \
..\..\indtext.c \
..\..\bigend.c \
..\..\whois.c \
..\..\iam.c \
..\..\dcc.c \
..\..\rp.c \
..\..\wp.c \
..\..\arf.c \
..\..\awf.c \
..\..\demo\object\bacfile.c \
..\..\demo\object\device.c \
..\..\demo\object\ai.c \
..\..\demo\object\ao.c \
..\..\demo\object\av.c \
..\..\demo\object\bi.c \
..\..\demo\object\bo.c \
..\..\demo\object\bv.c \
..\..\demo\object\lsp.c \
..\..\demo\object\mso.c \
..\..\datalink.c \
..\..\tsm.c \
..\..\address.c \
..\..\abort.c \
..\..\reject.c \
..\..\bacerror.c \
..\..\apdu.c \
..\..\npdu.c
OBJS = $(SRCS:.c=.obj)
# Compiler definitions
#
BCC_CFG = bcc32.cfg
CC = $(BORLAND_DIR)\bin\bcc32 +$(BCC_CFG)
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
TLIB = $(BORLAND_DIR)\bin\tlib
#
# Include directories
#
CC_DIR = $(BORLAND_DIR)\BIN
INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\handler\;..\..\demo\object\;.
CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES)
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib
#
# Main target
#
# This should be the first one in the makefile
all : $(BCC_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$(C_LIB_DIR) -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 ..\..\demo\handler\*.obj
del ..\..\demo\object\*.obj
del $(PRODUCT_EXE)
del *.map
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) -o$@ $<
# Compiler configuration file
$(BCC_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
#
# 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;TSM_ENABLED=1;BIG_ENDIAN=0
SRCS = main.c bip-init.c \
..\..\bip.c \
..\..\demo\handler\h_iam.c \
..\..\demo\handler\h_whois.c \
..\..\demo\handler\h_wp.c \
..\..\demo\handler\h_rp.c \
..\..\demo\handler\h_rp_a.c \
..\..\demo\handler\noserv.c \
..\..\demo\handler\txbuf.c \
..\..\demo\handler\s_rp.c \
..\..\demo\handler\s_whois.c \
..\..\bacdcode.c \
..\..\bacapp.c \
..\..\bacstr.c \
..\..\bactext.c \
..\..\indtext.c \
..\..\bigend.c \
..\..\whois.c \
..\..\iam.c \
..\..\dcc.c \
..\..\rp.c \
..\..\wp.c \
..\..\arf.c \
..\..\awf.c \
..\..\demo\object\bacfile.c \
..\..\demo\object\device.c \
..\..\demo\object\ai.c \
..\..\demo\object\ao.c \
..\..\demo\object\av.c \
..\..\demo\object\bi.c \
..\..\demo\object\bo.c \
..\..\demo\object\bv.c \
..\..\demo\object\lsp.c \
..\..\demo\object\mso.c \
..\..\datalink.c \
..\..\tsm.c \
..\..\address.c \
..\..\abort.c \
..\..\reject.c \
..\..\bacerror.c \
..\..\apdu.c \
..\..\npdu.c
OBJS = $(SRCS:.c=.obj)
# Compiler definitions
#
BCC_CFG = bcc32.cfg
CC = $(BORLAND_DIR)\bin\bcc32 +$(BCC_CFG)
#LINK = $(BORLAND_DIR)\bin\tlink32
LINK = $(BORLAND_DIR)\bin\ilink32
TLIB = $(BORLAND_DIR)\bin\tlib
#
# Include directories
#
CC_DIR = $(BORLAND_DIR)\BIN
INCL_DIRS = -I$(BORLAND_DIR)\include;..\..\;..\..\demo\handler\;..\..\demo\object\;.
CFLAGS = $(INCL_DIRS) $(CS_FLAGS) $(DEFINES)
# Libraries
#
C_LIB_DIR = $(BORLAND_DIR)\lib
LIBS = $(C_LIB_DIR)\IMPORT32.lib \
$(C_LIB_DIR)\CW32MT.lib
#
# Main target
#
# This should be the first one in the makefile
all : $(BCC_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$(C_LIB_DIR) -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 ..\..\demo\handler\*.obj
del ..\..\demo\object\*.obj
del $(PRODUCT_EXE)
del *.map
del $(BCC_CFG)
#
# Generic rules
#
.SUFFIXES: .cpp .c .sbr .obj
#
# cc generic rule
#
.c.obj:
$(CC) -o$@ $<
# Compiler configuration file
$(BCC_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
+232 -232
View File
@@ -1,232 +1,232 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: bacnet - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP632.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /I "..\..\.." /I ".." /I "..\..\..\demo\object\\" /I "..\..\..\demo\handler\\" /D "_DEBUG" /D BACDL_BIP=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D TSM_ENABLED=1 /D PRINT_ENABLED=1 /D BIG_ENDIAN=0 /D USE_INADDR=0 /FR"Debug/" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\code\bacnet-stack\abort.c"
"C:\code\bacnet-stack\address.c"
"C:\code\bacnet-stack\demo\object\ai.c"
"C:\code\bacnet-stack\demo\object\ao.c"
"C:\code\bacnet-stack\apdu.c"
"C:\code\bacnet-stack\arf.c"
"C:\code\bacnet-stack\demo\object\av.c"
"C:\code\bacnet-stack\bacapp.c"
"C:\code\bacnet-stack\bacdcode.c"
"C:\code\bacnet-stack\bacerror.c"
"C:\code\bacnet-stack\demo\object\bacfile.c"
"C:\code\bacnet-stack\bacstr.c"
"C:\code\bacnet-stack\bactext.c"
"C:\code\bacnet-stack\demo\object\bi.c"
"C:\code\bacnet-stack\bigend.c"
"C:\code\bacnet-stack\ports\win32\bip-init.c"
"C:\code\bacnet-stack\bip.c"
"C:\code\bacnet-stack\demo\object\bo.c"
"C:\code\bacnet-stack\demo\object\bv.c"
"C:\code\bacnet-stack\crc.c"
"C:\code\bacnet-stack\datetime.c"
"C:\code\bacnet-stack\dcc.c"
"C:\code\bacnet-stack\demo\object\device.c"
"C:\code\bacnet-stack\demo\handler\h_arf.c"
"C:\code\bacnet-stack\demo\handler\h_arf_a.c"
"C:\code\bacnet-stack\demo\handler\h_iam.c"
"C:\code\bacnet-stack\demo\handler\h_rp.c"
"C:\code\bacnet-stack\demo\handler\h_rp_a.c"
"C:\code\bacnet-stack\demo\handler\h_whois.c"
"C:\code\bacnet-stack\demo\handler\h_wp.c"
"C:\code\bacnet-stack\iam.c"
"C:\code\bacnet-stack\indtext.c"
"C:\code\bacnet-stack\demo\object\lc.c"
"C:\code\bacnet-stack\demo\object\lsp.c"
"C:\code\bacnet-stack\ports\win32\main.c"
"C:\code\bacnet-stack\demo\object\mso.c"
"C:\code\bacnet-stack\demo\handler\noserv.c"
"C:\code\bacnet-stack\npdu.c"
"C:\code\bacnet-stack\reject.c"
"C:\code\bacnet-stack\ringbuf.c"
"C:\code\bacnet-stack\rp.c"
"C:\code\bacnet-stack\demo\handler\s_rp.c"
"C:\code\bacnet-stack\demo\handler\s_whois.c"
"C:\code\bacnet-stack\demo\handler\s_wp.c"
"C:\code\bacnet-stack\tsm.c"
"C:\code\bacnet-stack\demo\handler\txbuf.c"
"C:\code\bacnet-stack\whois.c"
"C:\code\bacnet-stack\wp.c"
]
Creating command line "cl.exe @C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP632.tmp"
Creating temporary file "C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP633.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/bacnet.pdb" /debug /machine:I386 /out:"Debug/bacnet.exe" /pdbtype:sept
".\Debug\abort.obj"
".\Debug\address.obj"
".\Debug\ai.obj"
".\Debug\ao.obj"
".\Debug\apdu.obj"
".\Debug\arf.obj"
".\Debug\av.obj"
".\Debug\bacapp.obj"
".\Debug\bacdcode.obj"
".\Debug\bacerror.obj"
".\Debug\bacfile.obj"
".\Debug\bacstr.obj"
".\Debug\bactext.obj"
".\Debug\bi.obj"
".\Debug\bigend.obj"
".\Debug\bip-init.obj"
".\Debug\bip.obj"
".\Debug\bo.obj"
".\Debug\bv.obj"
".\Debug\crc.obj"
".\Debug\datetime.obj"
".\Debug\dcc.obj"
".\Debug\device.obj"
".\Debug\h_arf.obj"
".\Debug\h_arf_a.obj"
".\Debug\h_iam.obj"
".\Debug\h_rp.obj"
".\Debug\h_rp_a.obj"
".\Debug\h_whois.obj"
".\Debug\h_wp.obj"
".\Debug\iam.obj"
".\Debug\indtext.obj"
".\Debug\lc.obj"
".\Debug\lsp.obj"
".\Debug\main.obj"
".\Debug\mso.obj"
".\Debug\noserv.obj"
".\Debug\npdu.obj"
".\Debug\reject.obj"
".\Debug\ringbuf.obj"
".\Debug\rp.obj"
".\Debug\s_rp.obj"
".\Debug\s_whois.obj"
".\Debug\s_wp.obj"
".\Debug\tsm.obj"
".\Debug\txbuf.obj"
".\Debug\whois.obj"
".\Debug\wp.obj"
]
Creating command line "link.exe @C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP633.tmp"
<h3>Output Window</h3>
Compiling...
abort.c
address.c
ai.c
ao.c
apdu.c
arf.c
av.c
bacapp.c
bacdcode.c
bacerror.c
bacfile.c
bacstr.c
bactext.c
bi.c
bigend.c
bip-init.c
bip.c
bo.c
bv.c
crc.c
Generating Code...
Compiling...
datetime.c
dcc.c
device.c
h_arf.c
h_arf_a.c
h_iam.c
h_rp.c
h_rp_a.c
h_whois.c
h_wp.c
iam.c
indtext.c
lc.c
lsp.c
main.c
mso.c
noserv.c
npdu.c
reject.c
ringbuf.c
Generating Code...
Compiling...
rp.c
s_rp.c
s_whois.c
s_wp.c
tsm.c
txbuf.c
whois.c
wp.c
Generating Code...
Linking...
Creating temporary file "C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP635.tmp" with contents
[
/nologo /o"Debug/bacnet.bsc"
".\Debug\abort.sbr"
".\Debug\address.sbr"
".\Debug\ai.sbr"
".\Debug\ao.sbr"
".\Debug\apdu.sbr"
".\Debug\arf.sbr"
".\Debug\av.sbr"
".\Debug\bacapp.sbr"
".\Debug\bacdcode.sbr"
".\Debug\bacerror.sbr"
".\Debug\bacfile.sbr"
".\Debug\bacstr.sbr"
".\Debug\bactext.sbr"
".\Debug\bi.sbr"
".\Debug\bigend.sbr"
".\Debug\bip-init.sbr"
".\Debug\bip.sbr"
".\Debug\bo.sbr"
".\Debug\bv.sbr"
".\Debug\crc.sbr"
".\Debug\datetime.sbr"
".\Debug\dcc.sbr"
".\Debug\device.sbr"
".\Debug\h_arf.sbr"
".\Debug\h_arf_a.sbr"
".\Debug\h_iam.sbr"
".\Debug\h_rp.sbr"
".\Debug\h_rp_a.sbr"
".\Debug\h_whois.sbr"
".\Debug\h_wp.sbr"
".\Debug\iam.sbr"
".\Debug\indtext.sbr"
".\Debug\lc.sbr"
".\Debug\lsp.sbr"
".\Debug\main.sbr"
".\Debug\mso.sbr"
".\Debug\noserv.sbr"
".\Debug\npdu.sbr"
".\Debug\reject.sbr"
".\Debug\ringbuf.sbr"
".\Debug\rp.sbr"
".\Debug\s_rp.sbr"
".\Debug\s_whois.sbr"
".\Debug\s_wp.sbr"
".\Debug\tsm.sbr"
".\Debug\txbuf.sbr"
".\Debug\whois.sbr"
".\Debug\wp.sbr"]
Creating command line "bscmake.exe @C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP635.tmp"
Creating browse info file...
<h3>Output Window</h3>
<h3>Results</h3>
bacnet.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: bacnet - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP632.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /I "..\..\.." /I ".." /I "..\..\..\demo\object\\" /I "..\..\..\demo\handler\\" /D "_DEBUG" /D BACDL_BIP=1 /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D TSM_ENABLED=1 /D PRINT_ENABLED=1 /D BIG_ENDIAN=0 /D USE_INADDR=0 /FR"Debug/" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\code\bacnet-stack\abort.c"
"C:\code\bacnet-stack\address.c"
"C:\code\bacnet-stack\demo\object\ai.c"
"C:\code\bacnet-stack\demo\object\ao.c"
"C:\code\bacnet-stack\apdu.c"
"C:\code\bacnet-stack\arf.c"
"C:\code\bacnet-stack\demo\object\av.c"
"C:\code\bacnet-stack\bacapp.c"
"C:\code\bacnet-stack\bacdcode.c"
"C:\code\bacnet-stack\bacerror.c"
"C:\code\bacnet-stack\demo\object\bacfile.c"
"C:\code\bacnet-stack\bacstr.c"
"C:\code\bacnet-stack\bactext.c"
"C:\code\bacnet-stack\demo\object\bi.c"
"C:\code\bacnet-stack\bigend.c"
"C:\code\bacnet-stack\ports\win32\bip-init.c"
"C:\code\bacnet-stack\bip.c"
"C:\code\bacnet-stack\demo\object\bo.c"
"C:\code\bacnet-stack\demo\object\bv.c"
"C:\code\bacnet-stack\crc.c"
"C:\code\bacnet-stack\datetime.c"
"C:\code\bacnet-stack\dcc.c"
"C:\code\bacnet-stack\demo\object\device.c"
"C:\code\bacnet-stack\demo\handler\h_arf.c"
"C:\code\bacnet-stack\demo\handler\h_arf_a.c"
"C:\code\bacnet-stack\demo\handler\h_iam.c"
"C:\code\bacnet-stack\demo\handler\h_rp.c"
"C:\code\bacnet-stack\demo\handler\h_rp_a.c"
"C:\code\bacnet-stack\demo\handler\h_whois.c"
"C:\code\bacnet-stack\demo\handler\h_wp.c"
"C:\code\bacnet-stack\iam.c"
"C:\code\bacnet-stack\indtext.c"
"C:\code\bacnet-stack\demo\object\lc.c"
"C:\code\bacnet-stack\demo\object\lsp.c"
"C:\code\bacnet-stack\ports\win32\main.c"
"C:\code\bacnet-stack\demo\object\mso.c"
"C:\code\bacnet-stack\demo\handler\noserv.c"
"C:\code\bacnet-stack\npdu.c"
"C:\code\bacnet-stack\reject.c"
"C:\code\bacnet-stack\ringbuf.c"
"C:\code\bacnet-stack\rp.c"
"C:\code\bacnet-stack\demo\handler\s_rp.c"
"C:\code\bacnet-stack\demo\handler\s_whois.c"
"C:\code\bacnet-stack\demo\handler\s_wp.c"
"C:\code\bacnet-stack\tsm.c"
"C:\code\bacnet-stack\demo\handler\txbuf.c"
"C:\code\bacnet-stack\whois.c"
"C:\code\bacnet-stack\wp.c"
]
Creating command line "cl.exe @C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP632.tmp"
Creating temporary file "C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP633.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/bacnet.pdb" /debug /machine:I386 /out:"Debug/bacnet.exe" /pdbtype:sept
".\Debug\abort.obj"
".\Debug\address.obj"
".\Debug\ai.obj"
".\Debug\ao.obj"
".\Debug\apdu.obj"
".\Debug\arf.obj"
".\Debug\av.obj"
".\Debug\bacapp.obj"
".\Debug\bacdcode.obj"
".\Debug\bacerror.obj"
".\Debug\bacfile.obj"
".\Debug\bacstr.obj"
".\Debug\bactext.obj"
".\Debug\bi.obj"
".\Debug\bigend.obj"
".\Debug\bip-init.obj"
".\Debug\bip.obj"
".\Debug\bo.obj"
".\Debug\bv.obj"
".\Debug\crc.obj"
".\Debug\datetime.obj"
".\Debug\dcc.obj"
".\Debug\device.obj"
".\Debug\h_arf.obj"
".\Debug\h_arf_a.obj"
".\Debug\h_iam.obj"
".\Debug\h_rp.obj"
".\Debug\h_rp_a.obj"
".\Debug\h_whois.obj"
".\Debug\h_wp.obj"
".\Debug\iam.obj"
".\Debug\indtext.obj"
".\Debug\lc.obj"
".\Debug\lsp.obj"
".\Debug\main.obj"
".\Debug\mso.obj"
".\Debug\noserv.obj"
".\Debug\npdu.obj"
".\Debug\reject.obj"
".\Debug\ringbuf.obj"
".\Debug\rp.obj"
".\Debug\s_rp.obj"
".\Debug\s_whois.obj"
".\Debug\s_wp.obj"
".\Debug\tsm.obj"
".\Debug\txbuf.obj"
".\Debug\whois.obj"
".\Debug\wp.obj"
]
Creating command line "link.exe @C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP633.tmp"
<h3>Output Window</h3>
Compiling...
abort.c
address.c
ai.c
ao.c
apdu.c
arf.c
av.c
bacapp.c
bacdcode.c
bacerror.c
bacfile.c
bacstr.c
bactext.c
bi.c
bigend.c
bip-init.c
bip.c
bo.c
bv.c
crc.c
Generating Code...
Compiling...
datetime.c
dcc.c
device.c
h_arf.c
h_arf_a.c
h_iam.c
h_rp.c
h_rp_a.c
h_whois.c
h_wp.c
iam.c
indtext.c
lc.c
lsp.c
main.c
mso.c
noserv.c
npdu.c
reject.c
ringbuf.c
Generating Code...
Compiling...
rp.c
s_rp.c
s_whois.c
s_wp.c
tsm.c
txbuf.c
whois.c
wp.c
Generating Code...
Linking...
Creating temporary file "C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP635.tmp" with contents
[
/nologo /o"Debug/bacnet.bsc"
".\Debug\abort.sbr"
".\Debug\address.sbr"
".\Debug\ai.sbr"
".\Debug\ao.sbr"
".\Debug\apdu.sbr"
".\Debug\arf.sbr"
".\Debug\av.sbr"
".\Debug\bacapp.sbr"
".\Debug\bacdcode.sbr"
".\Debug\bacerror.sbr"
".\Debug\bacfile.sbr"
".\Debug\bacstr.sbr"
".\Debug\bactext.sbr"
".\Debug\bi.sbr"
".\Debug\bigend.sbr"
".\Debug\bip-init.sbr"
".\Debug\bip.sbr"
".\Debug\bo.sbr"
".\Debug\bv.sbr"
".\Debug\crc.sbr"
".\Debug\datetime.sbr"
".\Debug\dcc.sbr"
".\Debug\device.sbr"
".\Debug\h_arf.sbr"
".\Debug\h_arf_a.sbr"
".\Debug\h_iam.sbr"
".\Debug\h_rp.sbr"
".\Debug\h_rp_a.sbr"
".\Debug\h_whois.sbr"
".\Debug\h_wp.sbr"
".\Debug\iam.sbr"
".\Debug\indtext.sbr"
".\Debug\lc.sbr"
".\Debug\lsp.sbr"
".\Debug\main.sbr"
".\Debug\mso.sbr"
".\Debug\noserv.sbr"
".\Debug\npdu.sbr"
".\Debug\reject.sbr"
".\Debug\ringbuf.sbr"
".\Debug\rp.sbr"
".\Debug\s_rp.sbr"
".\Debug\s_whois.sbr"
".\Debug\s_wp.sbr"
".\Debug\tsm.sbr"
".\Debug\txbuf.sbr"
".\Debug\whois.sbr"
".\Debug\wp.sbr"]
Creating command line "bscmake.exe @C:\DOCUME~1\stk01\LOCALS~1\Temp\RSP635.tmp"
Creating browse info file...
<h3>Output Window</h3>
<h3>Results</h3>
bacnet.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>
+113 -113
View File
@@ -1,113 +1,113 @@
BACnet Stack - SourceForge.net
Build for Visual C++ 6.0
When building the BACnet stack using Visual C++ compiler,
there are some settings that are important.
Q. Are there some global configuration options for this BACnet stack?
A. The BACnet stack uses some preprocessor defines to configure
a number of subtle personalities.
PRINT_ENABLED=1 - enables printing to stdio
BIG_ENDIAN=0 - chooses the BACnet encoding and decoding order
BACDL_BIP=1 - chooses BACnet/IP for the datalink layer
BACDL_ETHERNET=0 - chooses BACnet Ethernet for the datalink layer
BACDL_ARCNET=0 - chooses BACnet ARCNET for the datalink layer
BACDL_MSTP=0 - chooses BACnet MS/TP for the datalink layer
USE_INADDR=1 - uses INADDR_BROADCAST for broadcast rather than CLASSx
TSM_ENABLED=1 - enables the Transaction State Machine for clients
BIP_DEBUG=1 - enables print statements for debugging
In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type OPTION_NAME=1 or OPTION_NAME=0 in that edit box
using a comma to separate multiple options.
7. Press OK
8. Compile the entire project again...
Q. MSVC refuses to open bacnet.dsw and bacnet.dsp.
A. bacnet.dsw and bacnet.dsp are text files that were retrieved
from CVS on a unix client and are now in unix text file format since
they end with a "\r\n" rather than "\n". Use the unix2dos commandline
tool to convert them back to dos:
unix2dos bacnet.dsw
unix2dos bacnet.dsp
Q. error LNK2001: unresolved external symbol _WinMain@16
A. The demo ports/win32/main.c was designed as a Win32 Console
Application. If you want to change it to a Windows GUI application,
you will have to add all the Windows GUI code, including WinMain().
I recommend that you use a framework, such as WxWidgets/WxWindows,
but this has not been done yet.
Q. error C1083: Cannot open include file: 'stdint.h': No such file
A. The BACnet stack uses some header files, and Visual C++ needs to know
where they are:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: Preprocessor
5. You can see the "Additional include directories:" box
6. Type the path to stdint.h in that edit box (using a comma if necessary)
7. Type the path to bacdcode.h in that edit box (using a comma if necessary)
In my system, the paths look like:
c:\code\bacnet-stack\,c:\code\bacnet-stack\ports\win32\,
c:\code\bacnet-stack\demo\handler\,c:\code\bacnet-stack\demo\object\
8. Press OK
9. Compile the project again...
Q. error C2065: 'MAX_MPDU' : undeclared identifier
A. The BACnet stack uses a preprocessor define to configure
its datalink layer. In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type BACDL_BIP=1 in that edit box (using a comma if necessary)
7. Press OK
8. Compile the entire project again...
Q. error LNK2001: unresolved external symbol _bacapp_print
A. The BACnet stack uses a preprocessor define to configure
printing to stdio. In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type PRINT_ENABLED=1 in that edit box (using a comma if necessary)
7. Press OK
8. Compile the entire project again...
Q. error LNK2001: unresolved external symbol __imp__closesocket@4
A. Visual C++ needs to have the Winsock library to be happy:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "Link" tab (4th Tab)
4. You can see "Object/library modules:" edit box
5. Type Wsock32.LIB in that edit box
6. Press OK
7. Compile the entire project again...
Q. error C2061: in file tsm.c
A. The BACnet stack uses a preprocessor define to configure
client functionality in the Transaction State Machine (TSM).
In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type TSM_ENABLED=1 in that edit box (using a comma if necessary)
7. Press OK
8. Compile the entire project again...
BACnet Stack - SourceForge.net
Build for Visual C++ 6.0
When building the BACnet stack using Visual C++ compiler,
there are some settings that are important.
Q. Are there some global configuration options for this BACnet stack?
A. The BACnet stack uses some preprocessor defines to configure
a number of subtle personalities.
PRINT_ENABLED=1 - enables printing to stdio
BIG_ENDIAN=0 - chooses the BACnet encoding and decoding order
BACDL_BIP=1 - chooses BACnet/IP for the datalink layer
BACDL_ETHERNET=0 - chooses BACnet Ethernet for the datalink layer
BACDL_ARCNET=0 - chooses BACnet ARCNET for the datalink layer
BACDL_MSTP=0 - chooses BACnet MS/TP for the datalink layer
USE_INADDR=1 - uses INADDR_BROADCAST for broadcast rather than CLASSx
TSM_ENABLED=1 - enables the Transaction State Machine for clients
BIP_DEBUG=1 - enables print statements for debugging
In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type OPTION_NAME=1 or OPTION_NAME=0 in that edit box
using a comma to separate multiple options.
7. Press OK
8. Compile the entire project again...
Q. MSVC refuses to open bacnet.dsw and bacnet.dsp.
A. bacnet.dsw and bacnet.dsp are text files that were retrieved
from CVS on a unix client and are now in unix text file format since
they end with a "\r\n" rather than "\n". Use the unix2dos commandline
tool to convert them back to dos:
unix2dos bacnet.dsw
unix2dos bacnet.dsp
Q. error LNK2001: unresolved external symbol _WinMain@16
A. The demo ports/win32/main.c was designed as a Win32 Console
Application. If you want to change it to a Windows GUI application,
you will have to add all the Windows GUI code, including WinMain().
I recommend that you use a framework, such as WxWidgets/WxWindows,
but this has not been done yet.
Q. error C1083: Cannot open include file: 'stdint.h': No such file
A. The BACnet stack uses some header files, and Visual C++ needs to know
where they are:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: Preprocessor
5. You can see the "Additional include directories:" box
6. Type the path to stdint.h in that edit box (using a comma if necessary)
7. Type the path to bacdcode.h in that edit box (using a comma if necessary)
In my system, the paths look like:
c:\code\bacnet-stack\,c:\code\bacnet-stack\ports\win32\,
c:\code\bacnet-stack\demo\handler\,c:\code\bacnet-stack\demo\object\
8. Press OK
9. Compile the project again...
Q. error C2065: 'MAX_MPDU' : undeclared identifier
A. The BACnet stack uses a preprocessor define to configure
its datalink layer. In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type BACDL_BIP=1 in that edit box (using a comma if necessary)
7. Press OK
8. Compile the entire project again...
Q. error LNK2001: unresolved external symbol _bacapp_print
A. The BACnet stack uses a preprocessor define to configure
printing to stdio. In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type PRINT_ENABLED=1 in that edit box (using a comma if necessary)
7. Press OK
8. Compile the entire project again...
Q. error LNK2001: unresolved external symbol __imp__closesocket@4
A. Visual C++ needs to have the Winsock library to be happy:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "Link" tab (4th Tab)
4. You can see "Object/library modules:" edit box
5. Type Wsock32.LIB in that edit box
6. Press OK
7. Compile the entire project again...
Q. error C2061: in file tsm.c
A. The BACnet stack uses a preprocessor define to configure
client functionality in the Transaction State Machine (TSM).
In Visual C++, add a Preprocessor Definition by:
1. Select "Project" menu
2. Select "Settings..."
3. Select the "C/C++" tab (3rd Tab)
4. Select the Category: General
5. You can see the "Preprocessor Definitions:" box
6. Type TSM_ENABLED=1 in that edit box (using a comma if necessary)
7. Press OK
8. Compile the entire project again...
+358 -358
View File
@@ -1,358 +1,358 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2005 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#define WIN32_LEAN_AND_MEAN
#define STRICT 1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include "bacdcode.h"
#include "bip.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;
if ((host_ent = gethostbyname(host_name)) == NULL)
return -1;
#ifdef BIP_DEBUG
printf("host: %s at %u.%u.%u.%u\n", host_name,
((uint8_t*)host_ent->h_addr)[0],
((uint8_t*)host_ent->h_addr)[1],
((uint8_t*)host_ent->h_addr)[2],
((uint8_t*)host_ent->h_addr)[3]);
#endif
/* note: network byte order */
return *(long *) host_ent->h_addr;
}
static void set_broadcast_address(uint32_t net_address)
{
#if USE_INADDR
/* Note: sometimes INADDR_BROADCAST does not let me get
any unicast messages. Not sure why... */
(void) net_address;
bip_set_broadcast_addr(INADDR_BROADCAST);
#else
long broadcast_address = 0;
long mask = 0;
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
}
static void cleanup(void)
{
WSACleanup();
}
/* on Windows, ifname is the dotted ip address of the interface */
void bip_set_interface(char *ifname)
{
struct in_addr address;
/* setup local address */
if (bip_get_addr() == 0) {
bip_set_addr(inet_addr(ifname));
}
#ifdef BIP_DEBUG
address.s_addr = htonl(bip_get_addr());
fprintf(stderr, "Interface: %s\n", ifname);
#endif
/* setup local broadcast address */
if (bip_get_broadcast_addr() == 0) {
address.s_addr = htonl(bip_get_addr());
set_broadcast_address(address.s_addr);
}
}
static char *winsock_error_code_text(int code)
{
switch (code) {
case WSAEACCES:
return "Permission denied.";
case WSAEINTR:
return "Interrupted system call.";
case WSAEBADF:
return "Bad file number.";
case WSAEFAULT:
return "Bad address.";
case WSAEINVAL:
return "Invalid argument.";
case WSAEMFILE:
return "Too many open files.";
case WSAEWOULDBLOCK:
return "Operation would block.";
case WSAEINPROGRESS:
return "Operation now in progress. This error is returned if any Windows Sockets API function is called while a blocking function is in progress.";
case WSAENOTSOCK:
return "Socket operation on nonsocket.";
case WSAEDESTADDRREQ:
return "Destination address required.";
case WSAEMSGSIZE:
return "Message too long.";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket.";
case WSAENOPROTOOPT:
return "Protocol not available.";
case WSAEPROTONOSUPPORT:
return "Protocol not supported.";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported.";
case WSAEOPNOTSUPP:
return "Operation not supported on socket.";
case WSAEPFNOSUPPORT:
return "Protocol family not supported.";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family.";
case WSAEADDRINUSE:
return "Address already in use.";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address.";
case WSAENETDOWN:
return "Network is down. This error may be reported at any time if the Windows Sockets implementation detects an underlying failure.";
case WSAENETUNREACH:
return "Network is unreachable.";
case WSAENETRESET:
return "Network dropped connection on reset.";
case WSAECONNABORTED:
return "Software caused connection abort.";
case WSAECONNRESET:
return "Connection reset by peer.";
case WSAENOBUFS:
return "No buffer space available.";
case WSAEISCONN:
return "Socket is already connected.";
case WSAENOTCONN:
return "Socket is not connected.";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown.";
case WSAETOOMANYREFS:
return "Too many references: cannot splice.";
case WSAETIMEDOUT:
return "Connection timed out.";
case WSAECONNREFUSED:
return "Connection refused.";
case WSAELOOP:
return "Too many levels of symbolic links.";
case WSAENAMETOOLONG:
return "File name too long.";
case WSAEHOSTDOWN:
return "Host is down.";
case WSAEHOSTUNREACH:
return "No route to host.";
case WSASYSNOTREADY:
return "Returned by WSAStartup(), "
"indicating that the network subsystem is unusable.";
case WSAVERNOTSUPPORTED:
return "Returned by WSAStartup(), "
"indicating that the Windows Sockets DLL cannot support "
"this application.";
case WSANOTINITIALISED:
return "Winsock not initialized. "
"This message is returned by any function except WSAStartup(), "
"indicating that a successful WSAStartup() has not yet "
"been performed.";
case WSAEDISCON:
return "Disconnect.";
case WSAHOST_NOT_FOUND:
return "Host not found. "
"This message indicates that the key "
"(name, address, and so on) was not found.";
case WSATRY_AGAIN:
return "Nonauthoritative host not found. "
"This error may suggest that the name service itself "
"is not functioning.";
case WSANO_RECOVERY:
return "Nonrecoverable error. "
"This error may suggest that the name service itself "
"is not functioning.";
case WSANO_DATA:
return "Valid name, no data record of requested type. "
"This error indicates that the key "
"(name, address, and so on) was not found.";
default: return "unknown";
}
}
bool bip_init(char *ifname)
{
int rv = 0; /* return from socket lib calls */
struct sockaddr_in sin = { -1 };
int value = 1;
int sock_fd = -1;
int Result;
int Code;
WSADATA wd;
struct in_addr address;
struct in_addr broadcast_address;
Result = WSAStartup((1 << 8) | 1, &wd);
/*Result = WSAStartup(MAKEWORD(2,2), &wd); */
if (Result != 0) {
Code = WSAGetLastError();
printf("TCP/IP stack initialization failed\n"
" error code: %i %s\n",
Code, winsock_error_code_text(Code));
exit(1);
}
atexit(cleanup);
if (ifname)
bip_set_interface(ifname);
/* has address been set? */
address.s_addr = htonl(bip_get_addr());
if (address.s_addr == 0) {
address.s_addr = gethostaddr();
if (address.s_addr == (unsigned) -1) {
Code = WSAGetLastError();
printf("Get host address failed\n"
" error code: %i %s\n",
Code, winsock_error_code_text(Code));
exit(1);
}
bip_set_addr(address.s_addr);
}
#ifdef BIP_DEBUG
fprintf(stderr, "IP Address: %s\n", inet_ntoa(address));
#endif
/* has broadcast address been set? */
if (bip_get_broadcast_addr() == 0) {
set_broadcast_address(address.s_addr);
}
#ifdef BIP_DEBUG
broadcast_address.s_addr = htonl(bip_get_broadcast_addr());
fprintf(stderr, "IP Broadcast Address: %s\n",
inet_ntoa(broadcast_address));
fprintf(stderr, "UDP Port: 0x%04X [%hu]\n",
bip_get_port(),
bip_get_port());
#endif
/* assumes that the driver has already been initialized */
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bip_set_socket(sock_fd);
if (sock_fd < 0) {
fprintf(stderr, "bip: failed to allocate a socket.\n");
return false;
}
/* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set REUSEADDR socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
}
/* allow us to send a broadcast */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST,
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set BROADCAST socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
}
#if 0
/* probably only for Apple... */
/* rebind a port that is already in use.
Note: all users of the port must specify this flag */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT,
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set REUSEPORT socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
}
#endif
/* bind the socket to the local port number and IP address */
sin.sin_family = AF_INET;
#if USE_INADDR
/* by setting sin.sin_addr.s_addr to INADDR_ANY,
I am telling the IP stack to automatically fill
in the IP address of the machine the process
is running on.
Some server computers have multiple IP addresses.
A socket bound to one of these will not accept
connections to another address. Frequently you prefer
to allow any one of the computer's IP addresses
to be used for connections. Use INADDR_ANY (0L) to
allow clients to connect using any one of the host's
IP addresses. */
sin.sin_addr.s_addr = htonl(INADDR_ANY);
#else
/* or we could use the specific adapter address
note: already in network byte order */
sin.sin_addr.s_addr = address.s_addr;
#endif
sin.sin_port = htons(bip_get_port());
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
rv = bind(sock_fd,
(const struct sockaddr *) &sin, sizeof(struct sockaddr));
if (rv < 0) {
fprintf(stderr, "bip: failed to bind to %s port %hd\n",
inet_ntoa(sin.sin_addr), bip_get_port());
close(sock_fd);
bip_set_socket(-1);
return false;
}
return true;
}
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2005 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#define WIN32_LEAN_AND_MEAN
#define STRICT 1
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include "bacdcode.h"
#include "bip.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;
if ((host_ent = gethostbyname(host_name)) == NULL)
return -1;
#ifdef BIP_DEBUG
printf("host: %s at %u.%u.%u.%u\n", host_name,
((uint8_t*)host_ent->h_addr)[0],
((uint8_t*)host_ent->h_addr)[1],
((uint8_t*)host_ent->h_addr)[2],
((uint8_t*)host_ent->h_addr)[3]);
#endif
/* note: network byte order */
return *(long *) host_ent->h_addr;
}
static void set_broadcast_address(uint32_t net_address)
{
#if USE_INADDR
/* Note: sometimes INADDR_BROADCAST does not let me get
any unicast messages. Not sure why... */
(void) net_address;
bip_set_broadcast_addr(INADDR_BROADCAST);
#else
long broadcast_address = 0;
long mask = 0;
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
}
static void cleanup(void)
{
WSACleanup();
}
/* on Windows, ifname is the dotted ip address of the interface */
void bip_set_interface(char *ifname)
{
struct in_addr address;
/* setup local address */
if (bip_get_addr() == 0) {
bip_set_addr(inet_addr(ifname));
}
#ifdef BIP_DEBUG
address.s_addr = htonl(bip_get_addr());
fprintf(stderr, "Interface: %s\n", ifname);
#endif
/* setup local broadcast address */
if (bip_get_broadcast_addr() == 0) {
address.s_addr = htonl(bip_get_addr());
set_broadcast_address(address.s_addr);
}
}
static char *winsock_error_code_text(int code)
{
switch (code) {
case WSAEACCES:
return "Permission denied.";
case WSAEINTR:
return "Interrupted system call.";
case WSAEBADF:
return "Bad file number.";
case WSAEFAULT:
return "Bad address.";
case WSAEINVAL:
return "Invalid argument.";
case WSAEMFILE:
return "Too many open files.";
case WSAEWOULDBLOCK:
return "Operation would block.";
case WSAEINPROGRESS:
return "Operation now in progress. This error is returned if any Windows Sockets API function is called while a blocking function is in progress.";
case WSAENOTSOCK:
return "Socket operation on nonsocket.";
case WSAEDESTADDRREQ:
return "Destination address required.";
case WSAEMSGSIZE:
return "Message too long.";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket.";
case WSAENOPROTOOPT:
return "Protocol not available.";
case WSAEPROTONOSUPPORT:
return "Protocol not supported.";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported.";
case WSAEOPNOTSUPP:
return "Operation not supported on socket.";
case WSAEPFNOSUPPORT:
return "Protocol family not supported.";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family.";
case WSAEADDRINUSE:
return "Address already in use.";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address.";
case WSAENETDOWN:
return "Network is down. This error may be reported at any time if the Windows Sockets implementation detects an underlying failure.";
case WSAENETUNREACH:
return "Network is unreachable.";
case WSAENETRESET:
return "Network dropped connection on reset.";
case WSAECONNABORTED:
return "Software caused connection abort.";
case WSAECONNRESET:
return "Connection reset by peer.";
case WSAENOBUFS:
return "No buffer space available.";
case WSAEISCONN:
return "Socket is already connected.";
case WSAENOTCONN:
return "Socket is not connected.";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown.";
case WSAETOOMANYREFS:
return "Too many references: cannot splice.";
case WSAETIMEDOUT:
return "Connection timed out.";
case WSAECONNREFUSED:
return "Connection refused.";
case WSAELOOP:
return "Too many levels of symbolic links.";
case WSAENAMETOOLONG:
return "File name too long.";
case WSAEHOSTDOWN:
return "Host is down.";
case WSAEHOSTUNREACH:
return "No route to host.";
case WSASYSNOTREADY:
return "Returned by WSAStartup(), "
"indicating that the network subsystem is unusable.";
case WSAVERNOTSUPPORTED:
return "Returned by WSAStartup(), "
"indicating that the Windows Sockets DLL cannot support "
"this application.";
case WSANOTINITIALISED:
return "Winsock not initialized. "
"This message is returned by any function except WSAStartup(), "
"indicating that a successful WSAStartup() has not yet "
"been performed.";
case WSAEDISCON:
return "Disconnect.";
case WSAHOST_NOT_FOUND:
return "Host not found. "
"This message indicates that the key "
"(name, address, and so on) was not found.";
case WSATRY_AGAIN:
return "Nonauthoritative host not found. "
"This error may suggest that the name service itself "
"is not functioning.";
case WSANO_RECOVERY:
return "Nonrecoverable error. "
"This error may suggest that the name service itself "
"is not functioning.";
case WSANO_DATA:
return "Valid name, no data record of requested type. "
"This error indicates that the key "
"(name, address, and so on) was not found.";
default: return "unknown";
}
}
bool bip_init(char *ifname)
{
int rv = 0; /* return from socket lib calls */
struct sockaddr_in sin = { -1 };
int value = 1;
int sock_fd = -1;
int Result;
int Code;
WSADATA wd;
struct in_addr address;
struct in_addr broadcast_address;
Result = WSAStartup((1 << 8) | 1, &wd);
/*Result = WSAStartup(MAKEWORD(2,2), &wd); */
if (Result != 0) {
Code = WSAGetLastError();
printf("TCP/IP stack initialization failed\n"
" error code: %i %s\n",
Code, winsock_error_code_text(Code));
exit(1);
}
atexit(cleanup);
if (ifname)
bip_set_interface(ifname);
/* has address been set? */
address.s_addr = htonl(bip_get_addr());
if (address.s_addr == 0) {
address.s_addr = gethostaddr();
if (address.s_addr == (unsigned) -1) {
Code = WSAGetLastError();
printf("Get host address failed\n"
" error code: %i %s\n",
Code, winsock_error_code_text(Code));
exit(1);
}
bip_set_addr(address.s_addr);
}
#ifdef BIP_DEBUG
fprintf(stderr, "IP Address: %s\n", inet_ntoa(address));
#endif
/* has broadcast address been set? */
if (bip_get_broadcast_addr() == 0) {
set_broadcast_address(address.s_addr);
}
#ifdef BIP_DEBUG
broadcast_address.s_addr = htonl(bip_get_broadcast_addr());
fprintf(stderr, "IP Broadcast Address: %s\n",
inet_ntoa(broadcast_address));
fprintf(stderr, "UDP Port: 0x%04X [%hu]\n",
bip_get_port(),
bip_get_port());
#endif
/* assumes that the driver has already been initialized */
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bip_set_socket(sock_fd);
if (sock_fd < 0) {
fprintf(stderr, "bip: failed to allocate a socket.\n");
return false;
}
/* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set REUSEADDR socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
}
/* allow us to send a broadcast */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST,
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set BROADCAST socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
}
#if 0
/* probably only for Apple... */
/* rebind a port that is already in use.
Note: all users of the port must specify this flag */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT,
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set REUSEPORT socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
}
#endif
/* bind the socket to the local port number and IP address */
sin.sin_family = AF_INET;
#if USE_INADDR
/* by setting sin.sin_addr.s_addr to INADDR_ANY,
I am telling the IP stack to automatically fill
in the IP address of the machine the process
is running on.
Some server computers have multiple IP addresses.
A socket bound to one of these will not accept
connections to another address. Frequently you prefer
to allow any one of the computer's IP addresses
to be used for connections. Use INADDR_ANY (0L) to
allow clients to connect using any one of the host's
IP addresses. */
sin.sin_addr.s_addr = htonl(INADDR_ANY);
#else
/* or we could use the specific adapter address
note: already in network byte order */
sin.sin_addr.s_addr = address.s_addr;
#endif
sin.sin_port = htons(bip_get_port());
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
rv = bind(sock_fd,
(const struct sockaddr *) &sin, sizeof(struct sockaddr));
if (rv < 0) {
fprintf(stderr, "bip: failed to bind to %s port %hd\n",
inet_ntoa(sin.sin_addr), bip_get_port());
close(sock_fd);
bip_set_socket(-1);
return false;
}
return true;
}
+455 -455
View File
@@ -1,455 +1,455 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2005 Steve Karg, modified by Kevin Liao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include <assert.h>
#include <direct.h>
#include <io.h>
#include "bacdef.h"
#include "ethernet.h"
#include "bacdcode.h"
/* Uses WinPCap to access raw ethernet */
/* Notes: */
/* To make ethernet.c work under win32, you have to: */
/* 1. install winpcap 3.1 development pack; */
/* 2. install Microsoft Platform SDK Feb 2003. */
/* 3. remove or modify functions used for log such as */
/* "LogError()", "LogInfo()", which were implemented */
/* as a wrapper of Log4cpp. */
/* -- Kevin Liao */
/* includes for accessing ethernet by using winpcap */
#include "pcap.h"
#include "packet32.h"
#include "ntddndis.h"
#include "remote-ext.h"
/* commonly used comparison address for ethernet */
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] =
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* commonly used empty address for ethernet quick compare */
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
/* my local device data - MAC address */
uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0 };
/* couple of var for using winpcap */
static char pcap_errbuf[PCAP_ERRBUF_SIZE + 1];
static pcap_t *pcap_eth802_fp = NULL; /* 802.2 file handle, from winpcap */
static unsigned eth_timeout = 100;
/* couple of external func for runtime error logging, you can simply */
/* replace them with standard "printf(...)" */
/* Logging extern functions: Info level */
extern void LogInfo(const char *msg);
/* Logging extern functions: Error level*/
extern void LogError(const char *msg);
/* Logging extern functions: Debug level*/
extern void LogDebug(const char *msg);
bool ethernet_valid(void)
{
return (pcap_eth802_fp != NULL);
}
void ethernet_cleanup(void)
{
if (pcap_eth802_fp) {
pcap_close(pcap_eth802_fp);
pcap_eth802_fp = NULL;
}
LogInfo("ethernet.c: ethernet_cleanup() ok.\n");
}
void ethernet_set_timeout(unsigned timeout)
{
eth_timeout = timeout;
}
/*----------------------------------------------------------------------
Portable function to set a socket into nonblocking mode.
Calling this on a socket causes all future read() and write() calls on
that socket to do only as much as they can immediately, and return
without waiting.
If no data can be read or written, they return -1 and set errno
to EAGAIN (or EWOULDBLOCK).
Thanks to Bjorn Reese for this code.
----------------------------------------------------------------------*/
/**
* We don't need to use this function since WinPCap has provided one
* named "pcap_setnonblock()".
* Kevin, 2006.08.15
*/
/*
int setNonblocking(int fd)
{
int flags;
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
*/
bool ethernet_init(char *if_name)
{
PPACKET_OID_DATA pOidData;
LPADAPTER lpAdapter;
pcap_if_t *pcap_all_if;
pcap_if_t *dev;
BOOLEAN result;
CHAR str[sizeof(PACKET_OID_DATA) + 128];
int i;
char msgBuf[200];
if (ethernet_valid())
ethernet_cleanup();
/**
* Find the interface user specified
*/
/* Retrieve the device list */
if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == -1) {
sprintf(msgBuf,
"ethernet.c: error in pcap_findalldevs: %s\n", pcap_errbuf);
LogError(msgBuf);
return false;
}
/* Scan the list printing every entry */
for (dev = pcap_all_if; dev; dev = dev->next) {
if (strcmp(if_name, dev->name) == 0)
break;
}
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
if (dev == NULL) {
sprintf(msgBuf,
"ethernet.c: specified interface not found: %s\n", if_name);
LogError(msgBuf);
return false;
}
/**
* Get local MAC address
*/
ZeroMemory(str, sizeof(PACKET_OID_DATA) + 128);
lpAdapter = PacketOpenAdapter(if_name);
if (lpAdapter == NULL) {
ethernet_cleanup();
sprintf(msgBuf,
"ethernet.c: error in PacketOpenAdapter(\"%s\")\n", if_name);
LogError(msgBuf);
return false;
}
pOidData = (PPACKET_OID_DATA) str;
pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
pOidData->Length = 6;
result = PacketRequest(lpAdapter, FALSE, pOidData);
if (!result) {
PacketCloseAdapter(lpAdapter);
ethernet_cleanup();
LogError("ethernet.c: error in PacketRequest()\n");
return false;
}
for (i = 0; i < 6; ++i)
Ethernet_MAC_Address[i] = pOidData->Data[i];
PacketCloseAdapter(lpAdapter);
/**
* Open interface for subsequent sending and receiving
*/
/* Open the output device */
pcap_eth802_fp = pcap_open(if_name, /* name of the device */
MAX_MPDU, /* portion of the packet to capture */
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
eth_timeout, /* read timeout */
NULL, /* authentication on the remote machine */
pcap_errbuf /* error buffer */
);
if (pcap_eth802_fp == NULL) {
PacketCloseAdapter(lpAdapter);
ethernet_cleanup();
sprintf(msgBuf,
"ethernet.c: unable to open the adapter. %s is not supported by WinPcap\n",
if_name);
LogError(msgBuf);
return false;
}
LogInfo("ethernet.c: ethernet_init() ok.\n");
atexit(ethernet_cleanup);
return ethernet_valid();
}
/* function to send a packet out the 802.2 socket */
/* returns bytes sent success, negative on failure */
int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
{
int bytes = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
int i = 0;
/* don't waste time if the socket is not valid */
if (!ethernet_valid()) {
LogError
("ethernet.c: invalid 802.2 ethernet interface descriptor!\n");
return -1;
}
/* load destination ethernet MAC address */
if (dest->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = dest->mac[i];
mtu_len++;
}
} else {
LogError("ethernet.c: invalid destination MAC address!\n");
return -2;
}
/* load source ethernet MAC address */
if (src->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = src->mac[i];
mtu_len++;
}
} else {
LogError("ethernet.c: invalid source MAC address!\n");
return -3;
}
if ((14 + 3 + pdu_len) > MAX_MPDU) {
LogError("ethernet.c: PDU is too big to send!\n");
return -4;
}
/* packet length */
mtu_len +=
encode_unsigned16(&mtu[12], 3 /*DSAP,SSAP,LLC */ + pdu_len);
/* Logical PDU portion */
mtu[mtu_len++] = 0x82; /* DSAP for BACnet */
mtu[mtu_len++] = 0x82; /* SSAP for BACnet */
mtu[mtu_len++] = 0x03; /* Control byte in header */
memcpy(&mtu[mtu_len], pdu, pdu_len);
mtu_len += pdu_len;
/* Send the packet */
if (pcap_sendpacket(pcap_eth802_fp, mtu, mtu_len) != 0) {
/* did it get sent? */
char msgBuf[200];
sprintf(msgBuf,
"ethernet.c: error sending packet: %s\n",
pcap_geterr(pcap_eth802_fp));
LogError(msgBuf);
return -5;
}
return mtu_len;
}
/* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
{
int i = 0; /* counter */
BACNET_ADDRESS src = { 0 }; /* source address */
for (i = 0; i < 6; i++) {
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* function to send a packet out the 802.2 socket */
/* returns 1 on success, 0 on failure */
return ethernet_send(dest, /* destination address */
&src, /* source address */
pdu, /* any data to be sent - may be null */
pdu_len /* number of bytes of data */
);
}
/* receives an 802.2 framed packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t ethernet_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout /* number of milliseconds to wait for a packet. we ommit it due to winpcap API. */
)
{
struct pcap_pkthdr *header;
int res;
u_char *pkt_data;
uint16_t pdu_len = 0; /* return value */
/* Make sure the socket is open */
if (!ethernet_valid()) {
LogError
("ethernet.c: invalid 802.2 ethernet interface descriptor!\n");
return 0;
}
/* Capture a packet */
res = pcap_next_ex(pcap_eth802_fp, &header, &pkt_data);
if (res < 0) {
char msgBuf[200];
sprintf(msgBuf,
"ethernet.c: error in receiving packet: %s\n",
pcap_geterr(pcap_eth802_fp));
return 0;
} else if (res == 0)
return 0;
if (header->len == 0 || header->caplen == 0)
return 0;
/* the signature of an 802.2 BACnet packet */
if ((pkt_data[14] != 0x82) && (pkt_data[15] != 0x82)) {
/*eth_log_error("ethernet.c: Non-BACnet packet\n"); */
return 0;
}
/* copy the source address */
src->mac_len = 6;
memmove(src->mac, &pkt_data[6], 6);
/* check destination address for when */
/* the Ethernet card is in promiscious mode */
if ((memcmp(&pkt_data[0], Ethernet_MAC_Address, 6) != 0)
&& (memcmp(&pkt_data[0], Ethernet_Broadcast, 6) != 0)) {
/*eth_log_error( "ethernet.c: This packet isn't for us\n"); */
return 0;
}
(void) decode_unsigned16(&pkt_data[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ;
/* copy the buffer into the PDU */
if (pdu_len < max_pdu)
memmove(&pdu[0], &pkt_data[17], pdu_len);
/* ignore packets that are too large */
else
pdu_len = 0;
return pdu_len;
}
void ethernet_set_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
for (i = 0; i < 6; i++) {
Ethernet_MAC_Address[i] = my_address->mac[i];
}
return;
}
void ethernet_get_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
my_address->mac_len = 0;
for (i = 0; i < 6; i++) {
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
my_address->net = 0; /* local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
}
return;
}
void ethernet_get_broadcast_address(BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
for (i = 0; i < 6; i++) {
dest->mac[i] = Ethernet_Broadcast[i];
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* denotes broadcast address */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
}
return;
}
void ethernet_debug_address(const char *info, BACNET_ADDRESS * dest)
{
int i = 0; /* counter */
char msgBuf[200];
if (info) {
sprintf(msgBuf, "%s", info);
LogError(msgBuf);
}
/* if */
if (dest) {
sprintf(msgBuf,
"Address:\n MAC Length=%d\n MAC Address=", dest->mac_len);
LogInfo(msgBuf);
for (i = 0; i < MAX_MAC_LEN; i++) {
sprintf(msgBuf, "%02X ", (unsigned) dest->mac[i]);
LogInfo(msgBuf);
} /* for */
LogInfo("\n");
sprintf(msgBuf,
" Net=%hu\n Len=%d\n Adr=", dest->net, dest->len);
LogInfo(msgBuf);
for (i = 0; i < MAX_MAC_LEN; i++) {
sprintf(msgBuf, "%02X ", (unsigned) dest->adr[i]);
LogInfo(msgBuf);
} /* for */
LogInfo("\n");
}
/* if ( dest ) */
return;
}
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2005 Steve Karg, modified by Kevin Liao
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
The Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based
on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However
the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public
License.
-------------------------------------------
####COPYRIGHTEND####*/
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include <assert.h>
#include <direct.h>
#include <io.h>
#include "bacdef.h"
#include "ethernet.h"
#include "bacdcode.h"
/* Uses WinPCap to access raw ethernet */
/* Notes: */
/* To make ethernet.c work under win32, you have to: */
/* 1. install winpcap 3.1 development pack; */
/* 2. install Microsoft Platform SDK Feb 2003. */
/* 3. remove or modify functions used for log such as */
/* "LogError()", "LogInfo()", which were implemented */
/* as a wrapper of Log4cpp. */
/* -- Kevin Liao */
/* includes for accessing ethernet by using winpcap */
#include "pcap.h"
#include "packet32.h"
#include "ntddndis.h"
#include "remote-ext.h"
/* commonly used comparison address for ethernet */
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] =
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
/* commonly used empty address for ethernet quick compare */
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
/* my local device data - MAC address */
uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0 };
/* couple of var for using winpcap */
static char pcap_errbuf[PCAP_ERRBUF_SIZE + 1];
static pcap_t *pcap_eth802_fp = NULL; /* 802.2 file handle, from winpcap */
static unsigned eth_timeout = 100;
/* couple of external func for runtime error logging, you can simply */
/* replace them with standard "printf(...)" */
/* Logging extern functions: Info level */
extern void LogInfo(const char *msg);
/* Logging extern functions: Error level*/
extern void LogError(const char *msg);
/* Logging extern functions: Debug level*/
extern void LogDebug(const char *msg);
bool ethernet_valid(void)
{
return (pcap_eth802_fp != NULL);
}
void ethernet_cleanup(void)
{
if (pcap_eth802_fp) {
pcap_close(pcap_eth802_fp);
pcap_eth802_fp = NULL;
}
LogInfo("ethernet.c: ethernet_cleanup() ok.\n");
}
void ethernet_set_timeout(unsigned timeout)
{
eth_timeout = timeout;
}
/*----------------------------------------------------------------------
Portable function to set a socket into nonblocking mode.
Calling this on a socket causes all future read() and write() calls on
that socket to do only as much as they can immediately, and return
without waiting.
If no data can be read or written, they return -1 and set errno
to EAGAIN (or EWOULDBLOCK).
Thanks to Bjorn Reese for this code.
----------------------------------------------------------------------*/
/**
* We don't need to use this function since WinPCap has provided one
* named "pcap_setnonblock()".
* Kevin, 2006.08.15
*/
/*
int setNonblocking(int fd)
{
int flags;
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
*/
bool ethernet_init(char *if_name)
{
PPACKET_OID_DATA pOidData;
LPADAPTER lpAdapter;
pcap_if_t *pcap_all_if;
pcap_if_t *dev;
BOOLEAN result;
CHAR str[sizeof(PACKET_OID_DATA) + 128];
int i;
char msgBuf[200];
if (ethernet_valid())
ethernet_cleanup();
/**
* Find the interface user specified
*/
/* Retrieve the device list */
if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == -1) {
sprintf(msgBuf,
"ethernet.c: error in pcap_findalldevs: %s\n", pcap_errbuf);
LogError(msgBuf);
return false;
}
/* Scan the list printing every entry */
for (dev = pcap_all_if; dev; dev = dev->next) {
if (strcmp(if_name, dev->name) == 0)
break;
}
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
if (dev == NULL) {
sprintf(msgBuf,
"ethernet.c: specified interface not found: %s\n", if_name);
LogError(msgBuf);
return false;
}
/**
* Get local MAC address
*/
ZeroMemory(str, sizeof(PACKET_OID_DATA) + 128);
lpAdapter = PacketOpenAdapter(if_name);
if (lpAdapter == NULL) {
ethernet_cleanup();
sprintf(msgBuf,
"ethernet.c: error in PacketOpenAdapter(\"%s\")\n", if_name);
LogError(msgBuf);
return false;
}
pOidData = (PPACKET_OID_DATA) str;
pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
pOidData->Length = 6;
result = PacketRequest(lpAdapter, FALSE, pOidData);
if (!result) {
PacketCloseAdapter(lpAdapter);
ethernet_cleanup();
LogError("ethernet.c: error in PacketRequest()\n");
return false;
}
for (i = 0; i < 6; ++i)
Ethernet_MAC_Address[i] = pOidData->Data[i];
PacketCloseAdapter(lpAdapter);
/**
* Open interface for subsequent sending and receiving
*/
/* Open the output device */
pcap_eth802_fp = pcap_open(if_name, /* name of the device */
MAX_MPDU, /* portion of the packet to capture */
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
eth_timeout, /* read timeout */
NULL, /* authentication on the remote machine */
pcap_errbuf /* error buffer */
);
if (pcap_eth802_fp == NULL) {
PacketCloseAdapter(lpAdapter);
ethernet_cleanup();
sprintf(msgBuf,
"ethernet.c: unable to open the adapter. %s is not supported by WinPcap\n",
if_name);
LogError(msgBuf);
return false;
}
LogInfo("ethernet.c: ethernet_init() ok.\n");
atexit(ethernet_cleanup);
return ethernet_valid();
}
/* function to send a packet out the 802.2 socket */
/* returns bytes sent success, negative on failure */
int ethernet_send(BACNET_ADDRESS * dest, /* destination address */
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
{
int bytes = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
int i = 0;
/* don't waste time if the socket is not valid */
if (!ethernet_valid()) {
LogError
("ethernet.c: invalid 802.2 ethernet interface descriptor!\n");
return -1;
}
/* load destination ethernet MAC address */
if (dest->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = dest->mac[i];
mtu_len++;
}
} else {
LogError("ethernet.c: invalid destination MAC address!\n");
return -2;
}
/* load source ethernet MAC address */
if (src->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = src->mac[i];
mtu_len++;
}
} else {
LogError("ethernet.c: invalid source MAC address!\n");
return -3;
}
if ((14 + 3 + pdu_len) > MAX_MPDU) {
LogError("ethernet.c: PDU is too big to send!\n");
return -4;
}
/* packet length */
mtu_len +=
encode_unsigned16(&mtu[12], 3 /*DSAP,SSAP,LLC */ + pdu_len);
/* Logical PDU portion */
mtu[mtu_len++] = 0x82; /* DSAP for BACnet */
mtu[mtu_len++] = 0x82; /* SSAP for BACnet */
mtu[mtu_len++] = 0x03; /* Control byte in header */
memcpy(&mtu[mtu_len], pdu, pdu_len);
mtu_len += pdu_len;
/* Send the packet */
if (pcap_sendpacket(pcap_eth802_fp, mtu, mtu_len) != 0) {
/* did it get sent? */
char msgBuf[200];
sprintf(msgBuf,
"ethernet.c: error sending packet: %s\n",
pcap_geterr(pcap_eth802_fp));
LogError(msgBuf);
return -5;
}
return mtu_len;
}
/* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
{
int i = 0; /* counter */
BACNET_ADDRESS src = { 0 }; /* source address */
for (i = 0; i < 6; i++) {
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* function to send a packet out the 802.2 socket */
/* returns 1 on success, 0 on failure */
return ethernet_send(dest, /* destination address */
&src, /* source address */
pdu, /* any data to be sent - may be null */
pdu_len /* number of bytes of data */
);
}
/* receives an 802.2 framed packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t ethernet_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout /* number of milliseconds to wait for a packet. we ommit it due to winpcap API. */
)
{
struct pcap_pkthdr *header;
int res;
u_char *pkt_data;
uint16_t pdu_len = 0; /* return value */
/* Make sure the socket is open */
if (!ethernet_valid()) {
LogError
("ethernet.c: invalid 802.2 ethernet interface descriptor!\n");
return 0;
}
/* Capture a packet */
res = pcap_next_ex(pcap_eth802_fp, &header, &pkt_data);
if (res < 0) {
char msgBuf[200];
sprintf(msgBuf,
"ethernet.c: error in receiving packet: %s\n",
pcap_geterr(pcap_eth802_fp));
return 0;
} else if (res == 0)
return 0;
if (header->len == 0 || header->caplen == 0)
return 0;
/* the signature of an 802.2 BACnet packet */
if ((pkt_data[14] != 0x82) && (pkt_data[15] != 0x82)) {
/*eth_log_error("ethernet.c: Non-BACnet packet\n"); */
return 0;
}
/* copy the source address */
src->mac_len = 6;
memmove(src->mac, &pkt_data[6], 6);
/* check destination address for when */
/* the Ethernet card is in promiscious mode */
if ((memcmp(&pkt_data[0], Ethernet_MAC_Address, 6) != 0)
&& (memcmp(&pkt_data[0], Ethernet_Broadcast, 6) != 0)) {
/*eth_log_error( "ethernet.c: This packet isn't for us\n"); */
return 0;
}
(void) decode_unsigned16(&pkt_data[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ;
/* copy the buffer into the PDU */
if (pdu_len < max_pdu)
memmove(&pdu[0], &pkt_data[17], pdu_len);
/* ignore packets that are too large */
else
pdu_len = 0;
return pdu_len;
}
void ethernet_set_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
for (i = 0; i < 6; i++) {
Ethernet_MAC_Address[i] = my_address->mac[i];
}
return;
}
void ethernet_get_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
my_address->mac_len = 0;
for (i = 0; i < 6; i++) {
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
my_address->net = 0; /* local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
}
return;
}
void ethernet_get_broadcast_address(BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
for (i = 0; i < 6; i++) {
dest->mac[i] = Ethernet_Broadcast[i];
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* denotes broadcast address */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
}
return;
}
void ethernet_debug_address(const char *info, BACNET_ADDRESS * dest)
{
int i = 0; /* counter */
char msgBuf[200];
if (info) {
sprintf(msgBuf, "%s", info);
LogError(msgBuf);
}
/* if */
if (dest) {
sprintf(msgBuf,
"Address:\n MAC Length=%d\n MAC Address=", dest->mac_len);
LogInfo(msgBuf);
for (i = 0; i < MAX_MAC_LEN; i++) {
sprintf(msgBuf, "%02X ", (unsigned) dest->mac[i]);
LogInfo(msgBuf);
} /* for */
LogInfo("\n");
sprintf(msgBuf,
" Net=%hu\n Len=%d\n Adr=", dest->net, dest->len);
LogInfo(msgBuf);
for (i = 0; i < MAX_MAC_LEN; i++) {
sprintf(msgBuf, "%02X ", (unsigned) dest->adr[i]);
LogInfo(msgBuf);
} /* for */
LogInfo("\n");
}
/* if ( dest ) */
return;
}
+257 -257
View File
@@ -1,257 +1,257 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* This is one way to use the embedded BACnet stack under Win32 */
/* compiled with Borland C++ 5.02 or Visual C++ 6.0 */
#include <winsock2.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <conio.h> /* for kbhit and getch */
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "handlers.h"
#include "client.h"
#include "datalink.h"
#include "txbuf.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* send a whois to see who is on the network */
static bool Who_Is_Request = true;
bool I_Am_Request = true;
static void Read_Properties(void)
{
uint32_t device_id = 0;
bool status = false;
unsigned max_apdu = 0;
BACNET_ADDRESS src;
bool next_device = false;
static unsigned index = 0;
static unsigned property = 0;
/* list of required (and some optional) properties in the
Device Object
note: you could just loop through
all the properties in all the objects. */
const int object_props[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_SYSTEM_STATUS,
PROP_VENDOR_NAME,
PROP_VENDOR_IDENTIFIER,
PROP_MODEL_NAME,
PROP_FIRMWARE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION,
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_CONFORMANCE_CLASS,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_LOCAL_TIME,
PROP_LOCAL_DATE,
PROP_UTC_OFFSET,
PROP_DAYLIGHT_SAVINGS_STATUS,
PROP_APDU_SEGMENT_TIMEOUT,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
PROP_DEVICE_ADDRESS_BINDING,
/* note: PROP_OBJECT_LIST is missing cause
we need to get it with an index method since
the list could be very large */
/* some proprietary properties */
514, 515,
/* end of list */
-1
};
if (address_count()) {
if (address_get_by_index(index, &device_id, &max_apdu, &src)) {
if (object_props[property] < 0)
next_device = true;
else {
status = Send_Read_Property_Request(device_id, /* destination device */
OBJECT_DEVICE,
device_id, object_props[property], BACNET_ARRAY_ALL);
if (status)
property++;
}
} else
next_device = true;
if (next_device) {
next_device = false;
index++;
if (index >= MAX_ADDRESS_CACHE)
index = 0;
property = 0;
}
}
return;
}
static void LocalIAmHandler(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
{
int len = 0;
uint32_t device_id = 0;
unsigned max_apdu = 0;
int segmentation = 0;
uint16_t vendor_id = 0;
(void) src;
(void) service_len;
len = iam_decode_service_request(service_request,
&device_id, &max_apdu, &segmentation, &vendor_id);
fprintf(stderr, "Received I-Am Request");
if (len != -1) {
fprintf(stderr, " from %u!\n", device_id);
address_add(device_id, max_apdu, src);
} else
fprintf(stderr, "!\n");
return;
}
static void Init_Service_Handlers(void)
{
/* 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_I_AM,
LocalIAmHandler);
/* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property);
/* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
}
static void print_address(char *name, BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
printf("%s: ", name);
for (i = 0; i < dest->mac_len; i++) {
printf("%02X", dest->mac[i]);
}
printf("\n");
}
}
static void print_address_cache(void)
{
int i, j;
BACNET_ADDRESS address;
uint32_t device_id = 0;
unsigned max_apdu = 0;
fprintf(stderr, "Device\tMAC\tMaxAPDU\tNet\n");
for (i = 0; i < MAX_ADDRESS_CACHE; i++) {
if (address_get_by_index(i, &device_id, &max_apdu, &address)) {
fprintf(stderr, "%u\t", device_id);
for (j = 0; j < address.mac_len; j++) {
fprintf(stderr, "%02X", address.mac[j]);
}
fprintf(stderr, "\t");
fprintf(stderr, "%hu\t", max_apdu);
fprintf(stderr, "%hu\n", address.net);
}
}
}
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
BACNET_ADDRESS my_address, broadcast_address;
(void) argc;
(void) argv;
Device_Set_Object_Instance_Number(124);
Init_Service_Handlers();
/* init the data link layer */
if (!datalink_init(NULL))
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");
/* loop forever */
for (;;) {
/* input */
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (I_Am_Request) {
I_Am_Request = false;
iam_send(&Handler_Transmit_Buffer[0]);
} else if (Who_Is_Request) {
Who_Is_Request = false;
Send_WhoIs(-1, -1);
} else {
Read_Properties();
}
/* output */
/* blink LEDs, Turn on or off outputs, etc */
/* wait for ESC from keyboard before quitting */
if (kbhit() && (getch() == 0x1B))
break;
}
print_address_cache();
return 0;
}
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* This is one way to use the embedded BACnet stack under Win32 */
/* compiled with Borland C++ 5.02 or Visual C++ 6.0 */
#include <winsock2.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <conio.h> /* for kbhit and getch */
#include "iam.h"
#include "address.h"
#include "config.h"
#include "bacdef.h"
#include "npdu.h"
#include "apdu.h"
#include "device.h"
#include "handlers.h"
#include "client.h"
#include "datalink.h"
#include "txbuf.h"
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* send a whois to see who is on the network */
static bool Who_Is_Request = true;
bool I_Am_Request = true;
static void Read_Properties(void)
{
uint32_t device_id = 0;
bool status = false;
unsigned max_apdu = 0;
BACNET_ADDRESS src;
bool next_device = false;
static unsigned index = 0;
static unsigned property = 0;
/* list of required (and some optional) properties in the
Device Object
note: you could just loop through
all the properties in all the objects. */
const int object_props[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_SYSTEM_STATUS,
PROP_VENDOR_NAME,
PROP_VENDOR_IDENTIFIER,
PROP_MODEL_NAME,
PROP_FIRMWARE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION,
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_CONFORMANCE_CLASS,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_LOCAL_TIME,
PROP_LOCAL_DATE,
PROP_UTC_OFFSET,
PROP_DAYLIGHT_SAVINGS_STATUS,
PROP_APDU_SEGMENT_TIMEOUT,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
PROP_DEVICE_ADDRESS_BINDING,
/* note: PROP_OBJECT_LIST is missing cause
we need to get it with an index method since
the list could be very large */
/* some proprietary properties */
514, 515,
/* end of list */
-1
};
if (address_count()) {
if (address_get_by_index(index, &device_id, &max_apdu, &src)) {
if (object_props[property] < 0)
next_device = true;
else {
status = Send_Read_Property_Request(device_id, /* destination device */
OBJECT_DEVICE,
device_id, object_props[property], BACNET_ARRAY_ALL);
if (status)
property++;
}
} else
next_device = true;
if (next_device) {
next_device = false;
index++;
if (index >= MAX_ADDRESS_CACHE)
index = 0;
property = 0;
}
}
return;
}
static void LocalIAmHandler(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
{
int len = 0;
uint32_t device_id = 0;
unsigned max_apdu = 0;
int segmentation = 0;
uint16_t vendor_id = 0;
(void) src;
(void) service_len;
len = iam_decode_service_request(service_request,
&device_id, &max_apdu, &segmentation, &vendor_id);
fprintf(stderr, "Received I-Am Request");
if (len != -1) {
fprintf(stderr, " from %u!\n", device_id);
address_add(device_id, max_apdu, src);
} else
fprintf(stderr, "!\n");
return;
}
static void Init_Service_Handlers(void)
{
/* 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_I_AM,
LocalIAmHandler);
/* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property);
/* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
}
static void print_address(char *name, BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
printf("%s: ", name);
for (i = 0; i < dest->mac_len; i++) {
printf("%02X", dest->mac[i]);
}
printf("\n");
}
}
static void print_address_cache(void)
{
int i, j;
BACNET_ADDRESS address;
uint32_t device_id = 0;
unsigned max_apdu = 0;
fprintf(stderr, "Device\tMAC\tMaxAPDU\tNet\n");
for (i = 0; i < MAX_ADDRESS_CACHE; i++) {
if (address_get_by_index(i, &device_id, &max_apdu, &address)) {
fprintf(stderr, "%u\t", device_id);
for (j = 0; j < address.mac_len; j++) {
fprintf(stderr, "%02X", address.mac[j]);
}
fprintf(stderr, "\t");
fprintf(stderr, "%hu\t", max_apdu);
fprintf(stderr, "%hu\n", address.net);
}
}
}
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
BACNET_ADDRESS my_address, broadcast_address;
(void) argc;
(void) argv;
Device_Set_Object_Instance_Number(124);
Init_Service_Handlers();
/* init the data link layer */
if (!datalink_init(NULL))
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");
/* loop forever */
for (;;) {
/* input */
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (I_Am_Request) {
I_Am_Request = false;
iam_send(&Handler_Transmit_Buffer[0]);
} else if (Who_Is_Request) {
Who_Is_Request = false;
Send_WhoIs(-1, -1);
} else {
Read_Properties();
}
/* output */
/* blink LEDs, Turn on or off outputs, etc */
/* wait for ESC from keyboard before quitting */
if (kbhit() && (getch() == 0x1B))
break;
}
print_address_cache();
return 0;
}
+38 -38
View File
@@ -1,38 +1,38 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#ifndef NET_H
#define NET_H
#define WIN32_LEAN_AND_MEAN
#define STRICT 1
#include <winsock2.h>
#define close closesocket
typedef int socklen_t;
#endif
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#ifndef NET_H
#define NET_H
#define WIN32_LEAN_AND_MEAN
#define STRICT 1
#include <winsock2.h>
#define close closesocket
typedef int socklen_t;
#endif
+15 -15
View File
@@ -1,15 +1,15 @@
BACnet Stack - Win32
This directory contains a demo program that compiles with a Win32 compiler.
It was tested with the freely downloadable Borland C++ 5.5, as well as
Borland C++ 5 and Visual C++ 6.0.
The makefile.mak file is used with the Borland command line tools.
Run setvars.bat to configure the environment for the Borland tools.
Edit it if necessary to set the correct location of your tools.
The bacnet.ide file is used with the Borland IDE.
The bacnet directory is used with Visual C++ 6 tools, and there is a
workspace file bacnet.dsw that is used to compile the demo program.
BACnet Stack - Win32
This directory contains a demo program that compiles with a Win32 compiler.
It was tested with the freely downloadable Borland C++ 5.5, as well as
Borland C++ 5 and Visual C++ 6.0.
The makefile.mak file is used with the Borland command line tools.
Run setvars.bat to configure the environment for the Borland tools.
Edit it if necessary to set the correct location of your tools.
The bacnet.ide file is used with the Borland IDE.
The bacnet directory is used with Visual C++ 6 tools, and there is a
workspace file bacnet.dsw that is used to compile the demo program.
+2 -2
View File
@@ -1,2 +1,2 @@
set BORLAND_DIR=\bcc55
set BORLAND_DIR=\bcc55
+28 -28
View File
@@ -1,28 +1,28 @@
#ifndef STDBOOL_H
#define STDBOOL_H
/* C99 Boolean types for compilers without C99 support */
#ifndef __cplusplus
typedef int _Bool;
#ifndef bool
#define bool _Bool
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define __bool_true_false_are_defined 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#endif
#ifndef STDBOOL_H
#define STDBOOL_H
/* C99 Boolean types for compilers without C99 support */
#ifndef __cplusplus
typedef int _Bool;
#ifndef bool
#define bool _Bool
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define __bool_true_false_are_defined 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#endif
+19 -19
View File
@@ -1,19 +1,19 @@
/* Defines the standard integer types that are used in code */
/* for the x86 processor and Borland Compiler */
#ifndef STDINT_H
#define STDINT_H
#include <stddef.h>
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
typedef signed char int8_t; /* 1 byte -127 to 127 */
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
/*typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 */
typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
/* typedef signed long long int64_t; */
/* typedef unsigned long long uint64_t; */
#endif /* STDINT_H */
/* Defines the standard integer types that are used in code */
/* for the x86 processor and Borland Compiler */
#ifndef STDINT_H
#define STDINT_H
#include <stddef.h>
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
typedef signed char int8_t; /* 1 byte -127 to 127 */
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
/*typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215 */
typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
/* typedef signed long long int64_t; */
/* typedef unsigned long long uint64_t; */
#endif /* STDINT_H */