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