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.
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;
}
+7 -9
View File
@@ -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);
+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);
}
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 */
+3 -3
View File
@@ -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 */
+2 -2
View File
@@ -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"}
,
+40 -40
View File
@@ -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 <assert.h>
@@ -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);
+12 -12
View File
@@ -38,13 +38,13 @@
#include <stdbool.h>
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 */
+1 -1
View File
@@ -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);
+122 -122
View File
@@ -1,122 +1,122 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#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 <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#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;
}
+1 -1
View File
@@ -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],
+10 -15
View File
@@ -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);
}
+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 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;
+6 -8
View File
@@ -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,
+137 -128
View File
@@ -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);
+1 -1
View File
@@ -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);
+376 -375
View File
@@ -1,375 +1,376 @@
/**************************************************************************
*
* Copyright (C) 2006-2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the response */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <string.h>
#include <errno.h>
#include <ctype.h> /* 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 <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* command line tool that sends a BACnet service, and displays the response */
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <string.h>
#include <errno.h>
#include <ctype.h> /* 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;
}
+9 -9
View File
@@ -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;
+3 -9
View File
@@ -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)
+170 -170
View File
@@ -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();
}
}
+11 -11
View File
@@ -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;
}
+5
View File
@@ -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