Ran the indent and comment script to standardize the source files.

This commit is contained in:
skarg
2007-02-23 02:14:50 +00:00
parent ada921d5f3
commit 1386b41f2d
21 changed files with 983 additions and 987 deletions
+43 -44
View File
@@ -112,15 +112,14 @@ int bacapp_encode_application_data(uint8_t * apdu,
/* decode the data and store it into value. /* decode the data and store it into value.
Return the number of octets consumed. */ Return the number of octets consumed. */
int bacapp_decode_data(uint8_t * apdu, int bacapp_decode_data(uint8_t * apdu,
uint8_t tag_data_type, uint8_t tag_data_type,
uint32_t len_value_type, uint32_t len_value_type, BACNET_APPLICATION_DATA_VALUE * value)
BACNET_APPLICATION_DATA_VALUE * value)
{ {
int len = 0; int len = 0;
int object_type = 0; int object_type = 0;
uint32_t instance = 0; uint32_t instance = 0;
if (apdu && value) { if (apdu && value) {
switch (tag_data_type) { switch (tag_data_type) {
case BACNET_APPLICATION_TAG_NULL: case BACNET_APPLICATION_TAG_NULL:
@@ -156,8 +155,7 @@ int bacapp_decode_data(uint8_t * apdu,
len = decode_bacnet_time(&apdu[0], &value->type.Time); len = decode_bacnet_time(&apdu[0], &value->type.Time);
break; break;
case BACNET_APPLICATION_TAG_OBJECT_ID: case BACNET_APPLICATION_TAG_OBJECT_ID:
len = decode_object_id(&apdu[0], len = decode_object_id(&apdu[0], &object_type, &instance);
&object_type, &instance);
value->type.Object_Id.type = object_type; value->type.Object_Id.type = object_type;
value->type.Object_Id.instance = instance; value->type.Object_Id.instance = instance;
break; break;
@@ -198,10 +196,8 @@ int bacapp_decode_application_data(uint8_t * apdu,
if (tag_len) { if (tag_len) {
len += tag_len; len += tag_len;
value->tag = tag_number; value->tag = tag_number;
len += bacapp_decode_data(&apdu[len], len += bacapp_decode_data(&apdu[len],
tag_number, tag_number, len_value_type, value);
len_value_type,
value);
} }
value->next = NULL; value->next = NULL;
} }
@@ -209,22 +205,23 @@ int bacapp_decode_application_data(uint8_t * apdu,
return len; return len;
} }
int bacapp_encode_context_data_value(uint8_t * apdu, uint8_t context_tag_number, int bacapp_encode_context_data_value(uint8_t * apdu,
BACNET_APPLICATION_DATA_VALUE * value) uint8_t context_tag_number, BACNET_APPLICATION_DATA_VALUE * value)
{ {
int apdu_len = 0; /* total length of the apdu, return value */ int apdu_len = 0; /* total length of the apdu, return value */
if (value && apdu) { if (value && apdu) {
switch (value->tag) { switch (value->tag) {
case BACNET_APPLICATION_TAG_NULL: case BACNET_APPLICATION_TAG_NULL:
apdu_len = encode_context_null(&apdu[0], context_tag_number); apdu_len = encode_context_null(&apdu[0], context_tag_number);
break; break;
case BACNET_APPLICATION_TAG_BOOLEAN: case BACNET_APPLICATION_TAG_BOOLEAN:
apdu_len = encode_context_boolean(&apdu[0], context_tag_number, apdu_len = encode_context_boolean(&apdu[0], context_tag_number,
value->type.Boolean); value->type.Boolean);
break; break;
case BACNET_APPLICATION_TAG_UNSIGNED_INT: case BACNET_APPLICATION_TAG_UNSIGNED_INT:
apdu_len = encode_context_unsigned(&apdu[0], context_tag_number, apdu_len =
encode_context_unsigned(&apdu[0], context_tag_number,
value->type.Unsigned_Int); value->type.Unsigned_Int);
break; break;
case BACNET_APPLICATION_TAG_SIGNED_INT: case BACNET_APPLICATION_TAG_SIGNED_INT:
@@ -236,11 +233,12 @@ int bacapp_encode_context_data_value(uint8_t * apdu, uint8_t context_tag_number,
value->type.Real); value->type.Real);
break; break;
case BACNET_APPLICATION_TAG_ENUMERATED: case BACNET_APPLICATION_TAG_ENUMERATED:
apdu_len = encode_context_enumerated(&apdu[0], context_tag_number, apdu_len =
encode_context_enumerated(&apdu[0], context_tag_number,
value->type.Enumerated); value->type.Enumerated);
break; break;
case BACNET_APPLICATION_TAG_DATE: case BACNET_APPLICATION_TAG_DATE:
apdu_len = encode_context_date(&apdu[0], context_tag_number, apdu_len = encode_context_date(&apdu[0], context_tag_number,
&value->type.Date); &value->type.Date);
break; break;
case BACNET_APPLICATION_TAG_TIME: case BACNET_APPLICATION_TAG_TIME:
@@ -248,27 +246,31 @@ int bacapp_encode_context_data_value(uint8_t * apdu, uint8_t context_tag_number,
&value->type.Time); &value->type.Time);
break; break;
case BACNET_APPLICATION_TAG_OBJECT_ID: case BACNET_APPLICATION_TAG_OBJECT_ID:
apdu_len = encode_context_object_id(&apdu[0], context_tag_number, apdu_len =
encode_context_object_id(&apdu[0], context_tag_number,
value->type.Object_Id.type, value->type.Object_Id.type,
value->type.Object_Id.instance); value->type.Object_Id.instance);
break; break;
case BACNET_APPLICATION_TAG_OCTET_STRING: case BACNET_APPLICATION_TAG_OCTET_STRING:
apdu_len = encode_context_octet_string(&apdu[0], context_tag_number, apdu_len =
encode_context_octet_string(&apdu[0], context_tag_number,
&value->type.Octet_String); &value->type.Octet_String);
break; break;
case BACNET_APPLICATION_TAG_CHARACTER_STRING: case BACNET_APPLICATION_TAG_CHARACTER_STRING:
apdu_len = encode_context_character_string(&apdu[0], context_tag_number, apdu_len =
&value->type.Character_String); encode_context_character_string(&apdu[0],
context_tag_number, &value->type.Character_String);
break; break;
case BACNET_APPLICATION_TAG_BIT_STRING: case BACNET_APPLICATION_TAG_BIT_STRING:
apdu_len = encode_context_bitstring(&apdu[0], context_tag_number, apdu_len =
encode_context_bitstring(&apdu[0], context_tag_number,
&value->type.Bit_String); &value->type.Bit_String);
break; break;
#if 0 #if 0
case BACNET_APPLICATION_TAG_DOUBLE: case BACNET_APPLICATION_TAG_DOUBLE:
/* FIXME: double is not implemented yet.*/ /* FIXME: double is not implemented yet. */
apdu_len = encode_context_double(&apdu[0], context_tag_number, apdu_len = encode_context_double(&apdu[0], context_tag_number,
value->type.Double); value->type.Double);
break; break;
#endif #endif
default: default:
@@ -280,8 +282,7 @@ int bacapp_encode_context_data_value(uint8_t * apdu, uint8_t context_tag_number,
} }
/* returns the fixed tag type for certain context tagged properties */ /* returns the fixed tag type for certain context tagged properties */
BACNET_APPLICATION_TAG bacapp_context_tag_type( BACNET_APPLICATION_TAG bacapp_context_tag_type(BACNET_PROPERTY_ID property,
BACNET_PROPERTY_ID property,
uint8_t tag_number) uint8_t tag_number)
{ {
BACNET_APPLICATION_TAG tag = MAX_BACNET_APPLICATION_TAG; BACNET_APPLICATION_TAG tag = MAX_BACNET_APPLICATION_TAG;
@@ -318,7 +319,7 @@ BACNET_APPLICATION_TAG bacapp_context_tag_type(
case 8: case 8:
tag = BACNET_APPLICATION_TAG_BOOLEAN; tag = BACNET_APPLICATION_TAG_BOOLEAN;
break; break;
case 4: /* propertyValue: abstract syntax */ case 4: /* propertyValue: abstract syntax */
default: default:
break; break;
} }
@@ -331,8 +332,8 @@ BACNET_APPLICATION_TAG bacapp_context_tag_type(
case 3: case 3:
tag = BACNET_APPLICATION_TAG_UNSIGNED_INT; tag = BACNET_APPLICATION_TAG_UNSIGNED_INT;
break; break;
case 0: /* calendarEntry: abstract syntax + context */ case 0: /* calendarEntry: abstract syntax + context */
case 2: /* list of BACnetTimeValue: abstract syntax */ case 2: /* list of BACnetTimeValue: abstract syntax */
default: default:
break; break;
} }
@@ -340,21 +341,21 @@ BACNET_APPLICATION_TAG bacapp_context_tag_type(
default: default:
break; break;
} }
return tag; return tag;
} }
int bacapp_encode_context_data(uint8_t * apdu, int bacapp_encode_context_data(uint8_t * apdu,
BACNET_APPLICATION_DATA_VALUE * value, BACNET_APPLICATION_DATA_VALUE * value, BACNET_PROPERTY_ID property)
BACNET_PROPERTY_ID property)
{ {
int apdu_len = 0; int apdu_len = 0;
BACNET_APPLICATION_TAG tag_data_type; BACNET_APPLICATION_TAG tag_data_type;
if (value && apdu) { if (value && apdu) {
tag_data_type = bacapp_context_tag_type(property, value->context_tag); tag_data_type =
bacapp_context_tag_type(property, value->context_tag);
if (tag_data_type < MAX_BACNET_APPLICATION_TAG) { if (tag_data_type < MAX_BACNET_APPLICATION_TAG) {
apdu_len = bacapp_encode_context_data_value(&apdu[0], apdu_len = bacapp_encode_context_data_value(&apdu[0],
value->context_tag, value); value->context_tag, value);
} else { } else {
/* FIXME: what now? */ /* FIXME: what now? */
@@ -363,11 +364,11 @@ int bacapp_encode_context_data(uint8_t * apdu,
value->next = NULL; value->next = NULL;
} }
return apdu_len; return apdu_len;
} }
int bacapp_decode_context_data(uint8_t * apdu, int bacapp_decode_context_data(uint8_t * apdu,
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value, int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property) BACNET_PROPERTY_ID property)
{ {
int apdu_len = 0, len = 0; int apdu_len = 0, len = 0;
@@ -386,10 +387,8 @@ int bacapp_decode_context_data(uint8_t * apdu,
value->context_tag = tag_number; value->context_tag = tag_number;
value->tag = bacapp_context_tag_type(property, tag_number); value->tag = bacapp_context_tag_type(property, tag_number);
if (value->tag < MAX_BACNET_APPLICATION_TAG) { if (value->tag < MAX_BACNET_APPLICATION_TAG) {
len = bacapp_decode_data(&apdu[apdu_len], len = bacapp_decode_data(&apdu[apdu_len],
value->tag, value->tag, len_value_type, value);
len_value_type,
value);
apdu_len += len; apdu_len += len;
} else { } else {
/* FIXME: what now? */ /* FIXME: what now? */
@@ -409,13 +408,13 @@ int bacapp_encode_data(uint8_t * apdu,
if (value && apdu) { if (value && apdu) {
if (value->context_specific) { if (value->context_specific) {
apdu_len = bacapp_encode_context_data_value(&apdu[0], apdu_len = bacapp_encode_context_data_value(&apdu[0],
value->context_tag, value); value->context_tag, value);
} else { } else {
apdu_len = bacapp_encode_application_data(&apdu[0], value); apdu_len = bacapp_encode_application_data(&apdu[0], value);
} }
} }
return apdu_len; return apdu_len;
} }
+7 -9
View File
@@ -43,8 +43,8 @@
struct BACnet_Application_Data_Value; struct BACnet_Application_Data_Value;
typedef struct BACnet_Application_Data_Value { typedef struct BACnet_Application_Data_Value {
bool context_specific; /* true if context specific data */ bool context_specific; /* true if context specific data */
uint8_t context_tag; /* only used for context specific data */ uint8_t context_tag; /* only used for context specific data */
uint8_t tag; /* application tag data type */ uint8_t tag; /* application tag data type */
union { union {
/* NULL - not needed as it is encoded in the tag alone */ /* NULL - not needed as it is encoded in the tag alone */
@@ -85,13 +85,11 @@ extern "C" {
BACNET_APPLICATION_DATA_VALUE * value, BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property); BACNET_PROPERTY_ID property);
int bacapp_encode_context_data_value(uint8_t * apdu, int bacapp_encode_context_data_value(uint8_t * apdu,
uint8_t context_tag_number, uint8_t context_tag_number, BACNET_APPLICATION_DATA_VALUE * value);
BACNET_APPLICATION_DATA_VALUE * value);
BACNET_APPLICATION_TAG bacapp_context_tag_type(BACNET_PROPERTY_ID
BACNET_APPLICATION_TAG bacapp_context_tag_type( property, uint8_t tag_number);
BACNET_PROPERTY_ID property,
uint8_t tag_number);
bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value, bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
BACNET_APPLICATION_DATA_VALUE * src_value); BACNET_APPLICATION_DATA_VALUE * src_value);
+7 -6
View File
@@ -774,7 +774,7 @@ int encode_tagged_null(uint8_t * apdu)
return encode_tag(&apdu[0], BACNET_APPLICATION_TAG_NULL, false, 0); return encode_tag(&apdu[0], BACNET_APPLICATION_TAG_NULL, false, 0);
} }
int encode_context_null(uint8_t * apdu, int tag_number) int encode_context_null(uint8_t * apdu, int tag_number)
{ {
return encode_tag(&apdu[0], tag_number, true, 0); return encode_tag(&apdu[0], tag_number, true, 0);
} }
@@ -875,14 +875,15 @@ int encode_tagged_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string)
} }
int encode_context_bitstring(uint8_t * apdu, int tag_number, int encode_context_bitstring(uint8_t * apdu, int tag_number,
BACNET_BIT_STRING * bit_string) BACNET_BIT_STRING * bit_string)
{ {
int len = 0; int len = 0;
int bit_string_encoded_length = 1; /* 1 for the bits remaining octet */ int bit_string_encoded_length = 1; /* 1 for the bits remaining octet */
/* bit string may use more than 1 octet for the tag, so find out how many */ /* bit string may use more than 1 octet for the tag, so find out how many */
bit_string_encoded_length += bitstring_bytes_used(bit_string); bit_string_encoded_length += bitstring_bytes_used(bit_string);
len = encode_tag(&apdu[0], tag_number, true, bit_string_encoded_length); len =
encode_tag(&apdu[0], tag_number, true, bit_string_encoded_length);
len += encode_bitstring(&apdu[len], bit_string); len += encode_bitstring(&apdu[len], bit_string);
return len; return len;
@@ -1042,7 +1043,7 @@ int encode_octet_string(uint8_t * apdu, BACNET_OCTET_STRING * octet_string)
{ {
int len = 0; /* return value */ int len = 0; /* return value */
uint8_t *value; uint8_t *value;
int i = 0; /* loop counter */ int i = 0; /* loop counter */
if (octet_string) { if (octet_string) {
/* FIXME: might need to pass in the length of the APDU /* FIXME: might need to pass in the length of the APDU
@@ -1128,7 +1129,7 @@ int encode_bacnet_character_string(uint8_t * apdu,
apdu[0] = characterstring_encoding(char_string); apdu[0] = characterstring_encoding(char_string);
pString = characterstring_value(char_string); pString = characterstring_value(char_string);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
apdu[1+i] = pString[i]; apdu[1 + i] = pString[i];
} }
return len + 1 /* for encoding */ ; return len + 1 /* for encoding */ ;
@@ -1447,7 +1448,7 @@ int encode_tagged_time(uint8_t * apdu, BACNET_TIME * btime)
return len; return len;
} }
int encode_context_time(uint8_t * apdu, int tag_number, int encode_context_time(uint8_t * apdu, int tag_number,
BACNET_TIME * btime) BACNET_TIME * btime)
{ {
int len = 0; /* return value */ int len = 0; /* return value */
+3 -3
View File
@@ -72,7 +72,7 @@ extern "C" {
/* from clause 20.2.2 Encoding of a Null Value */ /* from clause 20.2.2 Encoding of a Null Value */
int encode_tagged_null(uint8_t * apdu); int encode_tagged_null(uint8_t * apdu);
int encode_context_null(uint8_t * apdu, int tag_number); int encode_context_null(uint8_t * apdu, int tag_number);
/* from clause 20.2.3 Encoding of a Boolean Value */ /* from clause 20.2.3 Encoding of a Boolean Value */
int encode_tagged_boolean(uint8_t * apdu, bool boolean_value); int encode_tagged_boolean(uint8_t * apdu, bool boolean_value);
@@ -90,7 +90,7 @@ extern "C" {
int encode_tagged_bitstring(uint8_t * apdu, int encode_tagged_bitstring(uint8_t * apdu,
BACNET_BIT_STRING * bit_string); BACNET_BIT_STRING * bit_string);
int encode_context_bitstring(uint8_t * apdu, int tag_number, int encode_context_bitstring(uint8_t * apdu, int tag_number,
BACNET_BIT_STRING * bit_string); BACNET_BIT_STRING * bit_string);
/* from clause 20.2.6 Encoding of a Real Number Value */ /* from clause 20.2.6 Encoding of a Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* and 20.2.1 General Rules for Encoding BACnet Tags */
@@ -171,7 +171,7 @@ extern "C" {
int encode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime); int encode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime);
int encode_tagged_time(uint8_t * apdu, BACNET_TIME * btime); int encode_tagged_time(uint8_t * apdu, BACNET_TIME * btime);
int decode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime); int decode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime);
int encode_context_time(uint8_t * apdu, int tag_number, int encode_context_time(uint8_t * apdu, int tag_number,
BACNET_TIME * btime); BACNET_TIME * btime);
/* BACnet Date */ /* BACnet Date */
+2 -2
View File
@@ -639,7 +639,7 @@ INDTEXT_DATA bacnet_property_names[] = {
{PROP_REQUESTED_UPDATE_INTERVAL, "requested-update-interval"} {PROP_REQUESTED_UPDATE_INTERVAL, "requested-update-interval"}
, ,
{PROP_RESTART_NOTIFICATION_RECIPIENTS, {PROP_RESTART_NOTIFICATION_RECIPIENTS,
"restart-notification-recipients"} "restart-notification-recipients"}
, ,
{PROP_TIME_OF_DEVICE_RESTART, "time-of-device-restart"} {PROP_TIME_OF_DEVICE_RESTART, "time-of-device-restart"}
, ,
@@ -648,7 +648,7 @@ INDTEXT_DATA bacnet_property_names[] = {
{PROP_TRIGGER, "trigger"} {PROP_TRIGGER, "trigger"}
, ,
{PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS, {PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS,
"UTC-time-synchronization-recipients"} "UTC-time-synchronization-recipients"}
, ,
{PROP_NODE_SUBTYPE, "node-subtype"} {PROP_NODE_SUBTYPE, "node-subtype"}
, ,
+40 -40
View File
@@ -43,13 +43,13 @@
/* year = years since 1900 */ /* year = years since 1900 */
/* month 1=Jan */ /* month 1=Jan */
/* day = day of month 1..31 */ /* day = day of month 1..31 */
/* wday 1=Monday...7=Sunday */ /* wday 1=Monday...7=Sunday */
/* Wildcards: /* Wildcards:
A value of X'FF' in any of the four octets A value of X'FF' in any of the four octets
shall indicate that the value is unspecified. shall indicate that the value is unspecified.
If all four octets = X'FF', the corresponding If all four octets = X'FF', the corresponding
time or date may be interpreted as "any" or "don't care" time or date may be interpreted as "any" or "don't care"
*/ */
static bool is_leap_year(uint16_t year) static bool is_leap_year(uint16_t year)
@@ -115,12 +115,12 @@ static void days_since_epoch_into_ymd(uint32_t days,
year++; year++;
} }
while (days >= (uint32_t)month_days(year, month)) { while (days >= (uint32_t) month_days(year, month)) {
days -= month_days(year, month); days -= month_days(year, month);
month++; month++;
} }
day += ((uint8_t)days); day += ((uint8_t) days);
if (pYear) if (pYear)
*pYear = year; *pYear = year;
@@ -137,7 +137,7 @@ static void days_since_epoch_into_ymd(uint32_t days,
/* wday 1=Monday...7=Sunday */ /* wday 1=Monday...7=Sunday */
static uint8_t day_of_week(uint16_t year, uint8_t month, uint8_t day) static uint8_t day_of_week(uint16_t year, uint8_t month, uint8_t day)
{ {
return ((uint8_t)(days_since_epoch(year, month, day) % 7) + 1); return ((uint8_t) (days_since_epoch(year, month, day) % 7) + 1);
} }
/* if the date1 is the same as date2, return is 0 /* if the date1 is the same as date2, return is 0
@@ -292,9 +292,9 @@ static void seconds_since_midnight_into_hms(uint32_t seconds,
uint8_t hour = 0; uint8_t hour = 0;
uint8_t minute = 0; uint8_t minute = 0;
hour = (uint8_t)(seconds / (60 * 60)); hour = (uint8_t) (seconds / (60 * 60));
seconds -= (hour * 60 * 60); seconds -= (hour * 60 * 60);
minute = (uint8_t)(seconds / 60); minute = (uint8_t) (seconds / 60);
seconds -= (minute * 60); seconds -= (minute * 60);
if (pHours) if (pHours)
@@ -302,7 +302,7 @@ static void seconds_since_midnight_into_hms(uint32_t seconds,
if (pMinutes) if (pMinutes)
*pMinutes = minute; *pMinutes = minute;
if (pSeconds) if (pSeconds)
*pSeconds = (uint8_t)seconds; *pSeconds = (uint8_t) seconds;
} }
void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes) void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes)
@@ -334,29 +334,29 @@ void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes)
bdatetime->date.wday = day_of_week(bdatetime->date.year, bdatetime->date.wday = day_of_week(bdatetime->date.year,
bdatetime->date.month, bdatetime->date.day); bdatetime->date.month, bdatetime->date.day);
} }
bool datetime_wildcard(BACNET_DATE_TIME * bdatetime) bool datetime_wildcard(BACNET_DATE_TIME * bdatetime)
{ {
bool wildcard_present = false; bool wildcard_present = false;
if (bdatetime) { if (bdatetime) {
if ((bdatetime->date.year == (1900 + 0xFF)) && if ((bdatetime->date.year == (1900 + 0xFF)) &&
(bdatetime->date.month == 0xFF) && (bdatetime->date.month == 0xFF) &&
(bdatetime->date.day == 0xFF) && (bdatetime->date.day == 0xFF) &&
(bdatetime->date.wday == 0xFF) && (bdatetime->date.wday == 0xFF) &&
(bdatetime->time.hour == 0xFF) && (bdatetime->time.hour == 0xFF) &&
(bdatetime->time.min == 0xFF) && (bdatetime->time.min == 0xFF) &&
(bdatetime->time.sec == 0xFF) && (bdatetime->time.sec == 0xFF) &&
(bdatetime->time.hundredths == 0xFF)) { (bdatetime->time.hundredths == 0xFF)) {
wildcard_present = true; wildcard_present = true;
} }
} }
return wildcard_present; return wildcard_present;
} }
void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime) void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime)
{ {
if (bdatetime) { if (bdatetime) {
bdatetime->date.year = 1900 + 0xFF; bdatetime->date.year = 1900 + 0xFF;
bdatetime->date.month = 0xFF; bdatetime->date.month = 0xFF;
@@ -367,8 +367,8 @@ void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime)
bdatetime->time.sec = 0xFF; bdatetime->time.sec = 0xFF;
bdatetime->time.hundredths = 0xFF; bdatetime->time.hundredths = 0xFF;
} }
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
@@ -376,19 +376,19 @@ void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime)
#include "ctest.h" #include "ctest.h"
void testBACnetDateTimeWildcard(Test * pTest) void testBACnetDateTimeWildcard(Test * pTest)
{ {
BACNET_DATE_TIME bdatetime; BACNET_DATE_TIME bdatetime;
bool status = false; bool status = false;
datetime_set_values(&bdatetime, 1900, 1, 1, 0, 0, 0, 0); datetime_set_values(&bdatetime, 1900, 1, 1, 0, 0, 0, 0);
status = datetime_wildcard(&bdatetime); status = datetime_wildcard(&bdatetime);
ct_test(pTest, status == false); ct_test(pTest, status == false);
datetime_wildcard_set(&bdatetime); datetime_wildcard_set(&bdatetime);
status = datetime_wildcard(&bdatetime); status = datetime_wildcard(&bdatetime);
ct_test(pTest, status == true); ct_test(pTest, status == true);
} }
void testBACnetDateTimeAdd(Test * pTest) void testBACnetDateTimeAdd(Test * pTest)
{ {
BACNET_DATE_TIME bdatetime, test_bdatetime; BACNET_DATE_TIME bdatetime, test_bdatetime;
@@ -698,9 +698,9 @@ int main(void)
rc = ct_addTestFunction(pTest, testBACnetDateTimeSeconds); rc = ct_addTestFunction(pTest, testBACnetDateTimeSeconds);
assert(rc); assert(rc);
rc = ct_addTestFunction(pTest, testBACnetDateTimeAdd); rc = ct_addTestFunction(pTest, testBACnetDateTimeAdd);
assert(rc); assert(rc);
rc = ct_addTestFunction(pTest, testBACnetDateTimeWildcard); rc = ct_addTestFunction(pTest, testBACnetDateTimeWildcard);
assert(rc); assert(rc);
ct_setStream(pTest, stdout); ct_setStream(pTest, stdout);
ct_run(pTest); ct_run(pTest);
+12 -12
View File
@@ -38,13 +38,13 @@
#include <stdbool.h> #include <stdbool.h>
typedef enum { typedef enum {
BACNET_WEEKDAY_MONDAY = 1, BACNET_WEEKDAY_MONDAY = 1,
BACNET_WEEKDAY_TUESDAY = 2, BACNET_WEEKDAY_TUESDAY = 2,
BACNET_WEEKDAY_WEDNESDAY = 3, BACNET_WEEKDAY_WEDNESDAY = 3,
BACNET_WEEKDAY_THURSDAY = 4, BACNET_WEEKDAY_THURSDAY = 4,
BACNET_WEEKDAY_FRIDAY = 5, BACNET_WEEKDAY_FRIDAY = 5,
BACNET_WEEKDAY_SATURDAY = 6, BACNET_WEEKDAY_SATURDAY = 6,
BACNET_WEEKDAY_SUNDAY = 7 BACNET_WEEKDAY_SUNDAY = 7
} BACNET_WEEKDAY; } BACNET_WEEKDAY;
/* date */ /* date */
@@ -100,12 +100,12 @@ extern "C" {
/* utility add function */ /* utility add function */
void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, void datetime_add_minutes(BACNET_DATE_TIME * bdatetime,
uint32_t minutes); uint32_t minutes);
/* 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);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
+1 -1
View File
@@ -64,7 +64,7 @@ extern "C" {
BACNET_PROPERTY_ID object_property, BACNET_PROPERTY_ID object_property,
BACNET_APPLICATION_DATA_VALUE * object_value, BACNET_APPLICATION_DATA_VALUE * object_value,
uint8_t priority, int32_t array_index); uint8_t priority, int32_t array_index);
/* returns the invoke ID for confirmed request, or 0 if failed */ /* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Reinitialize_Device_Request(uint32_t device_id, uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
BACNET_REINITIALIZED_STATE state, char *password); BACNET_REINITIALIZED_STATE state, char *password);
+122 -122
View File
@@ -1,122 +1,122 @@
/************************************************************************** /**************************************************************************
* *
* 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.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "rp.h" #include "rp.h"
/* demo objects */ /* demo objects */
#include "device.h" #include "device.h"
/* note: this is a minimal handler. See h_rp.c for another */ /* note: this is a minimal handler. See h_rp.c for another */
static uint8_t Temp_Buf[MAX_APDU] = { 0 }; static uint8_t Temp_Buf[MAX_APDU] = { 0 };
void handler_read_property(uint8_t * service_request, void handler_read_property(uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
BACNET_READ_PROPERTY_DATA data; BACNET_READ_PROPERTY_DATA data;
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
bool send = false; bool send = false;
bool error = false; bool error = false;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
len = rp_decode_service_request(service_request, service_len, &data); len = rp_decode_service_request(service_request, service_len, &data);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src,
&my_address, &npdu_data); &my_address, &npdu_data);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
} else if (service_data->segmented_message) { } else if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
} else { } else {
/* most cases will be error */ /* most cases will be error */
error = true; error = true;
switch (data.object_type) { switch (data.object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
/* FIXME: probably need a length limitation sent with encode */ /* FIXME: probably need a length limitation sent with encode */
if (data.object_instance == Device_Object_Instance_Number()) { if (data.object_instance == Device_Object_Instance_Number()) {
len = Device_Encode_Property_APDU(&Temp_Buf[0], len = Device_Encode_Property_APDU(&Temp_Buf[0],
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;
} }
} }
if (error) { if (error) {
switch (len) { switch (len) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is Abort */
case -2: case -2:
len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
break; break;
case -1: case -1:
default: default:
len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code); SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
break; break;
} }
} }
pdu_len += len; pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data, bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len); &Handler_Transmit_Buffer[0], pdu_len);
return; return;
} }
+1 -1
View File
@@ -309,7 +309,7 @@ void handler_write_property(uint8_t * service_request,
#endif #endif
} }
break; break;
#endif /* BACFILE */ #endif /* BACFILE */
default: default:
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
+10 -15
View File
@@ -48,9 +48,8 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID object_property, BACNET_PROPERTY_ID object_property,
uint8_t *application_data, uint8_t * application_data,
int application_data_len, int application_data_len, uint8_t priority, int32_t array_index)
uint8_t priority, int32_t array_index)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
@@ -83,7 +82,8 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
data.object_property = object_property; data.object_property = object_property;
data.array_index = array_index; data.array_index = array_index;
data.application_data_len = application_data_len; data.application_data_len = application_data_len;
memcpy(&data.application_data[0],&application_data[0], application_data_len); memcpy(&data.application_data[0], &application_data[0],
application_data_len);
data.priority = priority; data.priority = priority;
len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, &data); invoke_id, &data);
@@ -126,13 +126,12 @@ uint8_t Send_Write_Property_Request(uint32_t device_id,
BACNET_APPLICATION_DATA_VALUE * object_value, BACNET_APPLICATION_DATA_VALUE * object_value,
uint8_t priority, int32_t array_index) uint8_t priority, int32_t array_index)
{ {
uint8_t application_data[MAX_APDU] = {0}; uint8_t application_data[MAX_APDU] = { 0 };
int apdu_len = 0, len = 0; int apdu_len = 0, len = 0;
while (object_value) { while (object_value) {
len = bacapp_encode_data( len = bacapp_encode_data(&application_data[apdu_len],
&application_data[apdu_len], object_value);
object_value);
if ((len + apdu_len) < MAX_APDU) { if ((len + apdu_len) < MAX_APDU) {
apdu_len += len; apdu_len += len;
} else { } else {
@@ -140,14 +139,10 @@ uint8_t Send_Write_Property_Request(uint32_t device_id,
} }
object_value = object_value->next; object_value = object_value->next;
} }
return Send_Write_Property_Request_Data( return Send_Write_Property_Request_Data(device_id,
device_id,
object_type, object_type,
object_instance, object_instance,
object_property, object_property,
&application_data[0], &application_data[0], apdu_len, priority, array_index);
apdu_len,
priority,
array_index);
} }
+17 -21
View File
@@ -139,9 +139,9 @@ float Analog_Output_Present_Value(uint32_t object_instance)
unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance) unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance)
{ {
unsigned index = 0; /* instance to index conversion */ unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
unsigned priority = 0; /* return value */ unsigned priority = 0; /* return value */
Analog_Output_Init(); Analog_Output_Init();
index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
@@ -157,20 +157,18 @@ unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance)
return priority; return priority;
} }
bool Analog_Output_Present_Value_Set( bool Analog_Output_Present_Value_Set(uint32_t object_instance,
uint32_t object_instance, float value, unsigned priority)
float value,
unsigned priority)
{ {
unsigned index = 0; unsigned index = 0;
bool status = false; bool status = false;
index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_OUTPUTS) { if (index < MAX_ANALOG_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) && (priority != 6 /* reserved */ ) &&
(value >= 0.0) && (value <= 100.0)) { (value >= 0.0) && (value <= 100.0)) {
Analog_Output_Level[index][priority] = (uint8_t)value; Analog_Output_Level[index][priority] = (uint8_t) value;
/* 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.
@@ -180,17 +178,16 @@ bool Analog_Output_Present_Value_Set(
status = true; status = true;
} }
} }
return status; return status;
} }
bool Analog_Output_Present_Value_Relinquish( bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
uint32_t object_instance,
int priority) int priority)
{ {
unsigned index = 0; unsigned index = 0;
bool status = false; bool status = false;
index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_OUTPUTS) { if (index < MAX_ANALOG_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
@@ -205,7 +202,7 @@ bool Analog_Output_Present_Value_Relinquish(
status = true; status = true;
} }
} }
return status; return status;
} }
@@ -366,10 +363,9 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* 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. */
status = Analog_Output_Present_Value_Set( status =
wp_data->object_instance, Analog_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, value.type.Real, wp_data->priority);
wp_data->priority);
if (wp_data->priority == 6) { if (wp_data->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
@@ -384,9 +380,9 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
level = AO_LEVEL_NULL; level = AO_LEVEL_NULL;
object_index = object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance); Analog_Output_Instance_To_Index(wp_data->object_instance);
status = Analog_Output_Present_Value_Relinquish( status =
wp_data->object_instance, Analog_Output_Present_Value_Relinquish(wp_data->
wp_data->priority); object_instance, wp_data->priority);
if (!status) { if (!status) {
*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;
+6 -8
View File
@@ -40,15 +40,13 @@ extern "C" {
uint32_t Analog_Output_Index_To_Instance(unsigned index); uint32_t Analog_Output_Index_To_Instance(unsigned index);
char *Analog_Output_Name(uint32_t object_instance); char *Analog_Output_Name(uint32_t object_instance);
float Analog_Output_Present_Value(uint32_t object_instance); float Analog_Output_Present_Value(uint32_t object_instance);
unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance); unsigned Analog_Output_Present_Value_Priority(uint32_t
bool Analog_Output_Present_Value_Set( object_instance);
uint32_t object_instance, bool Analog_Output_Present_Value_Set(uint32_t object_instance,
float value, float value, unsigned priority);
unsigned priority); bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
bool Analog_Output_Present_Value_Relinquish(
uint32_t object_instance,
int priority); int priority);
int Analog_Output_Encode_Property_APDU(uint8_t * apdu, int Analog_Output_Encode_Property_APDU(uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
+137 -128
View File
@@ -143,7 +143,7 @@ void Load_Control_Init(void)
Shed_Duration[i] = 0; Shed_Duration[i] = 0;
Duty_Window[i] = 0; Duty_Window[i] = 0;
Load_Control_Enable[i] = true; Load_Control_Enable[i] = true;
Full_Duty_Baseline[i] = 1.500; /* kilowatts */ Full_Duty_Baseline[i] = 1.500; /* kilowatts */
for (j = 0; j < MAX_SHED_LEVELS; j++) { for (j = 0; j < MAX_SHED_LEVELS; j++) {
/* FIXME: fake data for lighting application */ /* FIXME: fake data for lighting application */
/* The array shall be ordered by increasing shed amount. */ /* The array shall be ordered by increasing shed amount. */
@@ -254,12 +254,11 @@ struct tm {
timer = time(NULL); timer = time(NULL);
tblock = localtime(&timer); tblock = localtime(&timer);
datetime_set_values(bdatetime, datetime_set_values(bdatetime,
(uint16_t)tblock->tm_year, (uint16_t) tblock->tm_year,
(uint8_t)tblock->tm_mon, (uint8_t) tblock->tm_mon,
(uint8_t)tblock->tm_mday, (uint8_t) tblock->tm_mday,
(uint8_t)tblock->tm_hour, (uint8_t) tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t) tblock->tm_min, (uint8_t) tblock->tm_sec, 0);
(uint8_t)tblock->tm_sec, 0);
} }
/* convert the shed level request into an Analog Output Present_Value */ /* convert the shed level request into an Analog Output Present_Value */
@@ -270,62 +269,68 @@ static float Requested_Shed_Level_Value(int object_index)
float requested_level = 0.0; float requested_level = 0.0;
switch (Requested_Shed_Level[object_index].type) { switch (Requested_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
requested_level = (float)Requested_Shed_Level[object_index].value.percent; requested_level =
break; (float) Requested_Shed_Level[object_index].value.percent;
case BACNET_SHED_TYPE_AMOUNT: break;
/* Assumptions: wattage is linear with analog output level */ case BACNET_SHED_TYPE_AMOUNT:
requested_level = Full_Duty_Baseline[object_index] - Requested_Shed_Level[object_index].value.amount; /* Assumptions: wattage is linear with analog output level */
requested_level /= Full_Duty_Baseline[object_index]; requested_level =
requested_level *= 100.0; Full_Duty_Baseline[object_index] -
break; Requested_Shed_Level[object_index].value.amount;
case BACNET_SHED_TYPE_LEVEL: requested_level /= Full_Duty_Baseline[object_index];
default: requested_level *= 100.0;
for (i = 0; i < MAX_SHED_LEVELS; i++) { break;
if (Shed_Levels[object_index][i] <= Requested_Shed_Level[object_index].value.level) case BACNET_SHED_TYPE_LEVEL:
shed_level_index = i; default:
} for (i = 0; i < MAX_SHED_LEVELS; i++) {
requested_level = Shed_Level_Values[shed_level_index]; if (Shed_Levels[object_index][i] <=
break; Requested_Shed_Level[object_index].value.level)
shed_level_index = i;
}
requested_level = Shed_Level_Values[shed_level_index];
break;
} }
return requested_level; return requested_level;
} }
static void Shed_Level_Copy(BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL *src) static void Shed_Level_Copy(BACNET_SHED_LEVEL * dest,
BACNET_SHED_LEVEL * src)
{ {
if (dest && src) { if (dest && src) {
dest->type = src->type; dest->type = src->type;
switch (src->type) { switch (src->type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
dest->value.percent = src->value.percent; dest->value.percent = src->value.percent;
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
dest->value.amount = src->value.amount; dest->value.amount = src->value.amount;
break; break;
case BACNET_SHED_TYPE_LEVEL: case BACNET_SHED_TYPE_LEVEL:
default: default:
dest->value.level = src->value.level; dest->value.level = src->value.level;
break; break;
} }
} }
} }
static void Shed_Level_Default_Set(BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL_TYPE type) static void Shed_Level_Default_Set(BACNET_SHED_LEVEL * dest,
BACNET_SHED_LEVEL_TYPE type)
{ {
if (dest) { if (dest) {
dest->type = type; dest->type = type;
switch (type) { switch (type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
dest->value.percent = 100; dest->value.percent = 100;
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
dest->value.amount = 0.0; dest->value.amount = 0.0;
break; break;
case BACNET_SHED_TYPE_LEVEL: case BACNET_SHED_TYPE_LEVEL:
default: default:
dest->value.level = 0; dest->value.level = 0;
break; break;
} }
} }
} }
@@ -337,7 +342,7 @@ static bool Able_To_Meet_Shed_Request(int object_index)
unsigned priority = 0; unsigned priority = 0;
bool status = false; bool status = false;
int object_instance = 0; int object_instance = 0;
/* This demo is going to use the Analog Outputs as their Load */ /* This demo is going to use the Analog Outputs as their Load */
object_instance = object_index; object_instance = object_index;
priority = Analog_Output_Present_Value_Priority(object_instance); priority = Analog_Output_Present_Value_Priority(object_instance);
@@ -350,8 +355,8 @@ static bool Able_To_Meet_Shed_Request(int object_index)
status = true; status = true;
} }
} }
return status; return status;
} }
typedef enum load_control_state { typedef enum load_control_state {
@@ -367,15 +372,15 @@ static LOAD_CONTROL_STATE Load_Control_State_Previously[MAX_LOAD_CONTROLS];
static void Print_Load_Control_State(int object_index) static void Print_Load_Control_State(int object_index)
{ {
char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = { char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = {
"SHED_INACTIVE", "SHED_INACTIVE",
"SHED_REQUEST_PENDING", "SHED_REQUEST_PENDING",
"SHED_NON_COMPLIANT", "SHED_NON_COMPLIANT",
"SHED_COMPLIANT" "SHED_COMPLIANT"
}; };
if (object_index < MAX_LOAD_CONTROLS) { if (object_index < MAX_LOAD_CONTROLS) {
if (Load_Control_State[object_index] < MAX_LOAD_CONTROL_STATE) { if (Load_Control_State[object_index] < MAX_LOAD_CONTROL_STATE) {
printf("Load Control[%d]=%s\n",object_index, printf("Load Control[%d]=%s\n", object_index,
Load_Control_State_Text[Load_Control_State[object_index]]); Load_Control_State_Text[Load_Control_State[object_index]]);
} }
} }
@@ -387,42 +392,43 @@ void Load_Control_State_Machine(int object_index)
int diff = 0; /* used for datetime comparison */ int diff = 0; /* used for datetime comparison */
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? */
switch (Requested_Shed_Level[object_index].type) { switch (Requested_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
if (Requested_Shed_Level[object_index].value.percent == if (Requested_Shed_Level[object_index].value.percent ==
DEFAULT_VALUE_PERCENT) DEFAULT_VALUE_PERCENT)
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
if (Requested_Shed_Level[object_index].value.amount == if (Requested_Shed_Level[object_index].value.amount ==
DEFAULT_VALUE_AMOUNT) DEFAULT_VALUE_AMOUNT)
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
case BACNET_SHED_TYPE_LEVEL: case BACNET_SHED_TYPE_LEVEL:
default: default:
if (Requested_Shed_Level[object_index].value.level == if (Requested_Shed_Level[object_index].value.level ==
DEFAULT_VALUE_LEVEL) DEFAULT_VALUE_LEVEL)
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
} }
if (Load_Control_State[object_index] == SHED_INACTIVE) { if (Load_Control_State[object_index] == SHED_INACTIVE) {
printf("Load Control[%d]:Requested Shed Level=Default\n",object_index); printf("Load Control[%d]:Requested Shed Level=Default\n",
break; object_index);
break;
} }
} }
if (Start_Time_Property_Written[object_index]) { if (Start_Time_Property_Written[object_index]) {
Start_Time_Property_Written[object_index] = false; Start_Time_Property_Written[object_index] = false;
/* request to cancel using wildcards in start time? */ /* request to cancel using wildcards in start time? */
if (datetime_wildcard(&Start_Time[object_index])) { if (datetime_wildcard(&Start_Time[object_index])) {
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
} }
} }
/* cancel because current time is after start time + duration? */ /* cancel because current time is after start time + duration? */
Update_Current_Time(&Current_Time); Update_Current_Time(&Current_Time);
datetime_copy(&End_Time[object_index], &Start_Time[object_index]); datetime_copy(&End_Time[object_index], &Start_Time[object_index]);
datetime_add_minutes(&End_Time[object_index], datetime_add_minutes(&End_Time[object_index],
@@ -431,7 +437,9 @@ void Load_Control_State_Machine(int object_index)
if (diff < 0) { if (diff < 0) {
/* CancelShed */ /* CancelShed */
/* FIXME: stop shedding! i.e. relinquish */ /* FIXME: stop shedding! i.e. relinquish */
printf("Load Control[%d]:Current Time is after Start Time + Duration\n",object_index); printf
("Load Control[%d]:Current Time is after Start Time + Duration\n",
object_index);
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
} }
@@ -439,33 +447,28 @@ void Load_Control_State_Machine(int object_index)
if (diff < 0) { if (diff < 0) {
/* current time prior to start time */ /* current time prior to start time */
/* ReconfigurePending */ /* ReconfigurePending */
Shed_Level_Copy( Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Shed_Level_Default_Set( Shed_Level_Default_Set(&Actual_Shed_Level[object_index],
&Actual_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
} else if (diff > 0) { } else if (diff > 0) {
/* current time after to start time */ /* current time after to start time */
printf("Load Control[%d]:Current Time is after Start Time\n",object_index); printf("Load Control[%d]:Current Time is after Start Time\n",
object_index);
/* AbleToMeetShed */ /* AbleToMeetShed */
if (Able_To_Meet_Shed_Request(object_index)) { if (Able_To_Meet_Shed_Request(object_index)) {
Shed_Level_Copy( Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Analog_Output_Present_Value_Set(object_index, Analog_Output_Present_Value_Set(object_index,
Requested_Shed_Level_Value(object_index), 4); Requested_Shed_Level_Value(object_index), 4);
Shed_Level_Copy( Shed_Level_Copy(&Actual_Shed_Level[object_index],
&Actual_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Load_Control_State[object_index] = SHED_COMPLIANT; Load_Control_State[object_index] = SHED_COMPLIANT;
} else { } else {
/* CannotMeetShed */ /* CannotMeetShed */
Shed_Level_Default_Set( Shed_Level_Default_Set(&Expected_Shed_Level[object_index],
&Expected_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Shed_Level_Default_Set( Shed_Level_Default_Set(&Actual_Shed_Level[object_index],
&Actual_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Load_Control_State[object_index] = SHED_NON_COMPLIANT; Load_Control_State[object_index] = SHED_NON_COMPLIANT;
} }
@@ -479,14 +482,17 @@ void Load_Control_State_Machine(int object_index)
diff = datetime_compare(&End_Time[object_index], &Current_Time); diff = datetime_compare(&End_Time[object_index], &Current_Time);
if (diff < 0) { if (diff < 0) {
/* FinishedUnsuccessfulShed */ /* FinishedUnsuccessfulShed */
printf("Load Control[%d]:Current Time is after Start Time + Duration\n",object_index); printf
("Load Control[%d]:Current Time is after Start Time + Duration\n",
object_index);
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
} }
if (Load_Control_Request_Written[object_index] || if (Load_Control_Request_Written[object_index] ||
Start_Time_Property_Written[object_index]) { Start_Time_Property_Written[object_index]) {
/* UnsuccessfulShedReconfigured */ /* UnsuccessfulShedReconfigured */
printf("Load Control[%d]:Control Property written\n",object_index); printf("Load Control[%d]:Control Property written\n",
object_index);
Load_Control_Request_Written[object_index] = false; Load_Control_Request_Written[object_index] = false;
Start_Time_Property_Written[object_index] = false; Start_Time_Property_Written[object_index] = false;
Load_Control_State[object_index] = SHED_REQUEST_PENDING; Load_Control_State[object_index] = SHED_REQUEST_PENDING;
@@ -494,14 +500,13 @@ void Load_Control_State_Machine(int object_index)
} }
if (Able_To_Meet_Shed_Request(object_index)) { if (Able_To_Meet_Shed_Request(object_index)) {
/* CanNowComplyWithShed */ /* CanNowComplyWithShed */
printf("Load Control[%d]:Able to meet Shed Request\n",object_index); printf("Load Control[%d]:Able to meet Shed Request\n",
Shed_Level_Copy( object_index);
&Expected_Shed_Level[object_index], Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Analog_Output_Present_Value_Set(object_index, Analog_Output_Present_Value_Set(object_index,
Requested_Shed_Level_Value(object_index), 4); Requested_Shed_Level_Value(object_index), 4);
Shed_Level_Copy( Shed_Level_Copy(&Actual_Shed_Level[object_index],
&Actual_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Load_Control_State[object_index] = SHED_COMPLIANT; Load_Control_State[object_index] = SHED_COMPLIANT;
} }
@@ -514,15 +519,18 @@ void Load_Control_State_Machine(int object_index)
diff = datetime_compare(&End_Time[object_index], &Current_Time); diff = datetime_compare(&End_Time[object_index], &Current_Time);
if (diff < 0) { if (diff < 0) {
/* FinishedSuccessfulShed */ /* FinishedSuccessfulShed */
printf("Load Control[%d]:Current Time is after Start Time + Duration\n",object_index); printf
("Load Control[%d]:Current Time is after Start Time + Duration\n",
object_index);
datetime_wildcard_set(&Start_Time[i]); datetime_wildcard_set(&Start_Time[i]);
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
} }
if (Load_Control_Request_Written[object_index] || if (Load_Control_Request_Written[object_index] ||
Start_Time_Property_Written[object_index]) { Start_Time_Property_Written[object_index]) {
/* UnsuccessfulShedReconfigured */ /* UnsuccessfulShedReconfigured */
printf("Load Control[%d]:Control Property written\n",object_index); printf("Load Control[%d]:Control Property written\n",
object_index);
Load_Control_Request_Written[object_index] = false; Load_Control_Request_Written[object_index] = false;
Start_Time_Property_Written[object_index] = false; Start_Time_Property_Written[object_index] = false;
Load_Control_State[object_index] = SHED_REQUEST_PENDING; Load_Control_State[object_index] = SHED_REQUEST_PENDING;
@@ -530,12 +538,11 @@ void Load_Control_State_Machine(int object_index)
} }
if (!Able_To_Meet_Shed_Request(object_index)) { if (!Able_To_Meet_Shed_Request(object_index)) {
/* CanNoLongerComplyWithShed */ /* CanNoLongerComplyWithShed */
printf("Load Control[%d]:Not able to meet Shed Request\n",object_index); printf("Load Control[%d]:Not able to meet Shed Request\n",
Shed_Level_Default_Set( object_index);
&Expected_Shed_Level[object_index], Shed_Level_Default_Set(&Expected_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Shed_Level_Default_Set( Shed_Level_Default_Set(&Actual_Shed_Level[object_index],
&Actual_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Load_Control_State[object_index] = SHED_NON_COMPLIANT; Load_Control_State[object_index] = SHED_NON_COMPLIANT;
} }
@@ -543,13 +550,11 @@ void Load_Control_State_Machine(int object_index)
case SHED_INACTIVE: case SHED_INACTIVE:
default: default:
if (Start_Time_Property_Written[object_index]) { if (Start_Time_Property_Written[object_index]) {
printf("Load Control[%d]:Start Time written\n",object_index); printf("Load Control[%d]:Start Time written\n", object_index);
Start_Time_Property_Written[object_index] = false; Start_Time_Property_Written[object_index] = false;
Shed_Level_Copy( Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Shed_Level_Default_Set( Shed_Level_Default_Set(&Actual_Shed_Level[object_index],
&Actual_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Load_Control_State[object_index] = SHED_REQUEST_PENDING; Load_Control_State[object_index] = SHED_REQUEST_PENDING;
} }
@@ -829,19 +834,22 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
&value, PROP_REQUESTED_SHED_LEVEL); &value, PROP_REQUESTED_SHED_LEVEL);
if (value.tag == 0) { if (value.tag == 0) {
/* percent - Unsigned */ /* percent - Unsigned */
Requested_Shed_Level[object_index].type = BACNET_SHED_TYPE_PERCENT; Requested_Shed_Level[object_index].type =
BACNET_SHED_TYPE_PERCENT;
Requested_Shed_Level[object_index].value.percent = Requested_Shed_Level[object_index].value.percent =
value.type.Unsigned_Int; value.type.Unsigned_Int;
status = true; status = true;
} else if (value.tag == 1) { } else if (value.tag == 1) {
/* level - Unsigned */ /* level - Unsigned */
Requested_Shed_Level[object_index].type = BACNET_SHED_TYPE_LEVEL; Requested_Shed_Level[object_index].type =
BACNET_SHED_TYPE_LEVEL;
Requested_Shed_Level[object_index].value.level = Requested_Shed_Level[object_index].value.level =
value.type.Unsigned_Int; value.type.Unsigned_Int;
status = true; status = true;
} else if (value.tag == 2) { } else if (value.tag == 2) {
/* amount - REAL */ /* amount - REAL */
Requested_Shed_Level[object_index].type = BACNET_SHED_TYPE_AMOUNT; Requested_Shed_Level[object_index].type =
BACNET_SHED_TYPE_AMOUNT;
Requested_Shed_Level[object_index].value.amount = Requested_Shed_Level[object_index].value.amount =
value.type.Real; value.type.Real;
status = true; status = true;
@@ -966,8 +974,9 @@ void testLoadControlStateMachine(Test * pTest)
} }
} }
/**/ /**/
status = Load_Control_Write_Property(&wp_data, &error_class, &error_code); status =
Load_Control_Write_Property(&wp_data, &error_class, &error_code);
+1 -1
View File
@@ -34,7 +34,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void Load_Control_State_Machine_Handler(void); void Load_Control_State_Machine_Handler(void);
bool Load_Control_Valid_Instance(uint32_t object_instance); bool Load_Control_Valid_Instance(uint32_t object_instance);
+376 -375
View File
@@ -1,375 +1,376 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2006-2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006-2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* command line tool that sends a BACnet service, and displays the response */ /* command line tool that sends a BACnet service, and displays the response */
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> /* for time */ #include <time.h> /* for time */
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h> /* toupper */ #include <ctype.h> /* toupper */
#include "bactext.h" #include "bactext.h"
#include "iam.h" #include "iam.h"
#include "arf.h" #include "arf.h"
#include "tsm.h" #include "tsm.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 "net.h" #include "net.h"
#include "datalink.h" #include "datalink.h"
#include "whois.h" #include "whois.h"
/* some demo stuff needed */ /* some demo stuff needed */
#include "filename.h" #include "filename.h"
#include "handlers.h" #include "handlers.h"
#include "client.h" #include "client.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 };
/* global variables used in this file */ /* global variables used in this file */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
static uint32_t Target_Object_Instance = BACNET_MAX_INSTANCE; static uint32_t Target_Object_Instance = BACNET_MAX_INSTANCE;
static BACNET_OBJECT_TYPE Target_Object_Type = OBJECT_ANALOG_INPUT; static BACNET_OBJECT_TYPE Target_Object_Type = OBJECT_ANALOG_INPUT;
static BACNET_PROPERTY_ID Target_Object_Property = PROP_ACKED_TRANSITIONS; static BACNET_PROPERTY_ID Target_Object_Property = PROP_ACKED_TRANSITIONS;
/* array index value or BACNET_ARRAY_ALL */ /* array index value or BACNET_ARRAY_ALL */
static int32_t Target_Object_Property_Index = BACNET_ARRAY_ALL; static int32_t Target_Object_Property_Index = BACNET_ARRAY_ALL;
#define MAX_PROPERTY_VALUES 16 #define MAX_PROPERTY_VALUES 16
static BACNET_APPLICATION_DATA_VALUE Target_Object_Property_Value[MAX_PROPERTY_VALUES]; static BACNET_APPLICATION_DATA_VALUE
Target_Object_Property_Value[MAX_PROPERTY_VALUES];
/* 0 if not set, 1..16 if set */
static uint8_t Target_Object_Property_Priority = 0; /* 0 if not set, 1..16 if set */
static uint8_t Target_Object_Property_Priority = 0;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false; static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, static void MyErrorHandler(BACNET_ADDRESS * src,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code) uint8_t invoke_id,
{ BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
/* FIXME: verify src and invoke id */ {
(void) src; /* FIXME: verify src and invoke id */
(void) invoke_id; (void) src;
printf("\r\nBACnet Error!\r\n"); (void) invoke_id;
printf("Error Class: %s\r\n", bactext_error_class_name(error_class)); printf("\r\nBACnet Error!\r\n");
printf("Error Code: %s\r\n", bactext_error_code_name(error_code)); printf("Error Class: %s\r\n", bactext_error_class_name(error_class));
Error_Detected = true; printf("Error Code: %s\r\n", bactext_error_code_name(error_code));
} Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server) void MyAbortHandler(BACNET_ADDRESS * src,
{ uint8_t invoke_id, uint8_t abort_reason, bool server)
/* FIXME: verify src and invoke id */ {
(void) src; /* FIXME: verify src and invoke id */
(void) invoke_id; (void) src;
(void) server; (void) invoke_id;
printf("\r\nBACnet Abort!\r\n"); (void) server;
printf("Abort Reason: %s\r\n", printf("\r\nBACnet Abort!\r\n");
bactext_abort_reason_name(abort_reason)); printf("Abort Reason: %s\r\n",
Error_Detected = true; bactext_abort_reason_name(abort_reason));
} Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason) void MyRejectHandler(BACNET_ADDRESS * src,
{ uint8_t invoke_id, uint8_t reject_reason)
/* FIXME: verify src and invoke id */ {
(void) src; /* FIXME: verify src and invoke id */
(void) invoke_id; (void) src;
printf("\r\nBACnet Reject!\r\n"); (void) invoke_id;
printf("Reject Reason: %s\r\n", printf("\r\nBACnet Reject!\r\n");
bactext_reject_reason_name(reject_reason)); printf("Reject Reason: %s\r\n",
Error_Detected = true; bactext_reject_reason_name(reject_reason));
} Error_Detected = true;
}
void MyWritePropertySimpleAckHandler(BACNET_ADDRESS * src,
uint8_t invoke_id) void MyWritePropertySimpleAckHandler(BACNET_ADDRESS * src,
{ uint8_t invoke_id)
(void) src; {
(void) invoke_id; (void) src;
printf("\r\nWriteProperty Acknowledged!\r\n"); (void) invoke_id;
} printf("\r\nWriteProperty Acknowledged!\r\n");
}
static void Init_Service_Handlers(void)
{ static void Init_Service_Handlers(void)
/* we need to handle who-is {
to support dynamic device binding to us */ /* we need to handle who-is
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, to support dynamic device binding to us */
handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
/* handle i-am to support binding to other devices */ handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, /* handle i-am to support binding to other devices */
handler_i_am_bind); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
/* set the handler for all the services we don't implement handler_i_am_bind);
It is required to send the proper reject message... */ /* set the handler for all the services we don't implement
apdu_set_unrecognized_service_handler_handler It is required to send the proper reject message... */
(handler_unrecognized_service); apdu_set_unrecognized_service_handler_handler
/* we must implement read property - it's required! */ (handler_unrecognized_service);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, /* we must implement read property - it's required! */
handler_read_property); apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
/* handle the ack coming back */ handler_read_property);
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, /* handle the ack coming back */
MyWritePropertySimpleAckHandler); apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
/* handle any errors coming back */ MyWritePropertySimpleAckHandler);
apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, /* handle any errors coming back */
MyErrorHandler); apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
apdu_set_abort_handler(MyAbortHandler); MyErrorHandler);
apdu_set_reject_handler(MyRejectHandler); apdu_set_abort_handler(MyAbortHandler);
} apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
{ int main(int argc, char *argv[])
BACNET_ADDRESS src = { 0 }; /* address where message came from */ {
uint16_t pdu_len = 0; BACNET_ADDRESS src = { 0 }; /* address where message came from */
unsigned timeout = 100; /* milliseconds */ uint16_t pdu_len = 0;
unsigned max_apdu = 0; unsigned timeout = 100; /* milliseconds */
time_t elapsed_seconds = 0; unsigned max_apdu = 0;
time_t last_seconds = 0; time_t elapsed_seconds = 0;
time_t current_seconds = 0; time_t last_seconds = 0;
time_t timeout_seconds = 0; time_t current_seconds = 0;
uint8_t invoke_id = 0; time_t timeout_seconds = 0;
bool found = false; uint8_t invoke_id = 0;
char *value_string = NULL; bool found = false;
bool status = false; char *value_string = NULL;
int args_remaining = 0, tag_value_arg = 0, i = 0; bool status = false;
BACNET_APPLICATION_TAG property_tag; int args_remaining = 0, tag_value_arg = 0, i = 0;
uint8_t context_tag = 0; BACNET_APPLICATION_TAG property_tag;
uint8_t context_tag = 0;
if (argc < 9) {
/* note: priority 16 and 0 should produce the same end results... */ if (argc < 9) {
printf("Usage: %s device-instance object-type object-instance " /* note: priority 16 and 0 should produce the same end results... */
"property priority index tag value [tag value...]\r\n", printf("Usage: %s device-instance object-type object-instance "
filename_remove_path(argv[0])); "property priority index tag value [tag value...]\r\n",
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { filename_remove_path(argv[0]));
printf("device-instance:\r\n" if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
"BACnet Device Object Instance number that you are trying to\r\n" printf("device-instance:\r\n"
"communicate to. This number will be used to try and bind with\r\n" "BACnet Device Object Instance number that you are trying to\r\n"
"the device using Who-Is and I-Am services. For example, if you were\r\n" "communicate to. This number will be used to try and bind with\r\n"
"writing to Device Object 123, the device-instance would be 123.\r\n" "the device using Who-Is and I-Am services. For example, if you were\r\n"
"\r\n" "writing to Device Object 123, the device-instance would be 123.\r\n"
"object-type:\r\n" "\r\n"
"The object type is the integer value of the enumeration\r\n" "object-type:\r\n"
"BACNET_OBJECT_TYPE in bacenum.h. It is the object that you are\r\n" "The object type is the integer value of the enumeration\r\n"
"writing to. For example if you were writing to Analog Output 2, \r\n" "BACNET_OBJECT_TYPE in bacenum.h. It is the object that you are\r\n"
"the object-type would be 1.\r\n" "writing to. For example if you were writing to Analog Output 2, \r\n"
"\r\n" "the object-type would be 1.\r\n"
"object-instance:\r\n" "\r\n"
"This is the object instance number of the object that you are \r\n" "object-instance:\r\n"
"writing to. For example, if you were writing to Analog Output 2, \r\n" "This is the object instance number of the object that you are \r\n"
"the object-instance would be 2.\r\n" "writing to. For example, if you were writing to Analog Output 2, \r\n"
"\r\n" "the object-instance would be 2.\r\n"
"property:\r\n" "\r\n"
"The property is an integer value of the enumeration \r\n" "property:\r\n"
"BACNET_PROPERTY_ID in bacenum.h. It is the property you are \r\n" "The property is an integer value of the enumeration \r\n"
"writing to. For example, if you were writing to the Present Value\r\n" "BACNET_PROPERTY_ID in bacenum.h. It is the property you are \r\n"
"property, you would use 85 as the property.\r\n" "writing to. For example, if you were writing to the Present Value\r\n"
"\r\n" "property, you would use 85 as the property.\r\n"
"priority:\r\n" "\r\n"
"This parameter is used for setting the priority of the\r\n" "priority:\r\n"
"write. If Priority 0 is given, no priority is sent. The BACnet \r\n" "This parameter is used for setting the priority of the\r\n"
"standard states that the value is written at the lowest \r\n" "write. If Priority 0 is given, no priority is sent. The BACnet \r\n"
"priority (16) if the object property supports priorities\r\n" "standard states that the value is written at the lowest \r\n"
"when no priority is sent.\r\n" "priority (16) if the object property supports priorities\r\n"
"\r\n" "when no priority is sent.\r\n"
"index\r\n" "\r\n"
"This integer parameter is the index number of an array.\r\n" "index\r\n"
"If the property is an array, individual elements can be written\r\n" "This integer parameter is the index number of an array.\r\n"
"to if supported. If this parameter is -1, the index is ignored.\r\n" "If the property is an array, individual elements can be written\r\n"
"\r\n" "to if supported. If this parameter is -1, the index is ignored.\r\n"
"tag:\r\n" "\r\n"
"Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \r\n" "tag:\r\n"
"in bacenum.h. It is the data type of the value that you are\r\n" "Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \r\n"
"writing. For example, if you were writing a REAL value, you would \r\n" "in bacenum.h. It is the data type of the value that you are\r\n"
"use a tag of 4.\r\n" "writing. For example, if you were writing a REAL value, you would \r\n"
"Context tags are created using two tags in a row. The context tag\r\n" "use a tag of 4.\r\n"
"is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged REAL.\r\n" "Context tags are created using two tags in a row. The context tag\r\n"
"\r\n" "is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged REAL.\r\n"
"value:\r\n" "\r\n"
"The value is an ASCII representation of some type of data that you\r\n" "value:\r\n"
"are writing. It is encoded using the tag information provided. For\r\n" "The value is an ASCII representation of some type of data that you\r\n"
"example, if you were writing a REAL value of 100.0, you would use \r\n" "are writing. It is encoded using the tag information provided. For\r\n"
"100.0 as the value.\r\n" "example, if you were writing a REAL value of 100.0, you would use \r\n"
"\r\n" "100.0 as the value.\r\n"
"Here is a brief overview of BACnet property and tags:\r\n" "\r\n"
"Certain properties are expected to be written with certain \r\n" "Here is a brief overview of BACnet property and tags:\r\n"
"application tags, so you probably need to know which ones to use\r\n" "Certain properties are expected to be written with certain \r\n"
"with each property of each object. It is almost safe to say that\r\n" "application tags, so you probably need to know which ones to use\r\n"
"given a property and an object and a table, the tag could be looked\r\n" "with each property of each object. It is almost safe to say that\r\n"
"up automatically. There may be a few exceptions to this, such as\r\n" "given a property and an object and a table, the tag could be looked\r\n"
"the Any property type in the schedule object and the Present Value\r\n" "up automatically. There may be a few exceptions to this, such as\r\n"
"accepting REAL, BOOLEAN, NULL, etc. Perhaps it would be simpler for\r\n" "the Any property type in the schedule object and the Present Value\r\n"
"the demo to use this kind of table - but I also wanted to be able\r\n" "accepting REAL, BOOLEAN, NULL, etc. Perhaps it would be simpler for\r\n"
"to do negative testing by passing the wrong tag and have the server\r\n" "the demo to use this kind of table - but I also wanted to be able\r\n"
"return a reject message.\r\n" "to do negative testing by passing the wrong tag and have the server\r\n"
"\r\n" "return a reject message.\r\n"
"Example:\r\n" "\r\n"
"If you want send a 100 to the Present-Value in the Analog Output\r\n" "Example:\r\n"
"at priority 16, you could send the following command:\r\n" "If you want send a 100 to the Present-Value in the Analog Output\r\n"
"%s 123 1 0 85 4 100\r\n" "at priority 16, you could send the following command:\r\n"
"You could also send a relinquish command:\r\n" "%s 123 1 0 85 4 100\r\n"
"%s 123 1 0 85 0 0\r\n", "You could also send a relinquish command:\r\n"
filename_remove_path(argv[0]), "%s 123 1 0 85 0 0\r\n",
filename_remove_path(argv[0])); filename_remove_path(argv[0]),
} filename_remove_path(argv[0]));
return 0; }
} return 0;
/* decode the command line parameters */ }
Target_Device_Object_Instance = strtol(argv[1], NULL, 0); /* decode the command line parameters */
Target_Object_Type = strtol(argv[2], NULL, 0); Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
Target_Object_Instance = strtol(argv[3], NULL, 0); Target_Object_Type = strtol(argv[2], NULL, 0);
Target_Object_Property = strtol(argv[4], NULL, 0); Target_Object_Instance = strtol(argv[3], NULL, 0);
Target_Object_Property_Priority = strtol(argv[5], NULL, 0); Target_Object_Property = strtol(argv[4], NULL, 0);
Target_Object_Property_Index = strtol(argv[6], NULL, 0); Target_Object_Property_Priority = strtol(argv[5], NULL, 0);
if (Target_Object_Property_Index == -1) Target_Object_Property_Index = strtol(argv[6], NULL, 0);
Target_Object_Property_Index = BACNET_ARRAY_ALL; if (Target_Object_Property_Index == -1)
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { Target_Object_Property_Index = BACNET_ARRAY_ALL;
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
return 1; Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1);
} return 1;
if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) { }
fprintf(stderr, "object-type=%u - it must be less than %u\r\n", if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) {
Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1); fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
return 1; Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1);
} return 1;
if (Target_Object_Instance > BACNET_MAX_INSTANCE) { }
fprintf(stderr, "object-instance=%u - it must be less than %u\r\n", if (Target_Object_Instance > BACNET_MAX_INSTANCE) {
Target_Object_Instance, BACNET_MAX_INSTANCE + 1); fprintf(stderr, "object-instance=%u - it must be less than %u\r\n",
return 1; Target_Object_Instance, BACNET_MAX_INSTANCE + 1);
} return 1;
if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) { }
fprintf(stderr, "object-type=%u - it must be less than %u\r\n", if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) {
Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1); fprintf(stderr, "object-type=%u - it must be less than %u\r\n",
return 1; Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1);
} return 1;
args_remaining = (argc - 7); }
for (i = 0; i < MAX_PROPERTY_VALUES; i++) { args_remaining = (argc - 7);
tag_value_arg = 7+(i*2); for (i = 0; i < MAX_PROPERTY_VALUES; i++) {
/* special case for context tagged values */ tag_value_arg = 7 + (i * 2);
if (toupper(argv[tag_value_arg][0]) == 'C') { /* special case for context tagged values */
context_tag = strtol(&argv[tag_value_arg][1], NULL, 0); if (toupper(argv[tag_value_arg][0]) == 'C') {
tag_value_arg++; context_tag = strtol(&argv[tag_value_arg][1], NULL, 0);
args_remaining--; tag_value_arg++;
Target_Object_Property_Value[i].context_tag = context_tag; args_remaining--;
Target_Object_Property_Value[i].context_specific = true; Target_Object_Property_Value[i].context_tag = context_tag;
} else { Target_Object_Property_Value[i].context_specific = true;
Target_Object_Property_Value[i].context_specific = false; } else {
} Target_Object_Property_Value[i].context_specific = false;
property_tag = strtol(argv[tag_value_arg], NULL, 0); }
value_string = argv[tag_value_arg+1]; property_tag = strtol(argv[tag_value_arg], NULL, 0);
args_remaining -= 2; value_string = argv[tag_value_arg + 1];
/* printf("tag[%d]=%u value[%d]=%s\r\n", args_remaining -= 2;
i, property_tag, i, value_string); */ /* printf("tag[%d]=%u value[%d]=%s\r\n",
if (property_tag >= MAX_BACNET_APPLICATION_TAG) { i, property_tag, i, value_string); */
fprintf(stderr, "tag=%u - it must be less than %u\r\n", if (property_tag >= MAX_BACNET_APPLICATION_TAG) {
property_tag, MAX_BACNET_APPLICATION_TAG); fprintf(stderr, "tag=%u - it must be less than %u\r\n",
return 1; property_tag, MAX_BACNET_APPLICATION_TAG);
} return 1;
status = bacapp_parse_application_data(property_tag, }
value_string, &Target_Object_Property_Value[i]); status = bacapp_parse_application_data(property_tag,
if (!status) { value_string, &Target_Object_Property_Value[i]);
/* FIXME: show the expected entry format for the tag */ if (!status) {
fprintf(stderr, "unable to parse the tag value\r\n"); /* FIXME: show the expected entry format for the tag */
return 1; fprintf(stderr, "unable to parse the tag value\r\n");
} return 1;
Target_Object_Property_Value[i].next = NULL; }
if (i > 0) { Target_Object_Property_Value[i].next = NULL;
Target_Object_Property_Value[i-1].next = if (i > 0) {
&Target_Object_Property_Value[i]; Target_Object_Property_Value[i - 1].next =
} &Target_Object_Property_Value[i];
if (args_remaining <= 0) }
break; if (args_remaining <= 0)
} break;
/* setup my info */ }
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); /* setup my info */
address_init(); Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers(); address_init();
/* configure standard BACnet/IP port */ Init_Service_Handlers();
bip_set_interface("eth0"); /* for linux */ /* configure standard BACnet/IP port */
bip_set_port(0xBAC0); bip_set_interface("eth0"); /* for linux */
if (!bip_init()) bip_set_port(0xBAC0);
return 1; if (!bip_init())
/* configure the timeout values */ return 1;
last_seconds = time(NULL); /* configure the timeout values */
timeout_seconds = (Device_APDU_Timeout() / 1000) * last_seconds = time(NULL);
Device_Number_Of_APDU_Retries(); timeout_seconds = (Device_APDU_Timeout() / 1000) *
/* try to bind with the device */ Device_Number_Of_APDU_Retries();
Send_WhoIs(Target_Device_Object_Instance, /* try to bind with the device */
Target_Device_Object_Instance); Send_WhoIs(Target_Device_Object_Instance,
/* loop forever */ Target_Device_Object_Instance);
for (;;) { /* loop forever */
/* increment timer - exit if timed out */ for (;;) {
current_seconds = time(NULL); /* increment timer - exit if timed out */
current_seconds = time(NULL);
/* returns 0 bytes on timeout */
pdu_len = bip_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); /* returns 0 bytes on timeout */
pdu_len = bip_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) { /* process */
npdu_handler(&src, &Rx_Buf[0], pdu_len); if (pdu_len) {
} npdu_handler(&src, &Rx_Buf[0], pdu_len);
/* at least one second has passed */ }
if (current_seconds != last_seconds) /* at least one second has passed */
tsm_timer_milliseconds(((current_seconds - if (current_seconds != last_seconds)
last_seconds) * 1000)); tsm_timer_milliseconds(((current_seconds -
if (Error_Detected) last_seconds) * 1000));
break; if (Error_Detected)
/* wait until the device is bound, or timeout and quit */ break;
found = address_bind_request(Target_Device_Object_Instance, /* wait until the device is bound, or timeout and quit */
&max_apdu, &Target_Address); found = address_bind_request(Target_Device_Object_Instance,
if (found) { &max_apdu, &Target_Address);
if (invoke_id == 0) { if (found) {
invoke_id = if (invoke_id == 0) {
Send_Write_Property_Request( invoke_id =
Target_Device_Object_Instance, Target_Object_Type, Send_Write_Property_Request
Target_Object_Instance, Target_Object_Property, (Target_Device_Object_Instance, Target_Object_Type,
&Target_Object_Property_Value[0], Target_Object_Instance, Target_Object_Property,
Target_Object_Property_Priority, &Target_Object_Property_Value[0],
Target_Object_Property_Index); Target_Object_Property_Priority,
} else if (tsm_invoke_id_free(invoke_id)) Target_Object_Property_Index);
break; } else if (tsm_invoke_id_free(invoke_id))
else if (tsm_invoke_id_failed(invoke_id)) { break;
fprintf(stderr, "\rError: TSM Timeout!\r\n"); else if (tsm_invoke_id_failed(invoke_id)) {
tsm_free_invoke_id(invoke_id); fprintf(stderr, "\rError: TSM Timeout!\r\n");
/* try again or abort? */ tsm_free_invoke_id(invoke_id);
break; /* try again or abort? */
} break;
} else { }
/* increment timer - exit if timed out */ } else {
elapsed_seconds += (current_seconds - last_seconds); /* increment timer - exit if timed out */
if (elapsed_seconds > timeout_seconds) { elapsed_seconds += (current_seconds - last_seconds);
printf("\rError: APDU Timeout!\r\n"); if (elapsed_seconds > timeout_seconds) {
break; printf("\rError: APDU Timeout!\r\n");
} break;
} }
/* keep track of time for next check */ }
last_seconds = current_seconds; /* keep track of time for next check */
} last_seconds = current_seconds;
}
return 0;
} return 0;
}
+9 -9
View File
@@ -252,15 +252,15 @@ enum INT_STATE { INT_DISABLED, INT_ENABLED, INT_RESTORE };
BRA LOOP \ BRA LOOP \
_endasm } _endasm }
#endif #endif
#define setup_timer4(mode, period, postscale) \ #define setup_timer4(mode, period, postscale) \
T4CON = (mode | (postscale - 1) << 3); \ T4CON = (mode | (postscale - 1) << 3); \
PR4 = period PR4 = period
#define setup_timer2(mode, period, postscale) \ #define setup_timer2(mode, period, postscale) \
T2CON = (mode | (postscale - 1) << 3); \ T2CON = (mode | (postscale - 1) << 3); \
PR2 = period PR2 = period
/* Global Vars */ /* Global Vars */
extern volatile LED_REGS LEDS; extern volatile LED_REGS LEDS;
+3 -9
View File
@@ -45,19 +45,13 @@ void INT0_Interrupt(void);
void InterruptVectorHigh(void) void InterruptVectorHigh(void)
{ {
/* jump to interrupt routine */ /* jump to interrupt routine */
_asm goto InterruptHandlerHigh _asm goto InterruptHandlerHigh _endasm}
_endasm
}
#pragma code #pragma code
#pragma code InterruptVectorLow = 0x18 #pragma code InterruptVectorLow = 0x18
void InterruptVectorLow(void) void InterruptVectorLow(void)
{ {
/* jump to interrupt routine */ /* jump to interrupt routine */
_asm goto InterruptHandlerLow _asm goto InterruptHandlerLow _endasm}
_endasm
}
#pragma code #pragma code
#pragma interrupt InterruptHandlerHigh #pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh(void) void InterruptHandlerHigh(void)
+170 -170
View File
@@ -38,60 +38,60 @@
#include "handlers.h" #include "handlers.h"
#include "iam.h" #include "iam.h"
#include "txbuf.h" #include "txbuf.h"
/* chip configuration data */ /* chip configuration data */
/* define this to enable ICD */ /* define this to enable ICD */
/* #define USE_ICD */ /* #define USE_ICD */
// Configuration Bits /* Configuration Bits */
#pragma config OSC = HS, OSCS = OFF #pragma config OSC = HS, OSCS = OFF
#pragma config PWRT = ON #pragma config PWRT = ON
#pragma config BOR = ON, BORV = 27 #pragma config BOR = ON, BORV = 27
#pragma config CCP2MUX = ON #pragma config CCP2MUX = ON
#pragma config STVR = ON #pragma config STVR = ON
#pragma config LVP = OFF #pragma config LVP = OFF
#pragma config CP0 = OFF #pragma config CP0 = OFF
#pragma config CP1 = OFF #pragma config CP1 = OFF
#pragma config CP2 = OFF #pragma config CP2 = OFF
#pragma config CP3 = OFF #pragma config CP3 = OFF
#pragma config CP4 = OFF #pragma config CP4 = OFF
#pragma config CP5 = OFF #pragma config CP5 = OFF
#pragma config CP6 = OFF #pragma config CP6 = OFF
#pragma config CP7 = OFF #pragma config CP7 = OFF
#pragma config CPB = OFF #pragma config CPB = OFF
#pragma config CPD = OFF #pragma config CPD = OFF
#pragma config WRT0 = OFF #pragma config WRT0 = OFF
#pragma config WRT1 = OFF #pragma config WRT1 = OFF
#pragma config WRT2 = OFF #pragma config WRT2 = OFF
#pragma config WRT3 = OFF #pragma config WRT3 = OFF
#pragma config WRT4 = OFF #pragma config WRT4 = OFF
#pragma config WRT5 = OFF #pragma config WRT5 = OFF
#pragma config WRT6 = OFF #pragma config WRT6 = OFF
#pragma config WRT7 = OFF #pragma config WRT7 = OFF
#pragma config WRTB = OFF #pragma config WRTB = OFF
#pragma config WRTC = OFF #pragma config WRTC = OFF
#pragma config WRTD = OFF #pragma config WRTD = OFF
#pragma config EBTR0 = OFF #pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF #pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF #pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF #pragma config EBTR3 = OFF
#pragma config EBTR4 = OFF #pragma config EBTR4 = OFF
#pragma config EBTR5 = OFF #pragma config EBTR5 = OFF
#pragma config EBTR6 = OFF #pragma config EBTR6 = OFF
#pragma config EBTR7 = OFF #pragma config EBTR7 = OFF
#pragma config EBTRB = OFF #pragma config EBTRB = OFF
#ifdef USE_ICD #ifdef USE_ICD
#pragma config WDT = OFF, WDTPS = 128 #pragma config WDT = OFF, WDTPS = 128
#pragma config DEBUG = ON #pragma config DEBUG = ON
#else #else
#pragma config WDT = ON, WDTPS = 128 #pragma config WDT = ON, WDTPS = 128
#pragma config DEBUG = OFF #pragma config DEBUG = OFF
#endif /* USE_ICD */ #endif /* USE_ICD */
volatile uint8_t Milliseconds = 0; volatile uint8_t Milliseconds = 0;
volatile uint8_t Zero_Cross_Timeout = 0; volatile uint8_t Zero_Cross_Timeout = 0;
static void BACnet_Service_Handlers_Init(void) static void BACnet_Service_Handlers_Init(void)
{ {
/* we need to handle who-is to support dynamic device binding */ /* we need to handle who-is to support dynamic device binding */
@@ -100,17 +100,18 @@ static void BACnet_Service_Handlers_Init(void)
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
handler_reinitialize_device); handler_reinitialize_device);
#if 0 #if 0
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property); handler_write_property);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, apdu_set_unconfirmed_handler
handler_timesync_utc); (SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
handler_timesync_utc);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
handler_timesync); handler_timesync);
#endif #endif
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler apdu_set_confirmed_handler
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, (SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
@@ -122,12 +123,11 @@ void Reinitialize(void)
uint8_t i; uint8_t i;
char name = 0; char name = 0;
_asm reset _endasm _asm reset _endasm return;
return; }
}
void Global_Int(enum INT_STATE state) void Global_Int(enum INT_STATE state)
{ {
static uint8_t intstate = 0; static uint8_t intstate = 0;
switch (state) { switch (state) {
@@ -148,104 +148,104 @@ void Global_Int(enum INT_STATE state)
break; break;
} }
} }
void Hardware_Initialize(void) void Hardware_Initialize(void)
{ {
/* PORTA.0 Input - Photocell PORTA.1 Output - LED Row6 PORTA.2 Output /* PORTA.0 Input - Photocell PORTA.1 Output - LED Row6 PORTA.2 Output
* - LED Row5 PORTA.3 Output - LED Row4 PORTA.4 Input - Square Wave * - LED Row5 PORTA.3 Output - LED Row4 PORTA.4 Input - Square Wave
* input from RTC PORTA.5 Output - LCD RW */ * input from RTC PORTA.5 Output - LCD RW */
TRISA = 0xD1; TRISA = 0xD1;
/* PORTB.0 Input - Zero Cross PORTB.1 Input - USB RXF# PORTB.2 Input /* PORTB.0 Input - Zero Cross PORTB.1 Input - USB RXF# PORTB.2 Input
* USB TXE# PORTB.3 Output - Keypad Row Enable (74HC373 Output Control) * USB TXE# PORTB.3 Output - Keypad Row Enable (74HC373 Output Control)
* PORTB.4 Output Keypad Row Gate (74HC373 Gate) PORTB.5 Output Switch * PORTB.4 Output Keypad Row Gate (74HC373 Gate) PORTB.5 Output Switch
* Input Latch & Keypad Column Gate (74HC373 Gate) PORTB.6 Input - ICD * Input Latch & Keypad Column Gate (74HC373 Gate) PORTB.6 Input - ICD
* connection PORTB.7 Input - ICD connection */ * connection PORTB.7 Input - ICD connection */
TRISB = 0xC7; TRISB = 0xC7;
/* PORTC.0 Output - Pilot Latch PORTC.1 Output - Pilot Output Enable /* PORTC.0 Output - Pilot Latch PORTC.1 Output - Pilot Output Enable
* (low) PORTC.2 I/O - Piezo PORTC.3 Input - I2C clock PORTC.4 Input * (low) PORTC.2 I/O - Piezo PORTC.3 Input - I2C clock PORTC.4 Input
* I2C data PORTC.5 Output RS232 enable (low) PORTC.6 Output - RS232 Tx * I2C data PORTC.5 Output RS232 enable (low) PORTC.6 Output - RS232 Tx
* PORTC.7 Input - RS232 Rx */ * PORTC.7 Input - RS232 Rx */
TRISC = 0x9C; TRISC = 0x9C;
/* PORTD.0 I/O - Data bus PORTD.1 I/O - Data bus PORTD.2 I/O - Data /* PORTD.0 I/O - Data bus PORTD.1 I/O - Data bus PORTD.2 I/O - Data
* bus PORTD.3 I/O - Data bus PORTD.4 I/O - Data bus PORTD.5 I/O - Data * bus PORTD.3 I/O - Data bus PORTD.4 I/O - Data bus PORTD.5 I/O - Data
* bus PORTD.6 I/O - Data bus PORTD.7 I/O - Data bus */ * bus PORTD.6 I/O - Data bus PORTD.7 I/O - Data bus */
TRISD = 0xFF; TRISD = 0xFF;
/* PORTE.0 Input - USB RD PORTE.1 Input - USB WR PORTE.2 Output - LCD /* PORTE.0 Input - USB RD PORTE.1 Input - USB WR PORTE.2 Output - LCD
* RS PORTE.3 Output - 485 transmit enable PORTE.4 Output - Relay data * RS PORTE.3 Output - 485 transmit enable PORTE.4 Output - Relay data
* latch PORTE.5 Output Switch Input Clock PORTE.6 Output - Switch * latch PORTE.5 Output Switch Input Clock PORTE.6 Output - Switch
* Input High/Low PORTE.7 Input Switch Input Data */ * Input High/Low PORTE.7 Input Switch Input Data */
TRISE = 0x83; TRISE = 0x83;
/* PORTF.0 Output - LED Row2 PORTF.1 Output - LED Row1 PORTF.2 Output /* PORTF.0 Output - LED Row2 PORTF.1 Output - LED Row1 PORTF.2 Output
* - LED Col5 PORTF.3 Output - LED Col4 PORTF.4 Output - LED Col3 * - LED Col5 PORTF.3 Output - LED Col4 PORTF.4 Output - LED Col3
* PORTF.5 Output - LED Col2 PORTF.6 Output - LED Col1 PORTF.7 Output * PORTF.5 Output - LED Col2 PORTF.6 Output - LED Col1 PORTF.7 Output
* LED Col0 */ * LED Col0 */
TRISF = 0x00; TRISF = 0x00;
/* PORTG.0 Output - 485 receive enable PORTG.1 Output - 485 Tx PORTG.2 /* PORTG.0 Output - 485 receive enable PORTG.1 Output - 485 Tx PORTG.2
* Input 485 Rx PORTG.3 Output - LCD E PORTG.4 Output - LED Row0 */ * Input 485 Rx PORTG.3 Output - LCD E PORTG.4 Output - LED Row0 */
TRISG = 0xE6; TRISG = 0xE6;
/* The initial state of the keypad enables and latches */ /* The initial state of the keypad enables and latches */
KEYPAD_ROW_ENABLE = 1; KEYPAD_ROW_ENABLE = 1;
KEYPAD_ROW_LATCH = 0; KEYPAD_ROW_LATCH = 0;
KEYPAD_COL_LATCH = 1; KEYPAD_COL_LATCH = 1;
RELAY_LATCH = 0; RELAY_LATCH = 0;
/* Setup to read the switch inputs */ /* Setup to read the switch inputs */
SWITCH_COM = 1; SWITCH_COM = 1;
/* Enable the RS232 transmitter */ /* Enable the RS232 transmitter */
RS232_ENABLE = 0; RS232_ENABLE = 0;
/* Turn all leds off. These are the hardware pins */ /* Turn all leds off. These are the hardware pins */
LED_ROW1 = 1; LED_ROW1 = 1;
LED_ROW2 = 1; LED_ROW2 = 1;
LED_ROW3 = 1; LED_ROW3 = 1;
LED_ROW4 = 1; LED_ROW4 = 1;
LED_ROW5 = 1; LED_ROW5 = 1;
LED_ROW6 = 1; LED_ROW6 = 1;
LEDPORT = 0x03; LEDPORT = 0x03;
/* The initial values for the signals to the LCD */ /* The initial values for the signals to the LCD */
LCD_E = 1; LCD_E = 1;
LCD_RW = 1; LCD_RW = 1;
LCD_RS = 1; LCD_RS = 1;
/* The following gives us a PWM frequency of 1.990KHz with a 50% duty /* The following gives us a PWM frequency of 1.990KHz with a 50% duty
* cycle It also serves to multiplex the LEDs. */ * cycle It also serves to multiplex the LEDs. */
PIEZO_OFF(); PIEZO_OFF();
CCPR1L = 0x4E; CCPR1L = 0x4E;
CCP1CON = 0x2F; CCP1CON = 0x2F;
setup_timer2(6, 156, 2); setup_timer2(6, 156, 2);
PIE1bits.TMR2IE = 1; PIE1bits.TMR2IE = 1;
/* We will use Timer4 as our system tick timer. Our system tick is set /* We will use Timer4 as our system tick timer. Our system tick is set
* to 1ms. Hold off on enabling the int. */ * to 1ms. Hold off on enabling the int. */
setup_timer4(5, 250, 5); setup_timer4(5, 250, 5);
/* Setup our interrupt priorities */ /* Setup our interrupt priorities */
RCONbits.IPEN = 1; RCONbits.IPEN = 1;
IPR1 = 0; IPR1 = 0;
IPR2 = 0; IPR2 = 0;
IPR3 = 0; IPR3 = 0;
/* Setup TMR0 to be high priority */ /* Setup TMR0 to be high priority */
INTCON2 = 0xFC; INTCON2 = 0xFC;
INTCON3 = 0; INTCON3 = 0;
/* USART 1 high priority */ /* USART 1 high priority */
IPR1bits.RC1IP = 1; IPR1bits.RC1IP = 1;
IPR1bits.TX1IP = 1; IPR1bits.TX1IP = 1;
/* Finally enable our ints */ /* Finally enable our ints */
Global_Int(INT_ENABLED); Global_Int(INT_ENABLED);
} }
void Initialize_Variables(void) void Initialize_Variables(void)
{ {
@@ -260,22 +260,22 @@ void Initialize_Variables(void)
} }
void MainTasks(void) void MainTasks(void)
{ {
static uint16_t millisecond_counter = 0; static uint16_t millisecond_counter = 0;
/* Handle our millisecond counters */ /* Handle our millisecond counters */
while (Milliseconds) { while (Milliseconds) {
millisecond_counter++; millisecond_counter++;
--Milliseconds; --Milliseconds;
} }
/* Handle our seconds counters */ /* Handle our seconds counters */
if (millisecond_counter > 1000) { if (millisecond_counter > 1000) {
millisecond_counter -= 1000; millisecond_counter -= 1000;
dcc_timer_seconds(1); dcc_timer_seconds(1);
} }
} }
void main(void) void main(void)
{ {
RCONbits.NOT_POR = 1; RCONbits.NOT_POR = 1;
RCONbits.NOT_RI = 1; RCONbits.NOT_RI = 1;
Hardware_Initialize(); Hardware_Initialize();
@@ -288,7 +288,7 @@ void main(void)
RESTART_WDT(); RESTART_WDT();
dlmstp_task(); dlmstp_task();
MainTasks(); MainTasks();
Global_Int(INT_ENABLED); Global_Int(INT_ENABLED);
ENABLE_TIMER4_INT(); ENABLE_TIMER4_INT();
} }
} }
+11 -11
View File
@@ -43,7 +43,7 @@ uint32_t RS485_Baud_Rate = 38400;
/* the ISR and other use this for status and control */ /* the ISR and other use this for status and control */
COMSTAT RS485_Comstat; COMSTAT RS485_Comstat;
/*#pragma udata MSTPPortData /*#pragma udata MSTPPortData
*/ */
/* the buffer for receiving characters */ /* the buffer for receiving characters */
volatile uint8_t RS485_Rx_Buffer[MAX_MPDU]; volatile uint8_t RS485_Rx_Buffer[MAX_MPDU];
@@ -87,14 +87,14 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
}; };
RS485_Comstat.TxHead = 0; RS485_Comstat.TxHead = 0;
memcpy((void *) &RS485_Tx_Buffer[0], (void *) buffer, nbytes); memcpy((void *) &RS485_Tx_Buffer[0], (void *) buffer, nbytes);
#if 0 #if 0
for (i = 0; i < nbytes; i++) { for (i = 0; i < nbytes; i++) {
/* put the data into the buffer */ /* put the data into the buffer */
RS485_Tx_Buffer[i] = *buffer; RS485_Tx_Buffer[i] = *buffer;
buffer++; buffer++;
} }
#endif #endif
RS485_Comstat.Tx_Bytes = nbytes; RS485_Comstat.Tx_Bytes = nbytes;
/* disable the receiver */ /* disable the receiver */
PIE3bits.RC2IE = 0; PIE3bits.RC2IE = 0;
@@ -200,8 +200,8 @@ void RS485_Interrupt_Tx(void)
/* enable the receiver */ /* enable the receiver */
RS485_TX_ENABLE = 0; RS485_TX_ENABLE = 0;
RS485_RX_DISABLE = 0; RS485_RX_DISABLE = 0;
/* FIXME: might not be necessary /* FIXME: might not be necessary
*/ */
PIE3bits.RC2IE = 1; PIE3bits.RC2IE = 1;
RCSTA2bits.CREN = 1; RCSTA2bits.CREN = 1;
} }
+5
View File
@@ -114,6 +114,11 @@ make -f indtext.mak
./indtext >> test.log ./indtext >> test.log
make -f indtext.mak clean make -f indtext.mak clean
make -f demo/object/lc.mak clean
make -f demo/object/lc.mak
./loadcontrol >> test.log
make -f demo/object/lc.mak clean
make -f demo/object/lsp.mak clean make -f demo/object/lsp.mak clean
make -f demo/object/lsp.mak make -f demo/object/lsp.mak
./lsp >> test.log ./lsp >> test.log