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