Standardized the comments and indentation using the comment.sh and indent.sh scripts.
This commit is contained in:
+91
-98
@@ -173,31 +173,29 @@ int bacapp_decode_application_data(uint8_t * apdu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int bacapp_encode_context_data(uint8_t * apdu,
|
int bacapp_encode_context_data(uint8_t * apdu,
|
||||||
BACNET_APPLICATION_DATA_VALUE * value,
|
BACNET_APPLICATION_DATA_VALUE * value, BACNET_PROPERTY_ID property)
|
||||||
BACNET_PROPERTY_ID property)
|
|
||||||
{
|
{
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
|
|
||||||
if (value && apdu) {
|
if (value && apdu) {
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case PROP_REQUESTED_SHED_LEVEL:
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
switch (value->tag) {
|
switch (value->tag) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0],
|
apdu_len = encode_tagged_unsigned(&apdu[0],
|
||||||
value->type.Unsigned_Int);
|
value->type.Unsigned_Int);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
apdu_len = encode_tagged_real(&apdu[0],
|
apdu_len = encode_tagged_real(&apdu[0], value->type.Real);
|
||||||
value->type.Real);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
apdu_len = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
apdu_len = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return apdu_len;
|
return apdu_len;
|
||||||
@@ -221,25 +219,23 @@ int bacapp_decode_context_data(uint8_t * apdu,
|
|||||||
len += tag_len;
|
len += tag_len;
|
||||||
value->tag = tag_number;
|
value->tag = tag_number;
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case PROP_REQUESTED_SHED_LEVEL:
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
switch (tag_number) {
|
switch (tag_number) {
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
len += decode_unsigned(&apdu[len],
|
len += decode_unsigned(&apdu[len],
|
||||||
len_value_type,
|
len_value_type, &(value->type.Unsigned_Int));
|
||||||
&(value->type.Unsigned_Int));
|
break;
|
||||||
break;
|
case 2:
|
||||||
case 2:
|
len += decode_real(&apdu[len], &(value->type.Real));
|
||||||
len += decode_real(&apdu[len],
|
|
||||||
&(value->type.Real));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
len = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
len = 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,10 +273,12 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
|||||||
dest_value->type.Enumerated = src_value->type.Enumerated;
|
dest_value->type.Enumerated = src_value->type.Enumerated;
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_DATE:
|
case BACNET_APPLICATION_TAG_DATE:
|
||||||
datetime_copy_date(&dest_value->type.Date, &src_value->type.Date);
|
datetime_copy_date(&dest_value->type.Date,
|
||||||
|
&src_value->type.Date);
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_TIME:
|
case BACNET_APPLICATION_TAG_TIME:
|
||||||
datetime_copy_time(&dest_value->type.Time, &src_value->type.Time);
|
datetime_copy_time(&dest_value->type.Time,
|
||||||
|
&src_value->type.Time);
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_OBJECT_ID:
|
case BACNET_APPLICATION_TAG_OBJECT_ID:
|
||||||
dest_value->type.Object_Id.type =
|
dest_value->type.Object_Id.type =
|
||||||
@@ -310,57 +308,56 @@ bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
|
|||||||
Expects that the first octet contain the opening tag.
|
Expects that the first octet contain the opening tag.
|
||||||
Include a value property identifier for context specific data
|
Include a value property identifier for context specific data
|
||||||
such as the value received in a WriteProperty request */
|
such as the value received in a WriteProperty request */
|
||||||
int bacapp_data_len(uint8_t *apdu, int max_apdu_len,
|
int bacapp_data_len(uint8_t * apdu, int max_apdu_len,
|
||||||
BACNET_PROPERTY_ID property)
|
BACNET_PROPERTY_ID property)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int total_len = 0;
|
int total_len = 0;
|
||||||
int apdu_len = 0;
|
int apdu_len = 0;
|
||||||
uint8_t tag_number = 0;
|
uint8_t tag_number = 0;
|
||||||
uint8_t opening_tag_number = 0;
|
uint8_t opening_tag_number = 0;
|
||||||
uint8_t opening_tag_number_counter = 0;
|
uint8_t opening_tag_number_counter = 0;
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
BACNET_APPLICATION_DATA_VALUE application_value;
|
BACNET_APPLICATION_DATA_VALUE application_value;
|
||||||
|
|
||||||
if (decode_is_opening_tag(&apdu[0])) {
|
if (decode_is_opening_tag(&apdu[0])) {
|
||||||
len = decode_tag_number_and_value(&apdu[apdu_len],
|
len = decode_tag_number_and_value(&apdu[apdu_len],
|
||||||
&tag_number, &value);
|
&tag_number, &value);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
opening_tag_number = tag_number;
|
opening_tag_number = tag_number;
|
||||||
opening_tag_number_counter = 1;
|
opening_tag_number_counter = 1;
|
||||||
while (opening_tag_number_counter) {
|
while (opening_tag_number_counter) {
|
||||||
if (decode_is_opening_tag(&apdu[apdu_len])) {
|
if (decode_is_opening_tag(&apdu[apdu_len])) {
|
||||||
len = decode_tag_number_and_value(&apdu[apdu_len],
|
len = decode_tag_number_and_value(&apdu[apdu_len],
|
||||||
&tag_number, &value);
|
&tag_number, &value);
|
||||||
if (tag_number == opening_tag_number)
|
if (tag_number == opening_tag_number)
|
||||||
opening_tag_number_counter++;
|
opening_tag_number_counter++;
|
||||||
} else if (decode_is_closing_tag(&apdu[apdu_len])) {
|
} else if (decode_is_closing_tag(&apdu[apdu_len])) {
|
||||||
len = decode_tag_number_and_value(&apdu[apdu_len],
|
len = decode_tag_number_and_value(&apdu[apdu_len],
|
||||||
&tag_number, &value);
|
&tag_number, &value);
|
||||||
if (tag_number == opening_tag_number)
|
if (tag_number == opening_tag_number)
|
||||||
opening_tag_number_counter--;
|
opening_tag_number_counter--;
|
||||||
} else if (decode_is_context_specific(&apdu[apdu_len])) {
|
} else if (decode_is_context_specific(&apdu[apdu_len])) {
|
||||||
/* context-specific tagged data */
|
/* context-specific tagged data */
|
||||||
len = bacapp_decode_context_data(&apdu[apdu_len],
|
len = bacapp_decode_context_data(&apdu[apdu_len],
|
||||||
max_apdu_len - apdu_len, &application_value, property);
|
max_apdu_len - apdu_len, &application_value, property);
|
||||||
} else {
|
} else {
|
||||||
/* application tagged data */
|
/* application tagged data */
|
||||||
len = bacapp_decode_application_data(&apdu[apdu_len],
|
len = bacapp_decode_application_data(&apdu[apdu_len],
|
||||||
max_apdu_len - apdu_len, &application_value);
|
max_apdu_len - apdu_len, &application_value);
|
||||||
}
|
}
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
if (opening_tag_number_counter)
|
if (opening_tag_number_counter)
|
||||||
total_len += len;
|
total_len += len;
|
||||||
/* ERROR! */
|
/* ERROR! */
|
||||||
if (apdu_len > max_apdu_len)
|
if (apdu_len > max_apdu_len) {
|
||||||
{
|
total_len = -1;
|
||||||
total_len = -1;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return total_len;
|
return total_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BACAPP_PRINT_ENABLED
|
#ifdef BACAPP_PRINT_ENABLED
|
||||||
@@ -475,7 +472,7 @@ bool bacapp_print_value(FILE * stream,
|
|||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
fprintf(stream, "%s",
|
fprintf(stream, "%s",
|
||||||
bitstring_bit(&value->type.Bit_String,
|
bitstring_bit(&value->type.Bit_String,
|
||||||
(uint8_t)i) ? "true" : "false");
|
(uint8_t) i) ? "true" : "false");
|
||||||
if (i < len - 1)
|
if (i < len - 1)
|
||||||
fprintf(stream, ",");
|
fprintf(stream, ",");
|
||||||
}
|
}
|
||||||
@@ -580,7 +577,7 @@ void testBACnetApplicationDataLength(Test * pTest)
|
|||||||
{
|
{
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
int len = 0; /* total length of the apdu, return value */
|
int len = 0; /* total length of the apdu, return value */
|
||||||
int test_len = 0; /* length of the data */
|
int test_len = 0; /* length of the data */
|
||||||
uint8_t apdu[480] = { 0 };
|
uint8_t apdu[480] = { 0 };
|
||||||
BACNET_TIME local_time;
|
BACNET_TIME local_time;
|
||||||
BACNET_DATE local_date;
|
BACNET_DATE local_date;
|
||||||
@@ -609,8 +606,7 @@ void testBACnetApplicationDataLength(Test * pTest)
|
|||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/* verify the length of the data inside the opening/closing tags */
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
len = bacapp_data_len(&apdu[0], apdu_len,
|
len = bacapp_data_len(&apdu[0], apdu_len, PROP_OBJECT_IDENTIFIER);
|
||||||
PROP_OBJECT_IDENTIFIER);
|
|
||||||
ct_test(pTest, test_len == len);
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
/* 3. application tagged data, multiple elements */
|
/* 3. application tagged data, multiple elements */
|
||||||
@@ -669,8 +665,7 @@ void testBACnetApplicationDataLength(Test * pTest)
|
|||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/* verify the length of the data inside the opening/closing tags */
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
len = bacapp_data_len(&apdu[0], apdu_len,
|
len = bacapp_data_len(&apdu[0], apdu_len, PROP_PRIORITY_ARRAY);
|
||||||
PROP_PRIORITY_ARRAY);
|
|
||||||
ct_test(pTest, test_len == len);
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
/* 4. complex datatype - one element */
|
/* 4. complex datatype - one element */
|
||||||
@@ -681,10 +676,10 @@ void testBACnetApplicationDataLength(Test * pTest)
|
|||||||
len = encode_opening_tag(&apdu[apdu_len], 3);
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
test_len += len;
|
test_len += len;
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
local_date.year = 2006; /* AD */
|
local_date.year = 2006; /* AD */
|
||||||
local_date.month = 4; /* 1=Jan */
|
local_date.month = 4; /* 1=Jan */
|
||||||
local_date.day = 1; /* 1..31 */
|
local_date.day = 1; /* 1..31 */
|
||||||
local_date.wday = 6; /* 1=Monday */
|
local_date.wday = 6; /* 1=Monday */
|
||||||
len = encode_tagged_date(&apdu[apdu_len], &local_date);
|
len = encode_tagged_date(&apdu[apdu_len], &local_date);
|
||||||
test_len += len;
|
test_len += len;
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
@@ -701,8 +696,7 @@ void testBACnetApplicationDataLength(Test * pTest)
|
|||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/* verify the length of the data inside the opening/closing tags */
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
len = bacapp_data_len(&apdu[0], apdu_len,
|
len = bacapp_data_len(&apdu[0], apdu_len, PROP_START_TIME);
|
||||||
PROP_START_TIME);
|
|
||||||
ct_test(pTest, test_len == len);
|
ct_test(pTest, test_len == len);
|
||||||
|
|
||||||
/* 5. complex datatype - multiple elements */
|
/* 5. complex datatype - multiple elements */
|
||||||
@@ -720,8 +714,7 @@ void testBACnetApplicationDataLength(Test * pTest)
|
|||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/* verify the length of the data inside the opening/closing tags */
|
/* verify the length of the data inside the opening/closing tags */
|
||||||
len = bacapp_data_len(&apdu[0], apdu_len,
|
len = bacapp_data_len(&apdu[0], apdu_len, PROP_REQUESTED_SHED_LEVEL);
|
||||||
PROP_REQUESTED_SHED_LEVEL);
|
|
||||||
ct_test(pTest, test_len == len);
|
ct_test(pTest, test_len == len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,12 +759,12 @@ bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE * value,
|
|||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_DATE:
|
case BACNET_APPLICATION_TAG_DATE:
|
||||||
if (datetime_compare_date(&test_value->type.Date,
|
if (datetime_compare_date(&test_value->type.Date,
|
||||||
&value->type.Date) != 0)
|
&value->type.Date) != 0)
|
||||||
status = false;
|
status = false;
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_TIME:
|
case BACNET_APPLICATION_TAG_TIME:
|
||||||
if (datetime_compare_time(&test_value->type.Time,
|
if (datetime_compare_time(&test_value->type.Time,
|
||||||
&value->type.Time) != 0)
|
&value->type.Time) != 0)
|
||||||
status = false;
|
status = false;
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_OBJECT_ID:
|
case BACNET_APPLICATION_TAG_OBJECT_ID:
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
#include "datetime.h"
|
#include "datetime.h"
|
||||||
|
|
||||||
typedef struct BACnet_Application_Data_Value {
|
typedef struct BACnet_Application_Data_Value {
|
||||||
uint8_t tag; /* application or context-specific number */
|
uint8_t tag; /* application or context-specific number */
|
||||||
union {
|
union {
|
||||||
/* NULL - not needed as it is encoded in the tag alone */
|
/* NULL - not needed as it is encoded in the tag alone */
|
||||||
bool Boolean;
|
bool Boolean;
|
||||||
@@ -85,7 +85,7 @@ extern "C" {
|
|||||||
Expects that the first octet contain the opening tag.
|
Expects that the first octet contain the opening tag.
|
||||||
Include a value property identifier for context specific data
|
Include a value property identifier for context specific data
|
||||||
such as the value received in a WriteProperty request */
|
such as the value received in a WriteProperty request */
|
||||||
int bacapp_data_len(uint8_t *apdu, int max_apdu_len,
|
int bacapp_data_len(uint8_t * apdu, int max_apdu_len,
|
||||||
BACNET_PROPERTY_ID property);
|
BACNET_PROPERTY_ID property);
|
||||||
|
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
|
|||||||
@@ -731,9 +731,10 @@ int encode_tagged_boolean(uint8_t * apdu, bool boolean_value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* context tagged is encoded differently */
|
/* context tagged is encoded differently */
|
||||||
int encode_context_boolean(uint8_t * apdu, int tag_number, bool boolean_value)
|
int encode_context_boolean(uint8_t * apdu, int tag_number,
|
||||||
|
bool boolean_value)
|
||||||
{
|
{
|
||||||
int len = 1; /* return value */
|
int len = 1; /* return value */
|
||||||
|
|
||||||
apdu[1] = boolean_value ? 1 : 0;
|
apdu[1] = boolean_value ? 1 : 0;
|
||||||
/* we only reserved 1 byte for encoding the tag - check the limits */
|
/* we only reserved 1 byte for encoding the tag - check the limits */
|
||||||
|
|||||||
@@ -1186,7 +1186,7 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum BACnetNodeType {
|
typedef enum BACnetNodeType {
|
||||||
BACNET_NODE_UNKNOWN = 0,
|
BACNET_NODE_UNKNOWN = 0,
|
||||||
BACNET_NODE_SYSTEM = 1,
|
BACNET_NODE_SYSTEM = 1,
|
||||||
BACNET_NODE_NETWORK = 2,
|
BACNET_NODE_NETWORK = 2,
|
||||||
BACNET_NODE_DEVICE = 3,
|
BACNET_NODE_DEVICE = 3,
|
||||||
BACNET_NODE_ORGANIZATIONAL = 4,
|
BACNET_NODE_ORGANIZATIONAL = 4,
|
||||||
|
|||||||
+118
-58
@@ -203,13 +203,19 @@ INDTEXT_DATA bacnet_object_type_names[] = {
|
|||||||
,
|
,
|
||||||
{OBJECT_ACCUMULATOR, "Accumulator"}
|
{OBJECT_ACCUMULATOR, "Accumulator"}
|
||||||
,
|
,
|
||||||
{OBJECT_PULSE_CONVERTER, "Pulse-Converter"},
|
{OBJECT_PULSE_CONVERTER, "Pulse-Converter"}
|
||||||
|
,
|
||||||
|
|
||||||
{OBJECT_EVENT_LOG, "Event-Log"},
|
{OBJECT_EVENT_LOG, "Event-Log"}
|
||||||
{OBJECT_GLOBAL_GROUP, "Global-Group"},
|
,
|
||||||
{OBJECT_TREND_LOG_MULTIPLE, "Trend-Log-Multiple"},
|
{OBJECT_GLOBAL_GROUP, "Global-Group"}
|
||||||
{OBJECT_LOAD_CONTROL, "Load-Control"},
|
,
|
||||||
{OBJECT_STRUCTURED_VIEW, "Structured-View"},
|
{OBJECT_TREND_LOG_MULTIPLE, "Trend-Log-Multiple"}
|
||||||
|
,
|
||||||
|
{OBJECT_LOAD_CONTROL, "Load-Control"}
|
||||||
|
,
|
||||||
|
{OBJECT_STRUCTURED_VIEW, "Structured-View"}
|
||||||
|
,
|
||||||
|
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
/* Enumerated values 0-127 are reserved for definition by ASHRAE.
|
/* Enumerated values 0-127 are reserved for definition by ASHRAE.
|
||||||
@@ -566,58 +572,112 @@ INDTEXT_DATA bacnet_property_names[] = {
|
|||||||
,
|
,
|
||||||
{PROP_PROFILE_NAME, "profile-name"}
|
{PROP_PROFILE_NAME, "profile-name"}
|
||||||
,
|
,
|
||||||
{PROP_AUTO_SLAVE_DISCOVERY, "auto-slave-discovery"},
|
{PROP_AUTO_SLAVE_DISCOVERY, "auto-slave-discovery"}
|
||||||
{PROP_MANUAL_SLAVE_ADDRESS_BINDING, "manual-slave-address-binding"},
|
,
|
||||||
{PROP_SLAVE_ADDRESS_BINDING, "slave-address-binding"},
|
{PROP_MANUAL_SLAVE_ADDRESS_BINDING, "manual-slave-address-binding"}
|
||||||
{PROP_SLAVE_PROXY_ENABLE, "slave-proxy-enable"},
|
,
|
||||||
{PROP_LAST_NOTIFY_TIME, "last-notify-time"},
|
{PROP_SLAVE_ADDRESS_BINDING, "slave-address-binding"}
|
||||||
{PROP_SCHEDULE_DEFAULT, "schedule-default"},
|
,
|
||||||
{PROP_ACCEPTED_MODES, "accepted-modes"},
|
{PROP_SLAVE_PROXY_ENABLE, "slave-proxy-enable"}
|
||||||
{PROP_ADJUST_VALUE, "adjust-value"},
|
,
|
||||||
{PROP_COUNT, "count"},
|
{PROP_LAST_NOTIFY_TIME, "last-notify-time"}
|
||||||
{PROP_COUNT_BEFORE_CHANGE, "count-before-change"},
|
,
|
||||||
{PROP_COUNT_CHANGE_TIME, "count-change-time"},
|
{PROP_SCHEDULE_DEFAULT, "schedule-default"}
|
||||||
{PROP_COV_PERIOD, "COV-period"},
|
,
|
||||||
{PROP_INPUT_REFERENCE, "input-reference"},
|
{PROP_ACCEPTED_MODES, "accepted-modes"}
|
||||||
{PROP_LIMIT_MONITORING_INTERVAL, "limit-monitoring-interval"},
|
,
|
||||||
{PROP_LOGGING_DEVICE, "logging-device"},
|
{PROP_ADJUST_VALUE, "adjust-value"}
|
||||||
{PROP_LOGGING_RECORD, "logging-record"},
|
,
|
||||||
{PROP_PRESCALE, "prescale"},
|
{PROP_COUNT, "count"}
|
||||||
{PROP_PULSE_RATE, "pulse-rate"},
|
,
|
||||||
{PROP_SCALE, "scale"},
|
{PROP_COUNT_BEFORE_CHANGE, "count-before-change"}
|
||||||
{PROP_SCALE_FACTOR, "scale-factor"},
|
,
|
||||||
{PROP_UPDATE_TIME, "update-time"},
|
{PROP_COUNT_CHANGE_TIME, "count-change-time"}
|
||||||
{PROP_VALUE_BEFORE_CHANGE, "value-before-change"},
|
,
|
||||||
{PROP_VALUE_SET, "value-set"},
|
{PROP_COV_PERIOD, "COV-period"}
|
||||||
{PROP_VALUE_CHANGE_TIME, "value-change-time"},
|
,
|
||||||
{PROP_ALIGN_INTERVALS, "align-intervals"},
|
{PROP_INPUT_REFERENCE, "input-reference"}
|
||||||
{PROP_GROUP_MEMBER_NAMES, "group-member-names"},
|
,
|
||||||
{PROP_INTERVAL_OFFSET, "interval-offset"},
|
{PROP_LIMIT_MONITORING_INTERVAL, "limit-monitoring-interval"}
|
||||||
{PROP_LAST_RESTART_REASON, "last-restart-reason"},
|
,
|
||||||
{PROP_LOGGING_TYPE, "logging-type"},
|
{PROP_LOGGING_DEVICE, "logging-device"}
|
||||||
{PROP_MEMBER_STATUS_FLAGS, "member-status-flags"},
|
,
|
||||||
{PROP_NOTIFICATION_PERIOD, "notification-period"},
|
{PROP_LOGGING_RECORD, "logging-record"}
|
||||||
{PROP_PREVIOUS_NOTIFY_RECORD, "previous-notify-record"},
|
,
|
||||||
{PROP_REQUESTED_UPDATE_INTERVAL, "requested-update-interval"},
|
{PROP_PRESCALE, "prescale"}
|
||||||
{PROP_RESTART_NOTIFICATION_RECIPIENTS, "restart-notification-recipients"},
|
,
|
||||||
{PROP_TIME_OF_DEVICE_RESTART, "time-of-device-restart"},
|
{PROP_PULSE_RATE, "pulse-rate"}
|
||||||
{PROP_TIME_SYNCHRONIZATION_INTERVAL, "time-synchronization-interval"},
|
,
|
||||||
{PROP_TRIGGER, "trigger"},
|
{PROP_SCALE, "scale"}
|
||||||
{PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS, "UTC-time-synchronization-recipients"},
|
,
|
||||||
{PROP_NODE_SUBTYPE, "node-subtype"},
|
{PROP_SCALE_FACTOR, "scale-factor"}
|
||||||
{PROP_NODE_TYPE, "node-type"},
|
,
|
||||||
{PROP_STRUCTURED_OBJECT_LIST, "structured-object-list"},
|
{PROP_UPDATE_TIME, "update-time"}
|
||||||
{PROP_SUBORDINATE_ANNOTATIONS, "subordinate-annotations"},
|
,
|
||||||
{PROP_SUBORDINATE_LIST, "subordinate-list"},
|
{PROP_VALUE_BEFORE_CHANGE, "value-before-change"}
|
||||||
{PROP_ACTUAL_SHED_LEVEL, "actual-shed-level"},
|
,
|
||||||
{PROP_DUTY_WINDOW, "duty-window"},
|
{PROP_VALUE_SET, "value-set"}
|
||||||
{PROP_EXPECTED_SHED_LEVEL, "expected-shed-level"},
|
,
|
||||||
{PROP_FULL_DUTY_BASELINE, "full-duty-baseline"},
|
{PROP_VALUE_CHANGE_TIME, "value-change-time"}
|
||||||
{PROP_REQUESTED_SHED_LEVEL, "requested-shed-level"},
|
,
|
||||||
{PROP_SHED_DURATION, "shed-duration"},
|
{PROP_ALIGN_INTERVALS, "align-intervals"}
|
||||||
{PROP_SHED_LEVEL_DESCRIPTIONS, "shed-level-descriptions"},
|
,
|
||||||
{PROP_SHED_LEVELS, "shed-levels"},
|
{PROP_GROUP_MEMBER_NAMES, "group-member-names"}
|
||||||
{PROP_STATE_DESCRIPTION, "state-descriptions"},
|
,
|
||||||
|
{PROP_INTERVAL_OFFSET, "interval-offset"}
|
||||||
|
,
|
||||||
|
{PROP_LAST_RESTART_REASON, "last-restart-reason"}
|
||||||
|
,
|
||||||
|
{PROP_LOGGING_TYPE, "logging-type"}
|
||||||
|
,
|
||||||
|
{PROP_MEMBER_STATUS_FLAGS, "member-status-flags"}
|
||||||
|
,
|
||||||
|
{PROP_NOTIFICATION_PERIOD, "notification-period"}
|
||||||
|
,
|
||||||
|
{PROP_PREVIOUS_NOTIFY_RECORD, "previous-notify-record"}
|
||||||
|
,
|
||||||
|
{PROP_REQUESTED_UPDATE_INTERVAL, "requested-update-interval"}
|
||||||
|
,
|
||||||
|
{PROP_RESTART_NOTIFICATION_RECIPIENTS,
|
||||||
|
"restart-notification-recipients"}
|
||||||
|
,
|
||||||
|
{PROP_TIME_OF_DEVICE_RESTART, "time-of-device-restart"}
|
||||||
|
,
|
||||||
|
{PROP_TIME_SYNCHRONIZATION_INTERVAL, "time-synchronization-interval"}
|
||||||
|
,
|
||||||
|
{PROP_TRIGGER, "trigger"}
|
||||||
|
,
|
||||||
|
{PROP_UTC_TIME_SYNCHRONIZATION_RECIPIENTS,
|
||||||
|
"UTC-time-synchronization-recipients"}
|
||||||
|
,
|
||||||
|
{PROP_NODE_SUBTYPE, "node-subtype"}
|
||||||
|
,
|
||||||
|
{PROP_NODE_TYPE, "node-type"}
|
||||||
|
,
|
||||||
|
{PROP_STRUCTURED_OBJECT_LIST, "structured-object-list"}
|
||||||
|
,
|
||||||
|
{PROP_SUBORDINATE_ANNOTATIONS, "subordinate-annotations"}
|
||||||
|
,
|
||||||
|
{PROP_SUBORDINATE_LIST, "subordinate-list"}
|
||||||
|
,
|
||||||
|
{PROP_ACTUAL_SHED_LEVEL, "actual-shed-level"}
|
||||||
|
,
|
||||||
|
{PROP_DUTY_WINDOW, "duty-window"}
|
||||||
|
,
|
||||||
|
{PROP_EXPECTED_SHED_LEVEL, "expected-shed-level"}
|
||||||
|
,
|
||||||
|
{PROP_FULL_DUTY_BASELINE, "full-duty-baseline"}
|
||||||
|
,
|
||||||
|
{PROP_REQUESTED_SHED_LEVEL, "requested-shed-level"}
|
||||||
|
,
|
||||||
|
{PROP_SHED_DURATION, "shed-duration"}
|
||||||
|
,
|
||||||
|
{PROP_SHED_LEVEL_DESCRIPTIONS, "shed-level-descriptions"}
|
||||||
|
,
|
||||||
|
{PROP_SHED_LEVELS, "shed-levels"}
|
||||||
|
,
|
||||||
|
{PROP_STATE_DESCRIPTION, "state-descriptions"}
|
||||||
|
,
|
||||||
|
|
||||||
{0, NULL}
|
{0, NULL}
|
||||||
/* Enumerated values 0-511 are reserved for definition by ASHRAE.
|
/* Enumerated values 0-511 are reserved for definition by ASHRAE.
|
||||||
|
|||||||
+34
-28
@@ -273,6 +273,7 @@ int cov_notify_decode_service_request(uint8_t * apdu,
|
|||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
12.11.38Active_COV_Subscriptions
|
12.11.38Active_COV_Subscriptions
|
||||||
The Active_COV_Subscriptions property is a List of BACnetCOVSubscription, each of which consists of a Recipient, a
|
The Active_COV_Subscriptions property is a List of BACnetCOVSubscription, each of which consists of a Recipient, a
|
||||||
@@ -291,10 +292,8 @@ SubscribeCOV-Request ::= SEQUENCE {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int cov_subscribe_encode_adpu(
|
int cov_subscribe_encode_adpu(uint8_t * apdu,
|
||||||
uint8_t * apdu,
|
uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data)
|
||||||
uint8_t invoke_id,
|
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data)
|
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
@@ -317,10 +316,10 @@ int cov_subscribe_encode_adpu(
|
|||||||
data->monitoredObjectIdentifier.instance);
|
data->monitoredObjectIdentifier.instance);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
/*
|
/*
|
||||||
If both the 'Issue Confirmed Notifications' and
|
If both the 'Issue Confirmed Notifications' and
|
||||||
'Lifetime' parameters are absent, then this shall
|
'Lifetime' parameters are absent, then this shall
|
||||||
indicate a cancellation request.
|
indicate a cancellation request.
|
||||||
*/
|
*/
|
||||||
if (!data->cancellationRequest) {
|
if (!data->cancellationRequest) {
|
||||||
/* tag 2 - issueConfirmedNotifications */
|
/* tag 2 - issueConfirmedNotifications */
|
||||||
len = encode_context_boolean(&apdu[apdu_len],
|
len = encode_context_boolean(&apdu[apdu_len],
|
||||||
@@ -412,10 +411,8 @@ BACnetPropertyReference ::= SEQUENCE {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int cov_subscribe_property_encode_adpu(
|
int cov_subscribe_property_encode_adpu(uint8_t * apdu,
|
||||||
uint8_t * apdu,
|
uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data)
|
||||||
uint8_t invoke_id,
|
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data)
|
|
||||||
{
|
{
|
||||||
int len = 0; /* length of each encoding */
|
int len = 0; /* length of each encoding */
|
||||||
int apdu_len = 0; /* total length of the apdu, return value */
|
int apdu_len = 0; /* total length of the apdu, return value */
|
||||||
@@ -455,7 +452,7 @@ int cov_subscribe_property_encode_adpu(
|
|||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
if (data->monitoredProperty.propertyArrayIndex != BACNET_ARRAY_ALL) {
|
if (data->monitoredProperty.propertyArrayIndex != BACNET_ARRAY_ALL) {
|
||||||
len = encode_context_unsigned(&apdu[apdu_len],
|
len = encode_context_unsigned(&apdu[apdu_len],
|
||||||
1, data->monitoredProperty.propertyArrayIndex);
|
1, data->monitoredProperty.propertyArrayIndex);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -648,7 +645,8 @@ int ucov_notify_decode_apdu(uint8_t * apdu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cov_subscribe_decode_apdu(uint8_t * apdu,
|
int cov_subscribe_decode_apdu(uint8_t * apdu,
|
||||||
unsigned apdu_len, uint8_t * invoke_id, BACNET_SUBSCRIBE_COV_DATA * data)
|
unsigned apdu_len, uint8_t * invoke_id,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA * data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned offset = 0;
|
unsigned offset = 0;
|
||||||
@@ -675,7 +673,8 @@ int cov_subscribe_decode_apdu(uint8_t * apdu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cov_subscribe_property_decode_apdu(uint8_t * apdu,
|
int cov_subscribe_property_decode_apdu(uint8_t * apdu,
|
||||||
unsigned apdu_len, uint8_t * invoke_id, BACNET_SUBSCRIBE_COV_DATA * data)
|
unsigned apdu_len, uint8_t * invoke_id,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA * data)
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
unsigned offset = 0;
|
unsigned offset = 0;
|
||||||
@@ -716,11 +715,8 @@ void npdu_encode_npdu_data(BACNET_NPDU_DATA * npdu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
int datalink_send_pdu(
|
int datalink_send_pdu(BACNET_ADDRESS * dest,
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_NPDU_DATA * npdu_data, uint8_t * pdu, unsigned pdu_len)
|
||||||
BACNET_NPDU_DATA * npdu_data,
|
|
||||||
uint8_t * pdu,
|
|
||||||
unsigned pdu_len)
|
|
||||||
{
|
{
|
||||||
(void) dest;
|
(void) dest;
|
||||||
(void) npdu_data;
|
(void) npdu_data;
|
||||||
@@ -733,7 +729,7 @@ int datalink_send_pdu(
|
|||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
void datalink_get_broadcast_address(BACNET_ADDRESS * dest)
|
void datalink_get_broadcast_address(BACNET_ADDRESS * dest)
|
||||||
{
|
{
|
||||||
(void)dest;
|
(void) dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
@@ -825,7 +821,8 @@ void testCOVNotify(Test * pTest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void testCOVSubscribeData(Test * pTest,
|
void testCOVSubscribeData(Test * pTest,
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data, BACNET_SUBSCRIBE_COV_DATA * test_data)
|
BACNET_SUBSCRIBE_COV_DATA * data,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA * test_data)
|
||||||
{
|
{
|
||||||
ct_test(pTest,
|
ct_test(pTest,
|
||||||
test_data->subscriberProcessIdentifier ==
|
test_data->subscriberProcessIdentifier ==
|
||||||
@@ -836,20 +833,29 @@ void testCOVSubscribeData(Test * pTest,
|
|||||||
ct_test(pTest,
|
ct_test(pTest,
|
||||||
test_data->monitoredObjectIdentifier.instance ==
|
test_data->monitoredObjectIdentifier.instance ==
|
||||||
data->monitoredObjectIdentifier.instance);
|
data->monitoredObjectIdentifier.instance);
|
||||||
ct_test(pTest, test_data->cancellationRequest == data->cancellationRequest);
|
ct_test(pTest,
|
||||||
|
test_data->cancellationRequest == data->cancellationRequest);
|
||||||
if (!test_data->cancellationRequest) {
|
if (!test_data->cancellationRequest) {
|
||||||
ct_test(pTest, test_data->issueConfirmedNotifications == data->issueConfirmedNotifications);
|
ct_test(pTest,
|
||||||
|
test_data->issueConfirmedNotifications ==
|
||||||
|
data->issueConfirmedNotifications);
|
||||||
ct_test(pTest, test_data->lifetime == data->lifetime);
|
ct_test(pTest, test_data->lifetime == data->lifetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void testCOVSubscribePropertyData(Test * pTest,
|
void testCOVSubscribePropertyData(Test * pTest,
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data, BACNET_SUBSCRIBE_COV_DATA * test_data)
|
BACNET_SUBSCRIBE_COV_DATA * data,
|
||||||
|
BACNET_SUBSCRIBE_COV_DATA * test_data)
|
||||||
{
|
{
|
||||||
testCOVSubscribeData(pTest, data, test_data);
|
testCOVSubscribeData(pTest, data, test_data);
|
||||||
ct_test(pTest, test_data->monitoredProperty.propertyIdentifier == data->monitoredProperty.propertyIdentifier);
|
ct_test(pTest,
|
||||||
ct_test(pTest, test_data->monitoredProperty.propertyArrayIndex == data->monitoredProperty.propertyArrayIndex);
|
test_data->monitoredProperty.propertyIdentifier ==
|
||||||
ct_test(pTest, test_data->covIncrementPresent == data->covIncrementPresent);
|
data->monitoredProperty.propertyIdentifier);
|
||||||
|
ct_test(pTest,
|
||||||
|
test_data->monitoredProperty.propertyArrayIndex ==
|
||||||
|
data->monitoredProperty.propertyArrayIndex);
|
||||||
|
ct_test(pTest,
|
||||||
|
test_data->covIncrementPresent == data->covIncrementPresent);
|
||||||
if (test_data->covIncrementPresent) {
|
if (test_data->covIncrementPresent) {
|
||||||
ct_test(pTest, test_data->covIncrement == data->covIncrement);
|
ct_test(pTest, test_data->covIncrement == data->covIncrement);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-15
@@ -58,19 +58,19 @@ typedef struct BACnet_COV_Data {
|
|||||||
} BACNET_COV_DATA;
|
} BACNET_COV_DATA;
|
||||||
|
|
||||||
typedef struct BACnet_Property_Reference {
|
typedef struct BACnet_Property_Reference {
|
||||||
BACNET_PROPERTY_ID propertyIdentifier;
|
BACNET_PROPERTY_ID propertyIdentifier;
|
||||||
unsigned propertyArrayIndex; /* optional */
|
unsigned propertyArrayIndex; /* optional */
|
||||||
} BACNET_PROPERTY_REFERENCE;
|
} BACNET_PROPERTY_REFERENCE;
|
||||||
|
|
||||||
typedef struct BACnet_Subscribe_COV_Data {
|
typedef struct BACnet_Subscribe_COV_Data {
|
||||||
uint32_t subscriberProcessIdentifier;
|
uint32_t subscriberProcessIdentifier;
|
||||||
BACNET_OBJECT_ID monitoredObjectIdentifier;
|
BACNET_OBJECT_ID monitoredObjectIdentifier;
|
||||||
bool cancellationRequest; /* true if this is a cancellation request */
|
bool cancellationRequest; /* true if this is a cancellation request */
|
||||||
bool issueConfirmedNotifications; /* optional */
|
bool issueConfirmedNotifications; /* optional */
|
||||||
unsigned lifetime; /* optional */
|
unsigned lifetime; /* optional */
|
||||||
BACNET_PROPERTY_REFERENCE monitoredProperty;
|
BACNET_PROPERTY_REFERENCE monitoredProperty;
|
||||||
bool covIncrementPresent; /* true if present */
|
bool covIncrementPresent; /* true if present */
|
||||||
float covIncrement; /* optional */
|
float covIncrement; /* optional */
|
||||||
} BACNET_SUBSCRIBE_COV_DATA;
|
} BACNET_SUBSCRIBE_COV_DATA;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -97,18 +97,14 @@ extern "C" {
|
|||||||
int cov_subscribe_property_decode_service_request(uint8_t * apdu,
|
int cov_subscribe_property_decode_service_request(uint8_t * apdu,
|
||||||
unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA * data);
|
unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA * data);
|
||||||
|
|
||||||
int cov_subscribe_property_encode_adpu(
|
int cov_subscribe_property_encode_adpu(uint8_t * apdu,
|
||||||
uint8_t * apdu,
|
uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data);
|
||||||
uint8_t invoke_id,
|
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data);
|
|
||||||
|
|
||||||
int cov_subscribe_decode_service_request(uint8_t * apdu,
|
int cov_subscribe_decode_service_request(uint8_t * apdu,
|
||||||
unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA * data);
|
unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA * data);
|
||||||
|
|
||||||
int cov_subscribe_encode_adpu(
|
int cov_subscribe_encode_adpu(uint8_t * apdu,
|
||||||
uint8_t * apdu,
|
uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data);
|
||||||
uint8_t invoke_id,
|
|
||||||
BACNET_SUBSCRIBE_COV_DATA * data);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|||||||
+7
-13
@@ -73,19 +73,13 @@
|
|||||||
#elif defined(BACDL_TEST)
|
#elif defined(BACDL_TEST)
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
|
|
||||||
extern int datalink_send_pdu(
|
extern int datalink_send_pdu(BACNET_ADDRESS * dest,
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_NPDU_DATA * npdu_data, uint8_t * pdu, unsigned pdu_len);
|
||||||
BACNET_NPDU_DATA * npdu_data,
|
extern uint16_t datalink_receive(BACNET_ADDRESS * src,
|
||||||
uint8_t * pdu,
|
uint8_t * pdu, uint16_t max_pdu, unsigned timeout);
|
||||||
unsigned pdu_len);
|
extern void datalink_cleanup(void);
|
||||||
extern uint16_t datalink_receive(
|
extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest);
|
||||||
BACNET_ADDRESS * src,
|
extern void bip_get_my_address(BACNET_ADDRESS * my_address);
|
||||||
uint8_t * pdu,
|
|
||||||
uint16_t max_pdu,
|
|
||||||
unsigned timeout);
|
|
||||||
extern void datalink_cleanup(void);
|
|
||||||
extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest);
|
|
||||||
extern void bip_get_my_address(BACNET_ADDRESS * my_address);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+153
-173
@@ -47,90 +47,82 @@
|
|||||||
|
|
||||||
static bool is_leap_year(uint16_t year)
|
static bool is_leap_year(uint16_t year)
|
||||||
{
|
{
|
||||||
if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
|
if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
|
||||||
return (true);
|
return (true);
|
||||||
else
|
else
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t month_days(uint16_t year, uint8_t month)
|
static uint8_t month_days(uint16_t year, uint8_t month)
|
||||||
{
|
{
|
||||||
/* note: start with a zero in the first element to save us from a
|
/* note: start with a zero in the first element to save us from a
|
||||||
month - 1 calculation in the lookup */
|
month - 1 calculation in the lookup */
|
||||||
int month_days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
|
int month_days[13] =
|
||||||
|
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||||
|
|
||||||
/* February */
|
/* February */
|
||||||
if ((month == 2) && is_leap_year(year))
|
if ((month == 2) && is_leap_year(year))
|
||||||
return 29;
|
return 29;
|
||||||
else if (month >= 1 && month <= 12)
|
else if (month >= 1 && month <= 12)
|
||||||
return month_days[month];
|
return month_days[month];
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t days_since_epoch(uint16_t year, uint8_t month, uint8_t day)
|
static uint32_t days_since_epoch(uint16_t year, uint8_t month, uint8_t day)
|
||||||
{
|
{
|
||||||
uint32_t days = 0; /* return value */
|
uint32_t days = 0; /* return value */
|
||||||
uint8_t monthdays; /* days in a month */
|
uint8_t monthdays; /* days in a month */
|
||||||
uint16_t years = 0; /* loop counter for years */
|
uint16_t years = 0; /* loop counter for years */
|
||||||
uint8_t months = 0; /* loop counter for months */
|
uint8_t months = 0; /* loop counter for months */
|
||||||
|
|
||||||
monthdays = month_days(year, month);
|
monthdays = month_days(year, month);
|
||||||
if ((year >= 1900) && (monthdays) &&
|
if ((year >= 1900) && (monthdays) && (day >= 1) && (day <= monthdays)) {
|
||||||
(day >= 1) && (day <= monthdays))
|
for (years = 1900; years < year; years++) {
|
||||||
{
|
days += 365;
|
||||||
for (years = 1900; years < year; years++)
|
if (is_leap_year(years))
|
||||||
{
|
days++;
|
||||||
days += 365;
|
}
|
||||||
if (is_leap_year(years))
|
for (months = 1; months < month; months++) {
|
||||||
days++;
|
days += month_days(years, months);
|
||||||
|
}
|
||||||
|
days += (day - 1);
|
||||||
}
|
}
|
||||||
for (months = 1; months < month; months++)
|
|
||||||
{
|
|
||||||
days += month_days(years, months);
|
|
||||||
}
|
|
||||||
days += (day - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (days);
|
return (days);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void days_since_epoch_into_ymd(
|
static void days_since_epoch_into_ymd(uint32_t days,
|
||||||
uint32_t days,
|
uint16_t * pYear, uint8_t * pMonth, uint8_t * pDay)
|
||||||
uint16_t *pYear,
|
|
||||||
uint8_t *pMonth,
|
|
||||||
uint8_t *pDay)
|
|
||||||
{
|
{
|
||||||
int year = 1900;
|
int year = 1900;
|
||||||
int month = 1;
|
int month = 1;
|
||||||
int day = 1;
|
int day = 1;
|
||||||
|
|
||||||
while (days >= 365)
|
while (days >= 365) {
|
||||||
{
|
if ((is_leap_year(year)) && days == 365)
|
||||||
if ((is_leap_year(year)) && days == 365)
|
break;
|
||||||
break;
|
days -= 365;
|
||||||
days -= 365;
|
if (is_leap_year(year))
|
||||||
if (is_leap_year(year))
|
--days;
|
||||||
--days;
|
year++;
|
||||||
year++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (days >= month_days(year, month))
|
while (days >= month_days(year, month)) {
|
||||||
{
|
days -= month_days(year, month);
|
||||||
days -= month_days(year, month);
|
month++;
|
||||||
month++;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
day += days;
|
day += days;
|
||||||
|
|
||||||
if (pYear)
|
if (pYear)
|
||||||
*pYear = year;
|
*pYear = year;
|
||||||
if (pMonth)
|
if (pMonth)
|
||||||
*pMonth = month;
|
*pMonth = month;
|
||||||
if (pDay)
|
if (pDay)
|
||||||
*pDay = day;
|
*pDay = day;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -138,7 +130,7 @@ static void days_since_epoch_into_ymd(
|
|||||||
/* wday 1=Monday...7=Sunday */
|
/* wday 1=Monday...7=Sunday */
|
||||||
static uint8_t day_of_week(uint16_t year, uint8_t month, uint8_t day)
|
static uint8_t day_of_week(uint16_t year, uint8_t month, uint8_t day)
|
||||||
{
|
{
|
||||||
return ((days_since_epoch(year, month, day)%7)+1);
|
return ((days_since_epoch(year, month, day) % 7) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if the date1 is the same as date2, return is 0
|
/* if the date1 is the same as date2, return is 0
|
||||||
@@ -149,11 +141,11 @@ int datetime_compare_date(BACNET_DATE * date1, BACNET_DATE * date2)
|
|||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
if (date1 && date2) {
|
if (date1 && date2) {
|
||||||
diff = (int)date1->year - (int)date2->year;
|
diff = (int) date1->year - (int) date2->year;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
diff = (int)date1->month - (int)date2->month;
|
diff = (int) date1->month - (int) date2->month;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
diff = (int)date1->day - (int)date2->day;
|
diff = (int) date1->day - (int) date2->day;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,13 +161,14 @@ int datetime_compare_time(BACNET_TIME * time1, BACNET_TIME * time2)
|
|||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
if (time1 && time2) {
|
if (time1 && time2) {
|
||||||
diff = (int)time1->hour - (int)time2->hour;
|
diff = (int) time1->hour - (int) time2->hour;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
diff = (int)time1->min - (int)time2->min;
|
diff = (int) time1->min - (int) time2->min;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
diff = (int)time1->sec - (int)time2->sec;
|
diff = (int) time1->sec - (int) time2->sec;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
diff = (int)time1->hundredths - (int)time2->hundredths;
|
diff =
|
||||||
|
(int) time1->hundredths - (int) time2->hundredths;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,14 +183,14 @@ int datetime_compare_time(BACNET_TIME * time1, BACNET_TIME * time2)
|
|||||||
int datetime_compare(BACNET_DATE_TIME * datetime1,
|
int datetime_compare(BACNET_DATE_TIME * datetime1,
|
||||||
BACNET_DATE_TIME * datetime2)
|
BACNET_DATE_TIME * datetime2)
|
||||||
{
|
{
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
diff = datetime_compare_date(&datetime1->date,&datetime2->date);
|
diff = datetime_compare_date(&datetime1->date, &datetime2->date);
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
diff = datetime_compare_time(&datetime1->time,&datetime2->time);
|
diff = datetime_compare_time(&datetime1->time, &datetime2->time);
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void datetime_copy_date(BACNET_DATE * dest_date, BACNET_DATE * src_date)
|
void datetime_copy_date(BACNET_DATE * dest_date, BACNET_DATE * src_date)
|
||||||
@@ -220,12 +213,11 @@ void datetime_copy_time(BACNET_TIME * dest_time, BACNET_TIME * src_time)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void datetime_copy(
|
void datetime_copy(BACNET_DATE_TIME * dest_datetime,
|
||||||
BACNET_DATE_TIME * dest_datetime,
|
BACNET_DATE_TIME * src_datetime)
|
||||||
BACNET_DATE_TIME * src_datetime)
|
|
||||||
{
|
{
|
||||||
datetime_copy_time(&dest_datetime->time,&src_datetime->time);
|
datetime_copy_time(&dest_datetime->time, &src_datetime->time);
|
||||||
datetime_copy_date(&dest_datetime->date,&src_datetime->date);
|
datetime_copy_date(&dest_datetime->date, &src_datetime->date);
|
||||||
}
|
}
|
||||||
|
|
||||||
void datetime_set_date(BACNET_DATE * bdate,
|
void datetime_set_date(BACNET_DATE * bdate,
|
||||||
@@ -235,7 +227,7 @@ void datetime_set_date(BACNET_DATE * bdate,
|
|||||||
bdate->year = year;
|
bdate->year = year;
|
||||||
bdate->month = month;
|
bdate->month = month;
|
||||||
bdate->day = day;
|
bdate->day = day;
|
||||||
bdate->wday = day_of_week(year,month,day);
|
bdate->wday = day_of_week(year, month, day);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,8 +243,7 @@ void datetime_set_time(BACNET_TIME * btime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void datetime_set(BACNET_DATE_TIME * bdatetime,
|
void datetime_set(BACNET_DATE_TIME * bdatetime,
|
||||||
BACNET_DATE * bdate,
|
BACNET_DATE * bdate, BACNET_TIME * btime)
|
||||||
BACNET_TIME * btime)
|
|
||||||
{
|
{
|
||||||
if (bdate && btime && bdatetime) {
|
if (bdate && btime && bdatetime) {
|
||||||
bdatetime->time.hour = btime->hour;
|
bdatetime->time.hour = btime->hour;
|
||||||
@@ -274,7 +265,7 @@ void datetime_set_values(BACNET_DATE_TIME * bdatetime,
|
|||||||
bdatetime->date.year = year;
|
bdatetime->date.year = year;
|
||||||
bdatetime->date.month = month;
|
bdatetime->date.month = month;
|
||||||
bdatetime->date.day = day;
|
bdatetime->date.day = day;
|
||||||
bdatetime->date.wday = day_of_week(year,month,day);
|
bdatetime->date.wday = day_of_week(year, month, day);
|
||||||
bdatetime->time.hour = hour;
|
bdatetime->time.hour = hour;
|
||||||
bdatetime->time.min = minute;
|
bdatetime->time.min = minute;
|
||||||
bdatetime->time.sec = seconds;
|
bdatetime->time.sec = seconds;
|
||||||
@@ -289,20 +280,18 @@ static uint32_t seconds_since_midnight(uint8_t hours, uint8_t minutes,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void seconds_since_midnight_into_hms(uint32_t seconds,
|
static void seconds_since_midnight_into_hms(uint32_t seconds,
|
||||||
uint8_t * pHours,
|
uint8_t * pHours, uint8_t * pMinutes, uint8_t * pSeconds)
|
||||||
uint8_t *pMinutes,
|
|
||||||
uint8_t *pSeconds)
|
|
||||||
{
|
{
|
||||||
uint8_t hour = 0;
|
uint8_t hour = 0;
|
||||||
uint8_t minute = 0;
|
uint8_t minute = 0;
|
||||||
|
|
||||||
hour = seconds / (60 * 60);
|
hour = seconds / (60 * 60);
|
||||||
seconds -= (hour * 60 * 60);
|
seconds -= (hour * 60 * 60);
|
||||||
minute = seconds / 60;
|
minute = seconds / 60;
|
||||||
seconds -= (minute * 60);
|
seconds -= (minute * 60);
|
||||||
|
|
||||||
if (pHours)
|
if (pHours)
|
||||||
*pHours = hour;
|
*pHours = hour;
|
||||||
if (pMinutes)
|
if (pMinutes)
|
||||||
*pMinutes = minute;
|
*pMinutes = minute;
|
||||||
if (pSeconds)
|
if (pSeconds)
|
||||||
@@ -316,37 +305,27 @@ void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes)
|
|||||||
uint32_t days = 0;
|
uint32_t days = 0;
|
||||||
|
|
||||||
/* convert bdatetime to seconds and days */
|
/* convert bdatetime to seconds and days */
|
||||||
bdatetime_minutes = seconds_since_midnight(
|
bdatetime_minutes = seconds_since_midnight(bdatetime->time.hour,
|
||||||
bdatetime->time.hour,
|
bdatetime->time.min, bdatetime->time.sec) / 60;
|
||||||
bdatetime->time.min,
|
bdatetime_days = days_since_epoch(bdatetime->date.year,
|
||||||
bdatetime->time.sec) / 60;
|
bdatetime->date.month, bdatetime->date.day);
|
||||||
bdatetime_days = days_since_epoch(
|
|
||||||
bdatetime->date.year,
|
|
||||||
bdatetime->date.month,
|
|
||||||
bdatetime->date.day);
|
|
||||||
|
|
||||||
/* add */
|
/* add */
|
||||||
days = minutes / (24*60);
|
days = minutes / (24 * 60);
|
||||||
bdatetime_days += days;
|
bdatetime_days += days;
|
||||||
minutes -= (days * 24 * 60);
|
minutes -= (days * 24 * 60);
|
||||||
bdatetime_minutes += minutes;
|
bdatetime_minutes += minutes;
|
||||||
days = bdatetime_minutes / (24*60);
|
days = bdatetime_minutes / (24 * 60);
|
||||||
bdatetime_days += days;
|
bdatetime_days += days;
|
||||||
|
|
||||||
/* convert bdatetime from seconds and days */
|
/* convert bdatetime from seconds and days */
|
||||||
seconds_since_midnight_into_hms(bdatetime_minutes * 60,
|
seconds_since_midnight_into_hms(bdatetime_minutes * 60,
|
||||||
&bdatetime->time.hour,
|
&bdatetime->time.hour, &bdatetime->time.min, &bdatetime->time.sec);
|
||||||
&bdatetime->time.min,
|
days_since_epoch_into_ymd(bdatetime_days,
|
||||||
&bdatetime->time.sec);
|
|
||||||
days_since_epoch_into_ymd(
|
|
||||||
bdatetime_days,
|
|
||||||
&bdatetime->date.year,
|
&bdatetime->date.year,
|
||||||
&bdatetime->date.month,
|
&bdatetime->date.month, &bdatetime->date.day);
|
||||||
&bdatetime->date.day);
|
bdatetime->date.wday = day_of_week(bdatetime->date.year,
|
||||||
bdatetime->date.wday = day_of_week(
|
bdatetime->date.month, bdatetime->date.day);
|
||||||
bdatetime->date.year,
|
|
||||||
bdatetime->date.month,
|
|
||||||
bdatetime->date.day);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
@@ -360,27 +339,27 @@ void testBACnetDateTimeAdd(Test * pTest)
|
|||||||
uint32_t minutes = 0;
|
uint32_t minutes = 0;
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0);
|
datetime_set_values(&bdatetime, 1900, 1, 1, 0, 0, 0, 0);
|
||||||
datetime_copy(&test_bdatetime,&bdatetime);
|
datetime_copy(&test_bdatetime, &bdatetime);
|
||||||
datetime_add_minutes(&bdatetime, minutes);
|
datetime_add_minutes(&bdatetime, minutes);
|
||||||
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
|
|
||||||
datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0);
|
datetime_set_values(&bdatetime, 1900, 1, 1, 0, 0, 0, 0);
|
||||||
datetime_add_minutes(&bdatetime, 60);
|
datetime_add_minutes(&bdatetime, 60);
|
||||||
datetime_set_values(&test_bdatetime, 1900,1,1,1,0,0,0);
|
datetime_set_values(&test_bdatetime, 1900, 1, 1, 1, 0, 0, 0);
|
||||||
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
|
|
||||||
datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0);
|
datetime_set_values(&bdatetime, 1900, 1, 1, 0, 0, 0, 0);
|
||||||
datetime_add_minutes(&bdatetime, (24*60));
|
datetime_add_minutes(&bdatetime, (24 * 60));
|
||||||
datetime_set_values(&test_bdatetime, 1900,1,2,0,0,0,0);
|
datetime_set_values(&test_bdatetime, 1900, 1, 2, 0, 0, 0, 0);
|
||||||
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
|
|
||||||
datetime_set_values(&bdatetime, 1900,1,1,0,0,0,0);
|
datetime_set_values(&bdatetime, 1900, 1, 1, 0, 0, 0, 0);
|
||||||
datetime_add_minutes(&bdatetime, (31*24*60));
|
datetime_add_minutes(&bdatetime, (31 * 24 * 60));
|
||||||
datetime_set_values(&test_bdatetime, 1900,2,1,0,0,0,0);
|
datetime_set_values(&test_bdatetime, 1900, 2, 1, 0, 0, 0, 0);
|
||||||
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
diff = datetime_compare(&test_bdatetime, &bdatetime);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
}
|
}
|
||||||
@@ -394,13 +373,14 @@ void testBACnetDateTimeSeconds(Test * pTest)
|
|||||||
uint32_t seconds = 0, test_seconds;
|
uint32_t seconds = 0, test_seconds;
|
||||||
|
|
||||||
for (hour = 0; hour < 24; hour++) {
|
for (hour = 0; hour < 24; hour++) {
|
||||||
for (minute = 0; minute < 60; minute+=3) {
|
for (minute = 0; minute < 60; minute += 3) {
|
||||||
for (second = 0; second < 60; second+=17) {
|
for (second = 0; second < 60; second += 17) {
|
||||||
seconds = seconds_since_midnight(hour, minute, second);
|
seconds = seconds_since_midnight(hour, minute, second);
|
||||||
seconds_since_midnight_into_hms(seconds,
|
seconds_since_midnight_into_hms(seconds,
|
||||||
&test_hour, &test_minute, &test_second);
|
&test_hour, &test_minute, &test_second);
|
||||||
test_seconds = seconds_since_midnight(
|
test_seconds =
|
||||||
test_hour, test_minute, test_second);
|
seconds_since_midnight(test_hour, test_minute,
|
||||||
|
test_second);
|
||||||
ct_test(pTest, seconds == test_seconds);
|
ct_test(pTest, seconds == test_seconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,56 +392,56 @@ void testBACnetDate(Test * pTest)
|
|||||||
BACNET_DATE bdate1, bdate2;
|
BACNET_DATE bdate1, bdate2;
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
datetime_set_date(&bdate1, 1900,1,1);
|
datetime_set_date(&bdate1, 1900, 1, 1);
|
||||||
datetime_copy_date(&bdate2, &bdate1);
|
datetime_copy_date(&bdate2, &bdate1);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
datetime_set_date(&bdate2, 1900,1,2);
|
datetime_set_date(&bdate2, 1900, 1, 2);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_date(&bdate2, 1900,2,1);
|
datetime_set_date(&bdate2, 1900, 2, 1);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_date(&bdate2, 1901,1,1);
|
datetime_set_date(&bdate2, 1901, 1, 1);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
|
|
||||||
/* midpoint */
|
/* midpoint */
|
||||||
datetime_set_date(&bdate1, 2007,7,15);
|
datetime_set_date(&bdate1, 2007, 7, 15);
|
||||||
datetime_copy_date(&bdate2, &bdate1);
|
datetime_copy_date(&bdate2, &bdate1);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
datetime_set_date(&bdate2, 2007,7,14);
|
datetime_set_date(&bdate2, 2007, 7, 14);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_date(&bdate2, 2007,7,1);
|
datetime_set_date(&bdate2, 2007, 7, 1);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_date(&bdate2, 2007,7,31);
|
datetime_set_date(&bdate2, 2007, 7, 31);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_date(&bdate2, 2007,8,15);
|
datetime_set_date(&bdate2, 2007, 8, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_date(&bdate2, 2007,12,15);
|
datetime_set_date(&bdate2, 2007, 12, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_date(&bdate2, 2007,6,15);
|
datetime_set_date(&bdate2, 2007, 6, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_date(&bdate2, 2007,1,15);
|
datetime_set_date(&bdate2, 2007, 1, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_date(&bdate2, 2006,7,15);
|
datetime_set_date(&bdate2, 2006, 7, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_date(&bdate2, 1900,7,15);
|
datetime_set_date(&bdate2, 1900, 7, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_date(&bdate2, 2008,7,15);
|
datetime_set_date(&bdate2, 2008, 7, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_date(&bdate2, 2154,7,15);
|
datetime_set_date(&bdate2, 2154, 7, 15);
|
||||||
diff = datetime_compare_date(&bdate1, &bdate2);
|
diff = datetime_compare_date(&bdate1, &bdate2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
|
|
||||||
@@ -473,44 +453,44 @@ void testBACnetTime(Test * pTest)
|
|||||||
BACNET_TIME btime1, btime2;
|
BACNET_TIME btime1, btime2;
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
datetime_set_time(&btime1, 0,0,0,0);
|
datetime_set_time(&btime1, 0, 0, 0, 0);
|
||||||
datetime_copy_time(&btime2, &btime1);
|
datetime_copy_time(&btime2, &btime1);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
|
|
||||||
datetime_set_time(&btime1, 23,59,59,99);
|
datetime_set_time(&btime1, 23, 59, 59, 99);
|
||||||
datetime_copy_time(&btime2, &btime1);
|
datetime_copy_time(&btime2, &btime1);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
|
|
||||||
/* midpoint */
|
/* midpoint */
|
||||||
datetime_set_time(&btime1, 12,30,30,50);
|
datetime_set_time(&btime1, 12, 30, 30, 50);
|
||||||
datetime_copy_time(&btime2, &btime1);
|
datetime_copy_time(&btime2, &btime1);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
datetime_set_time(&btime2, 12,30,30,51);
|
datetime_set_time(&btime2, 12, 30, 30, 51);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_time(&btime2, 12,30,31,50);
|
datetime_set_time(&btime2, 12, 30, 31, 50);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_time(&btime2, 12,31,30,50);
|
datetime_set_time(&btime2, 12, 31, 30, 50);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_time(&btime2, 13,30,30,50);
|
datetime_set_time(&btime2, 13, 30, 30, 50);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
|
|
||||||
datetime_set_time(&btime2, 12,30,30,49);
|
datetime_set_time(&btime2, 12, 30, 30, 49);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_time(&btime2, 12,30,29,50);
|
datetime_set_time(&btime2, 12, 30, 29, 50);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_time(&btime2, 12,29,30,50);
|
datetime_set_time(&btime2, 12, 29, 30, 50);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_time(&btime2, 11,30,30,50);
|
datetime_set_time(&btime2, 11, 30, 30, 50);
|
||||||
diff = datetime_compare_time(&btime1, &btime2);
|
diff = datetime_compare_time(&btime1, &btime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
|
|
||||||
@@ -524,59 +504,59 @@ void testBACnetDateTime(Test * pTest)
|
|||||||
BACNET_TIME btime;
|
BACNET_TIME btime;
|
||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
datetime_set_values(&bdatetime1, 1900,1,1,0,0,0,0);
|
datetime_set_values(&bdatetime1, 1900, 1, 1, 0, 0, 0, 0);
|
||||||
datetime_copy(&bdatetime2, &bdatetime1);
|
datetime_copy(&bdatetime2, &bdatetime1);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
datetime_set_time(&btime, 0,0,0,0);
|
datetime_set_time(&btime, 0, 0, 0, 0);
|
||||||
datetime_set_date(&bdate, 1900,1,1);
|
datetime_set_date(&bdate, 1900, 1, 1);
|
||||||
datetime_set(&bdatetime1, &bdate, &btime);
|
datetime_set(&bdatetime1, &bdate, &btime);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff == 0);
|
ct_test(pTest, diff == 0);
|
||||||
|
|
||||||
/* midpoint */
|
/* midpoint */
|
||||||
/* if datetime1 is before datetime2, returns negative */
|
/* if datetime1 is before datetime2, returns negative */
|
||||||
datetime_set_values(&bdatetime1, 2000,7,15,12,30,30,50);
|
datetime_set_values(&bdatetime1, 2000, 7, 15, 12, 30, 30, 50);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,12,30,30,51);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 12, 30, 30, 51);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,12,30,31,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 12, 30, 31, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,12,31,30,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 12, 31, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,13,30,30,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 13, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,16,12,30,30,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 16, 12, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,8,15,12,30,30,50);
|
datetime_set_values(&bdatetime2, 2000, 8, 15, 12, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2001,7,15,12,30,30,50);
|
datetime_set_values(&bdatetime2, 2001, 7, 15, 12, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff < 0);
|
ct_test(pTest, diff < 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,12,30,30,49);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 12, 30, 30, 49);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,12,30,29,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 12, 30, 29, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,12,29,30,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 12, 29, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,15,11,30,30,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 15, 11, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,7,14,12,30,30,50);
|
datetime_set_values(&bdatetime2, 2000, 7, 14, 12, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_values(&bdatetime2, 2000,6,15,12,30,30,50);
|
datetime_set_values(&bdatetime2, 2000, 6, 15, 12, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
datetime_set_values(&bdatetime2, 1999,7,15,12,30,30,50);
|
datetime_set_values(&bdatetime2, 1999, 7, 15, 12, 30, 30, 50);
|
||||||
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
diff = datetime_compare(&bdatetime1, &bdatetime2);
|
||||||
ct_test(pTest, diff > 0);
|
ct_test(pTest, diff > 0);
|
||||||
|
|
||||||
@@ -591,7 +571,7 @@ void testDateEpoch(Test * pTest)
|
|||||||
uint8_t month = 0, test_month = 0;
|
uint8_t month = 0, test_month = 0;
|
||||||
uint8_t day = 0, test_day = 0;
|
uint8_t day = 0, test_day = 0;
|
||||||
|
|
||||||
days = days_since_epoch(1900,1,1);
|
days = days_since_epoch(1900, 1, 1);
|
||||||
ct_test(pTest, days == 0);
|
ct_test(pTest, days == 0);
|
||||||
days_since_epoch_into_ymd(days, &year, &month, &day);
|
days_since_epoch_into_ymd(days, &year, &month, &day);
|
||||||
ct_test(pTest, year == 1900);
|
ct_test(pTest, year == 1900);
|
||||||
|
|||||||
+8
-12
@@ -68,8 +68,7 @@ extern "C" {
|
|||||||
void datetime_set_time(BACNET_TIME * btime,
|
void datetime_set_time(BACNET_TIME * btime,
|
||||||
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths);
|
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths);
|
||||||
void datetime_set(BACNET_DATE_TIME * bdatetime,
|
void datetime_set(BACNET_DATE_TIME * bdatetime,
|
||||||
BACNET_DATE * bdate,
|
BACNET_DATE * bdate, BACNET_TIME * btime);
|
||||||
BACNET_TIME * btime);
|
|
||||||
void datetime_set_values(BACNET_DATE_TIME * bdatetime,
|
void datetime_set_values(BACNET_DATE_TIME * bdatetime,
|
||||||
uint16_t year, uint8_t month, uint8_t day,
|
uint16_t year, uint8_t month, uint8_t day,
|
||||||
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths);
|
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths);
|
||||||
@@ -80,23 +79,20 @@ extern "C" {
|
|||||||
if date1 is after date2, returns positive */
|
if date1 is after date2, returns positive */
|
||||||
int datetime_compare_date(BACNET_DATE * date1, BACNET_DATE * date2);
|
int datetime_compare_date(BACNET_DATE * date1, BACNET_DATE * date2);
|
||||||
int datetime_compare_time(BACNET_TIME * time1, BACNET_TIME * time2);
|
int datetime_compare_time(BACNET_TIME * time1, BACNET_TIME * time2);
|
||||||
int datetime_compare(
|
int datetime_compare(BACNET_DATE_TIME * datetime1,
|
||||||
BACNET_DATE_TIME * datetime1,
|
BACNET_DATE_TIME * datetime2);
|
||||||
BACNET_DATE_TIME * datetime2);
|
|
||||||
|
|
||||||
/* utility copy functions */
|
/* utility copy functions */
|
||||||
void datetime_copy_date(BACNET_DATE * date1, BACNET_DATE * date2);
|
void datetime_copy_date(BACNET_DATE * date1, BACNET_DATE * date2);
|
||||||
void datetime_copy_time(BACNET_TIME * time1, BACNET_TIME * time2);
|
void datetime_copy_time(BACNET_TIME * time1, BACNET_TIME * time2);
|
||||||
void datetime_copy(
|
void datetime_copy(BACNET_DATE_TIME * datetime1,
|
||||||
BACNET_DATE_TIME * datetime1,
|
BACNET_DATE_TIME * datetime2);
|
||||||
BACNET_DATE_TIME * datetime2);
|
|
||||||
|
|
||||||
/* utility add function */
|
/* utility add function */
|
||||||
void datetime_add_minutes(BACNET_DATE_TIME * bdatetime, uint32_t minutes);
|
void datetime_add_minutes(BACNET_DATE_TIME * bdatetime,
|
||||||
|
uint32_t minutes);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
#endif /* DATE_TIME_H */
|
||||||
#endif /* DATE_TIME_H */
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ static uint8_t Temp_Buf[MAX_APDU] = { 0 };
|
|||||||
|
|
||||||
void handler_read_property(uint8_t * service_request,
|
void handler_read_property(uint8_t * service_request,
|
||||||
uint16_t service_len,
|
uint16_t service_len,
|
||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
||||||
BACNET_CONFIRMED_SERVICE_DATA * service_data)
|
|
||||||
{
|
{
|
||||||
BACNET_READ_PROPERTY_DATA data;
|
BACNET_READ_PROPERTY_DATA data;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|||||||
@@ -67,11 +67,11 @@ static void PrintReadPropertyData(BACNET_READ_PROPERTY_DATA * data)
|
|||||||
#endif
|
#endif
|
||||||
application_data = data->application_data;
|
application_data = data->application_data;
|
||||||
application_data_len = data->application_data_len;
|
application_data_len = data->application_data_len;
|
||||||
/* FIXME: what if application_data_len is bigger than 255? */
|
/* FIXME: what if application_data_len is bigger than 255? */
|
||||||
/* value? need to loop until all of the len is gone... */
|
/* value? need to loop until all of the len is gone... */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
len = bacapp_decode_application_data(application_data,
|
len = bacapp_decode_application_data(application_data,
|
||||||
(uint8_t)application_data_len, &value);
|
(uint8_t) application_data_len, &value);
|
||||||
if (first_value && (len < application_data_len)) {
|
if (first_value && (len < application_data_len)) {
|
||||||
first_value = false;
|
first_value = false;
|
||||||
fprintf(stdout, "{");
|
fprintf(stdout, "{");
|
||||||
|
|||||||
@@ -259,7 +259,8 @@ void handler_write_property(uint8_t * service_request,
|
|||||||
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
|
||||||
error_code);
|
error_code);
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
fprintf(stderr, "Sending Write Access Error for Load Control!\n");
|
fprintf(stderr,
|
||||||
|
"Sending Write Access Error for Load Control!\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -89,7 +89,8 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
|
|||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
|
(uint16_t) pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
datalink_send_pdu(&dest, &npdu_data,
|
datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
|
|||||||
data.object_property = object_property;
|
data.object_property = object_property;
|
||||||
data.array_index = array_index;
|
data.array_index = array_index;
|
||||||
data.application_data_len =
|
data.application_data_len =
|
||||||
bacapp_encode_application_data(
|
bacapp_encode_application_data(&data.application_data[0],
|
||||||
&data.application_data[0],object_value);
|
object_value);
|
||||||
data.priority = priority;
|
data.priority = priority;
|
||||||
len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
len = wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
|
||||||
invoke_id, &data);
|
invoke_id, &data);
|
||||||
@@ -94,7 +94,8 @@ uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
|
|||||||
max_apdu in the address binding table. */
|
max_apdu in the address binding table. */
|
||||||
if ((unsigned) pdu_len < max_apdu) {
|
if ((unsigned) pdu_len < max_apdu) {
|
||||||
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
|
||||||
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t)pdu_len);
|
&npdu_data, &Handler_Transmit_Buffer[0],
|
||||||
|
(uint16_t) pdu_len);
|
||||||
bytes_sent =
|
bytes_sent =
|
||||||
datalink_send_pdu(&dest, &npdu_data,
|
datalink_send_pdu(&dest, &npdu_data,
|
||||||
&Handler_Transmit_Buffer[0], pdu_len);
|
&Handler_Transmit_Buffer[0], pdu_len);
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
BACNET_CHARACTER_STRING char_string;
|
||||||
float value = (float)3.14;
|
float value = (float) 3.14;
|
||||||
|
|
||||||
(void) array_index;
|
(void) array_index;
|
||||||
switch (property) {
|
switch (property) {
|
||||||
@@ -122,7 +122,7 @@ int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT);
|
apdu_len = encode_tagged_enumerated(&apdu[0], UNITS_PERCENT);
|
||||||
break;
|
break;
|
||||||
case 9997:
|
case 9997:
|
||||||
apdu_len = encode_tagged_real(&apdu[0], (float)90.510);
|
apdu_len = encode_tagged_real(&apdu[0], (float) 90.510);
|
||||||
break;
|
break;
|
||||||
case 9998:
|
case 9998:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0], 90);
|
apdu_len = encode_tagged_unsigned(&apdu[0], 90);
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ int Analog_Output_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
BACNET_CHARACTER_STRING char_string;
|
||||||
float real_value = (float)1.414;
|
float real_value = (float) 1.414;
|
||||||
unsigned object_index = 0;
|
unsigned object_index = 0;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
bool state = false;
|
bool state = false;
|
||||||
@@ -237,12 +237,12 @@ int Analog_Output_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
object_index =
|
object_index =
|
||||||
Analog_Output_Instance_To_Index(object_instance);
|
Analog_Output_Instance_To_Index(object_instance);
|
||||||
if (array_index <= BACNET_MAX_PRIORITY) {
|
if (array_index <= BACNET_MAX_PRIORITY) {
|
||||||
if (Analog_Output_Level[object_index][array_index-1] ==
|
if (Analog_Output_Level[object_index][array_index - 1] ==
|
||||||
AO_LEVEL_NULL)
|
AO_LEVEL_NULL)
|
||||||
apdu_len = encode_tagged_null(&apdu[0]);
|
apdu_len = encode_tagged_null(&apdu[0]);
|
||||||
else {
|
else {
|
||||||
real_value =
|
real_value =
|
||||||
Analog_Output_Level[object_index][array_index-1];
|
Analog_Output_Level[object_index][array_index - 1];
|
||||||
apdu_len = encode_tagged_real(&apdu[0], real_value);
|
apdu_len = encode_tagged_real(&apdu[0], real_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -285,10 +285,8 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
@@ -300,8 +298,7 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
object. */
|
object. */
|
||||||
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
||||||
(priority != 6 /* reserved */ ) &&
|
(priority != 6 /* reserved */ ) &&
|
||||||
(value.type.Real >= 0.0) &&
|
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
|
||||||
(value.type.Real <= 100.0)) {
|
|
||||||
level = (uint8_t) value.type.Real;
|
level = (uint8_t) value.type.Real;
|
||||||
object_index =
|
object_index =
|
||||||
Analog_Output_Instance_To_Index(wp_data->
|
Analog_Output_Instance_To_Index(wp_data->
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
int apdu_len = 0; /* return value */
|
int apdu_len = 0; /* return value */
|
||||||
BACNET_BIT_STRING bit_string;
|
BACNET_BIT_STRING bit_string;
|
||||||
BACNET_CHARACTER_STRING char_string;
|
BACNET_CHARACTER_STRING char_string;
|
||||||
float real_value = (float)1.414;
|
float real_value = (float) 1.414;
|
||||||
unsigned object_index = 0;
|
unsigned object_index = 0;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
bool state = false;
|
bool state = false;
|
||||||
@@ -234,12 +234,12 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
} else {
|
} else {
|
||||||
object_index = Analog_Value_Instance_To_Index(object_instance);
|
object_index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
if (array_index <= BACNET_MAX_PRIORITY) {
|
if (array_index <= BACNET_MAX_PRIORITY) {
|
||||||
if (Analog_Value_Level[object_index][array_index-1] ==
|
if (Analog_Value_Level[object_index][array_index - 1] ==
|
||||||
ANALOG_LEVEL_NULL)
|
ANALOG_LEVEL_NULL)
|
||||||
apdu_len = encode_tagged_null(&apdu[0]);
|
apdu_len = encode_tagged_null(&apdu[0]);
|
||||||
else {
|
else {
|
||||||
real_value =
|
real_value =
|
||||||
Analog_Value_Level[object_index][array_index-1];
|
Analog_Value_Level[object_index][array_index - 1];
|
||||||
apdu_len = encode_tagged_real(&apdu[0], real_value);
|
apdu_len = encode_tagged_real(&apdu[0], real_value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -282,10 +282,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
@@ -297,8 +295,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
object. */
|
object. */
|
||||||
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
||||||
(priority != 6 /* reserved */ ) &&
|
(priority != 6 /* reserved */ ) &&
|
||||||
(value.type.Real >= 0.0) &&
|
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
|
||||||
(value.type.Real <= 100.0)) {
|
|
||||||
level = (uint8_t) value.type.Real;
|
level = (uint8_t) value.type.Real;
|
||||||
object_index =
|
object_index =
|
||||||
Analog_Value_Instance_To_Index(wp_data->
|
Analog_Value_Instance_To_Index(wp_data->
|
||||||
@@ -349,8 +346,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
object_index =
|
||||||
Analog_Value_Instance_To_Index(wp_data->object_instance);
|
Analog_Value_Instance_To_Index(wp_data->object_instance);
|
||||||
Analog_Value_Out_Of_Service[object_index] =
|
Analog_Value_Out_Of_Service[object_index] = value.type.Boolean;
|
||||||
value.type.Boolean;
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
|||||||
@@ -232,10 +232,8 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
|
|||||||
@@ -283,10 +283,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
|
|||||||
@@ -280,10 +280,8 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
@@ -347,8 +345,7 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
object_index =
|
||||||
Binary_Value_Instance_To_Index(wp_data->object_instance);
|
Binary_Value_Instance_To_Index(wp_data->object_instance);
|
||||||
Binary_Value_Out_Of_Service[object_index] =
|
Binary_Value_Out_Of_Service[object_index] = value.type.Boolean;
|
||||||
value.type.Boolean;
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
|||||||
@@ -796,18 +796,16 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
if (value.tag == BACNET_APPLICATION_TAG_OBJECT_ID) {
|
||||||
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
|
||||||
(Device_Set_Object_Instance_Number(
|
(Device_Set_Object_Instance_Number(value.type.Object_Id.
|
||||||
value.type.Object_Id.instance))) {
|
instance))) {
|
||||||
/* FIXME: we could send an I-Am broadcast to let the world know */
|
/* FIXME: we could send an I-Am broadcast to let the world know */
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -835,8 +833,7 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
case PROP_APDU_TIMEOUT:
|
case PROP_APDU_TIMEOUT:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
/* FIXME: bounds check? */
|
/* FIXME: bounds check? */
|
||||||
Device_Set_APDU_Timeout((uint16_t) value.type.
|
Device_Set_APDU_Timeout((uint16_t) value.type.Unsigned_Int);
|
||||||
Unsigned_Int);
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -870,13 +867,12 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
|
||||||
uint8_t encoding;
|
uint8_t encoding;
|
||||||
encoding =
|
encoding =
|
||||||
characterstring_encoding(&value.type.
|
characterstring_encoding(&value.type.Character_String);
|
||||||
Character_String);
|
|
||||||
if (encoding == CHARACTER_ANSI_X34) {
|
if (encoding == CHARACTER_ANSI_X34) {
|
||||||
status =
|
status =
|
||||||
Device_Set_Object_Name(
|
Device_Set_Object_Name(characterstring_value(&value.
|
||||||
characterstring_value(&value.type.Character_String),
|
type.Character_String),
|
||||||
characterstring_length(&value.type.Character_String));
|
characterstring_length(&value.type.Character_String));
|
||||||
if (!status) {
|
if (!status) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||||
|
|||||||
+128
-144
@@ -28,7 +28,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h> /* for memcpy */
|
#include <string.h> /* for memcpy */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "bacdcode.h"
|
#include "bacdcode.h"
|
||||||
@@ -45,9 +45,9 @@
|
|||||||
static BACNET_SHED_STATE Present_Value[MAX_LOAD_CONTROLS];
|
static BACNET_SHED_STATE Present_Value[MAX_LOAD_CONTROLS];
|
||||||
|
|
||||||
typedef enum BACnetShedLevelType {
|
typedef enum BACnetShedLevelType {
|
||||||
BACNET_SHED_TYPE_PERCENT, /* Unsigned */
|
BACNET_SHED_TYPE_PERCENT, /* Unsigned */
|
||||||
BACNET_SHED_TYPE_LEVEL, /* Unsigned */
|
BACNET_SHED_TYPE_LEVEL, /* Unsigned */
|
||||||
BACNET_SHED_TYPE_AMOUNT /* REAL */
|
BACNET_SHED_TYPE_AMOUNT /* REAL */
|
||||||
} BACNET_SHED_LEVEL_TYPE;
|
} BACNET_SHED_LEVEL_TYPE;
|
||||||
|
|
||||||
/* The shed levels for the LEVEL choice of BACnetShedLevel
|
/* The shed levels for the LEVEL choice of BACnetShedLevel
|
||||||
@@ -103,9 +103,9 @@ static unsigned Shed_Levels[MAX_LOAD_CONTROLS][MAX_SHED_LEVELS];
|
|||||||
Load Control object can take on. It is the same for
|
Load Control object can take on. It is the same for
|
||||||
all the load control objects in this example device. */
|
all the load control objects in this example device. */
|
||||||
static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
|
static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
|
||||||
"dim lights 10%",
|
"dim lights 10%",
|
||||||
"dim lights 20%",
|
"dim lights 20%",
|
||||||
"dim lights 30%"
|
"dim lights 30%"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* we need to have our arrays initialized before answering any calls */
|
/* we need to have our arrays initialized before answering any calls */
|
||||||
@@ -122,8 +122,9 @@ void Load_Control_Init(void)
|
|||||||
Present_Value[i] = BACNET_SHED_INACTIVE;
|
Present_Value[i] = BACNET_SHED_INACTIVE;
|
||||||
Requested_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
Requested_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
||||||
Requested_Shed_Level[i].value.level = 0;
|
Requested_Shed_Level[i].value.level = 0;
|
||||||
datetime_set_values(&Start_Time[i],0,0,0,0,0,0,0);
|
datetime_set_values(&Start_Time[i], 0, 0, 0, 0, 0, 0, 0);
|
||||||
datetime_set_values(&Previous_Start_Time[i],0,0,0,0,0,0,0);
|
datetime_set_values(&Previous_Start_Time[i], 0, 0, 0, 0, 0, 0,
|
||||||
|
0);
|
||||||
Shed_Duration[i] = 0;
|
Shed_Duration[i] = 0;
|
||||||
Duty_Window[i] = 0;
|
Duty_Window[i] = 0;
|
||||||
Load_Control_Enable[i] = true;
|
Load_Control_Enable[i] = true;
|
||||||
@@ -131,7 +132,7 @@ void Load_Control_Init(void)
|
|||||||
for (j = 0; j < MAX_SHED_LEVELS; j++) {
|
for (j = 0; j < MAX_SHED_LEVELS; j++) {
|
||||||
/* FIXME: fake data for lighting application */
|
/* FIXME: fake data for lighting application */
|
||||||
/* The array shall be ordered by increasing shed amount. */
|
/* The array shall be ordered by increasing shed amount. */
|
||||||
Shed_Levels[i][j] = 90 - (j * (30/MAX_SHED_LEVELS));
|
Shed_Levels[i][j] = 90 - (j * (30 / MAX_SHED_LEVELS));
|
||||||
}
|
}
|
||||||
Expected_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
Expected_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
||||||
Expected_Shed_Level[i].value.level = 0;
|
Expected_Shed_Level[i].value.level = 0;
|
||||||
@@ -186,7 +187,8 @@ unsigned Load_Control_Instance_To_Index(uint32_t object_instance)
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BACNET_SHED_STATE Load_Control_Present_Value(uint32_t object_instance)
|
static BACNET_SHED_STATE Load_Control_Present_Value(uint32_t
|
||||||
|
object_instance)
|
||||||
{
|
{
|
||||||
BACNET_SHED_STATE value = BACNET_SHED_INACTIVE;
|
BACNET_SHED_STATE value = BACNET_SHED_INACTIVE;
|
||||||
unsigned index = 0;
|
unsigned index = 0;
|
||||||
@@ -234,46 +236,41 @@ struct tm {
|
|||||||
|
|
||||||
timer = time(NULL);
|
timer = time(NULL);
|
||||||
tblock = localtime(&timer);
|
tblock = localtime(&timer);
|
||||||
datetime_set_values(
|
datetime_set_values(bdatetime,
|
||||||
bdatetime,
|
|
||||||
tblock->tm_year,
|
tblock->tm_year,
|
||||||
tblock->tm_mon,
|
tblock->tm_mon,
|
||||||
tblock->tm_mday,
|
tblock->tm_mday,
|
||||||
tblock->tm_hour,
|
tblock->tm_hour, tblock->tm_min, tblock->tm_sec, 0);
|
||||||
tblock->tm_min,
|
|
||||||
tblock->tm_sec,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef enum load_control_state
|
typedef enum load_control_state {
|
||||||
{
|
SHED_INACTIVE,
|
||||||
SHED_INACTIVE,
|
SHED_REQUEST_PENDING,
|
||||||
SHED_REQUEST_PENDING,
|
SHED_NON_COMPLIANT,
|
||||||
SHED_NON_COMPLIANT,
|
SHED_COMPLIANT
|
||||||
SHED_COMPLIANT
|
|
||||||
} LOAD_CONTROL_STATE;
|
} LOAD_CONTROL_STATE;
|
||||||
|
|
||||||
void Load_Control_State_Machine(int object_index)
|
void Load_Control_State_Machine(int object_index)
|
||||||
{
|
{
|
||||||
static LOAD_CONTROL_STATE state[MAX_LOAD_CONTROLS];
|
static LOAD_CONTROL_STATE state[MAX_LOAD_CONTROLS];
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
unsigned i = 0; /* loop counter */
|
unsigned i = 0; /* loop counter */
|
||||||
int diff = 0; /* used for datetime comparison */
|
int diff = 0; /* used for datetime comparison */
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
for (i = 0; i < MAX_LOAD_CONTROLS; i++) {
|
for (i = 0; i < MAX_LOAD_CONTROLS; i++) {
|
||||||
state[i] = SHED_INACTIVE;
|
state[i] = SHED_INACTIVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state[object_index])
|
switch (state[object_index]) {
|
||||||
{
|
case SHED_REQUEST_PENDING:
|
||||||
case SHED_REQUEST_PENDING:
|
|
||||||
Update_Current_Time(&Current_Time);
|
Update_Current_Time(&Current_Time);
|
||||||
datetime_copy(&End_Time[object_index],&Start_Time[object_index]);
|
datetime_copy(&End_Time[object_index], &Start_Time[object_index]);
|
||||||
datetime_add_minutes(&End_Time[object_index], Shed_Duration[object_index]);
|
datetime_add_minutes(&End_Time[object_index],
|
||||||
diff = datetime_compare(&End_Time[object_index],&Current_Time);
|
Shed_Duration[object_index]);
|
||||||
|
diff = datetime_compare(&End_Time[object_index], &Current_Time);
|
||||||
if (diff < 0) {
|
if (diff < 0) {
|
||||||
/* CancelShed */
|
/* CancelShed */
|
||||||
/* FIXME: stop shedding! i.e. relinquish */
|
/* FIXME: stop shedding! i.e. relinquish */
|
||||||
@@ -286,12 +283,12 @@ void Load_Control_State_Machine(int object_index)
|
|||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHED_NON_COMPLIANT:
|
case SHED_NON_COMPLIANT:
|
||||||
break;
|
break;
|
||||||
case SHED_COMPLIANT:
|
case SHED_COMPLIANT:
|
||||||
break;
|
break;
|
||||||
case SHED_INACTIVE:
|
case SHED_INACTIVE:
|
||||||
default:
|
default:
|
||||||
diff = datetime_compare(&Previous_Start_Time[object_index],
|
diff = datetime_compare(&Previous_Start_Time[object_index],
|
||||||
&Start_Time[object_index]);
|
&Start_Time[object_index]);
|
||||||
if (diff != 0) {
|
if (diff != 0) {
|
||||||
@@ -301,24 +298,23 @@ void Load_Control_State_Machine(int object_index)
|
|||||||
/* FIXME: calculate your Actual Shed Level */
|
/* FIXME: calculate your Actual Shed Level */
|
||||||
Expected_Shed_Level[object_index].type =
|
Expected_Shed_Level[object_index].type =
|
||||||
Requested_Shed_Level[object_index].type;
|
Requested_Shed_Level[object_index].type;
|
||||||
switch (Requested_Shed_Level[object_index].type)
|
switch (Requested_Shed_Level[object_index].type) {
|
||||||
{
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
case BACNET_SHED_TYPE_PERCENT:
|
Actual_Shed_Level[object_index].value.percent =
|
||||||
Actual_Shed_Level[object_index].value.percent =
|
Expected_Shed_Level[object_index].value.percent =
|
||||||
Expected_Shed_Level[object_index].value.percent =
|
Requested_Shed_Level[object_index].value.percent;
|
||||||
Requested_Shed_Level[object_index].value.percent;
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
case BACNET_SHED_TYPE_AMOUNT:
|
Actual_Shed_Level[object_index].value.amount =
|
||||||
Actual_Shed_Level[object_index].value.amount =
|
Expected_Shed_Level[object_index].value.amount =
|
||||||
Expected_Shed_Level[object_index].value.amount =
|
Requested_Shed_Level[object_index].value.amount;
|
||||||
Requested_Shed_Level[object_index].value.amount;
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
case BACNET_SHED_TYPE_LEVEL:
|
default:
|
||||||
default:
|
Actual_Shed_Level[object_index].value.level =
|
||||||
Actual_Shed_Level[object_index].value.level =
|
Expected_Shed_Level[object_index].value.level =
|
||||||
Expected_Shed_Level[object_index].value.level =
|
Requested_Shed_Level[object_index].value.level;
|
||||||
Requested_Shed_Level[object_index].value.level;
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
state[object_index] = SHED_REQUEST_PENDING;
|
state[object_index] = SHED_REQUEST_PENDING;
|
||||||
}
|
}
|
||||||
@@ -369,12 +365,12 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
case PROP_OBJECT_TYPE:
|
case PROP_OBJECT_TYPE:
|
||||||
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_LOAD_CONTROL);
|
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_LOAD_CONTROL);
|
||||||
break;
|
break;
|
||||||
/* optional property
|
/* optional property
|
||||||
case PROP_DESCRIPTION:
|
case PROP_DESCRIPTION:
|
||||||
characterstring_init_ansi(&char_string,"optional description");
|
characterstring_init_ansi(&char_string,"optional description");
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
enumeration = Load_Control_Present_Value(object_instance);
|
enumeration = Load_Control_Present_Value(object_instance);
|
||||||
apdu_len = encode_tagged_enumerated(&apdu[0], enumeration);
|
apdu_len = encode_tagged_enumerated(&apdu[0], enumeration);
|
||||||
@@ -384,13 +380,13 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
/* IN_ALARM - Logical FALSE (0) if the Event_State property
|
/* IN_ALARM - Logical FALSE (0) if the Event_State property
|
||||||
has a value of NORMAL, otherwise logical TRUE (1). */
|
has a value of NORMAL, otherwise logical TRUE (1). */
|
||||||
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
|
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
|
||||||
/* FAULT - Logical TRUE (1) if the Reliability property is
|
/* FAULT - Logical TRUE (1) if the Reliability property is
|
||||||
present and does not have a value of NO_FAULT_DETECTED,
|
present and does not have a value of NO_FAULT_DETECTED,
|
||||||
otherwise logical FALSE (0). */
|
otherwise logical FALSE (0). */
|
||||||
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
|
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
|
||||||
/* OVERRIDDEN - Logical TRUE (1) if the point has been
|
/* OVERRIDDEN - Logical TRUE (1) if the point has been
|
||||||
overridden by some mechanism local to the BACnet Device,
|
overridden by some mechanism local to the BACnet Device,
|
||||||
otherwise logical FALSE (0).*/
|
otherwise logical FALSE (0). */
|
||||||
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
|
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
|
||||||
/* OUT_OF_SERVICE - This bit shall always be Logical FALSE (0). */
|
/* OUT_OF_SERVICE - This bit shall always be Logical FALSE (0). */
|
||||||
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
|
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
@@ -400,26 +396,24 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
||||||
break;
|
break;
|
||||||
case PROP_REQUESTED_SHED_LEVEL:
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
switch (Requested_Shed_Level[object_index].type)
|
switch (Requested_Shed_Level[object_index].type) {
|
||||||
{
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
case BACNET_SHED_TYPE_PERCENT:
|
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
||||||
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
Requested_Shed_Level[object_index].value.percent);
|
||||||
Requested_Shed_Level[object_index].value.percent);
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
case BACNET_SHED_TYPE_AMOUNT:
|
apdu_len = encode_context_real(&apdu[0], 2,
|
||||||
apdu_len = encode_context_real(&apdu[0], 2,
|
Requested_Shed_Level[object_index].value.amount);
|
||||||
Requested_Shed_Level[object_index].value.amount);
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
case BACNET_SHED_TYPE_LEVEL:
|
default:
|
||||||
default:
|
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
||||||
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
Requested_Shed_Level[object_index].value.level);
|
||||||
Requested_Shed_Level[object_index].value.level);
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_START_TIME:
|
case PROP_START_TIME:
|
||||||
len = encode_tagged_date(&apdu[0],
|
len = encode_tagged_date(&apdu[0], &Start_Time[object_index].date);
|
||||||
&Start_Time[object_index].date);
|
|
||||||
apdu_len = len;
|
apdu_len = len;
|
||||||
len = encode_tagged_time(&apdu[apdu_len],
|
len = encode_tagged_time(&apdu[apdu_len],
|
||||||
&Start_Time[object_index].time);
|
&Start_Time[object_index].time);
|
||||||
@@ -437,58 +431,57 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
state = Load_Control_Enable[object_index];
|
state = Load_Control_Enable[object_index];
|
||||||
apdu_len = encode_tagged_boolean(&apdu[0], state);
|
apdu_len = encode_tagged_boolean(&apdu[0], state);
|
||||||
break;
|
break;
|
||||||
case PROP_FULL_DUTY_BASELINE: /* optional */
|
case PROP_FULL_DUTY_BASELINE: /* optional */
|
||||||
apdu_len = encode_tagged_real(&apdu[0],
|
apdu_len = encode_tagged_real(&apdu[0],
|
||||||
Full_Duty_Baseline[object_index]);
|
Full_Duty_Baseline[object_index]);
|
||||||
break;
|
break;
|
||||||
case PROP_EXPECTED_SHED_LEVEL:
|
case PROP_EXPECTED_SHED_LEVEL:
|
||||||
switch (Expected_Shed_Level[object_index].type)
|
switch (Expected_Shed_Level[object_index].type) {
|
||||||
{
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
case BACNET_SHED_TYPE_PERCENT:
|
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
||||||
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
Expected_Shed_Level[object_index].value.percent);
|
||||||
Expected_Shed_Level[object_index].value.percent);
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
case BACNET_SHED_TYPE_AMOUNT:
|
apdu_len = encode_context_real(&apdu[0], 2,
|
||||||
apdu_len = encode_context_real(&apdu[0], 2,
|
Expected_Shed_Level[object_index].value.amount);
|
||||||
Expected_Shed_Level[object_index].value.amount);
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
case BACNET_SHED_TYPE_LEVEL:
|
default:
|
||||||
default:
|
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
||||||
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
Expected_Shed_Level[object_index].value.level);
|
||||||
Expected_Shed_Level[object_index].value.level);
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_ACTUAL_SHED_LEVEL:
|
case PROP_ACTUAL_SHED_LEVEL:
|
||||||
switch (Actual_Shed_Level[object_index].type)
|
switch (Actual_Shed_Level[object_index].type) {
|
||||||
{
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
case BACNET_SHED_TYPE_PERCENT:
|
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
||||||
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
Actual_Shed_Level[object_index].value.percent);
|
||||||
Actual_Shed_Level[object_index].value.percent);
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
case BACNET_SHED_TYPE_AMOUNT:
|
apdu_len = encode_context_real(&apdu[0], 2,
|
||||||
apdu_len = encode_context_real(&apdu[0], 2,
|
Actual_Shed_Level[object_index].value.amount);
|
||||||
Actual_Shed_Level[object_index].value.amount);
|
break;
|
||||||
break;
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
case BACNET_SHED_TYPE_LEVEL:
|
default:
|
||||||
default:
|
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
||||||
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
Actual_Shed_Level[object_index].value.level);
|
||||||
Actual_Shed_Level[object_index].value.level);
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_SHED_LEVELS:
|
case PROP_SHED_LEVELS:
|
||||||
/* Array element zero is the number of elements in the array */
|
/* Array element zero is the number of elements in the array */
|
||||||
if (array_index == BACNET_ARRAY_LENGTH_INDEX)
|
if (array_index == BACNET_ARRAY_LENGTH_INDEX)
|
||||||
apdu_len =
|
apdu_len = encode_tagged_unsigned(&apdu[0], MAX_SHED_LEVELS);
|
||||||
encode_tagged_unsigned(&apdu[0], MAX_SHED_LEVELS);
|
|
||||||
/* if no index was specified, then try to encode the entire list */
|
/* if no index was specified, then try to encode the entire list */
|
||||||
/* into one packet. */
|
/* into one packet. */
|
||||||
else if (array_index == BACNET_ARRAY_ALL) {
|
else if (array_index == BACNET_ARRAY_ALL) {
|
||||||
apdu_len = 0;
|
apdu_len = 0;
|
||||||
for (i = 0; i < MAX_SHED_LEVELS; i++) {
|
for (i = 0; i < MAX_SHED_LEVELS; i++) {
|
||||||
/* FIXME: check if we have room before adding it to APDU */
|
/* FIXME: check if we have room before adding it to APDU */
|
||||||
len = encode_tagged_unsigned(&apdu[apdu_len], Shed_Levels[object_index][i]);
|
len =
|
||||||
|
encode_tagged_unsigned(&apdu[apdu_len],
|
||||||
|
Shed_Levels[object_index][i]);
|
||||||
/* add it if we have room */
|
/* add it if we have room */
|
||||||
if ((apdu_len + len) < MAX_APDU)
|
if ((apdu_len + len) < MAX_APDU)
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
@@ -502,7 +495,7 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
} else {
|
} else {
|
||||||
if (array_index <= MAX_SHED_LEVELS) {
|
if (array_index <= MAX_SHED_LEVELS) {
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0],
|
apdu_len = encode_tagged_unsigned(&apdu[0],
|
||||||
Shed_Levels[object_index][array_index-1]);
|
Shed_Levels[object_index][array_index - 1]);
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||||
@@ -513,8 +506,7 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
case PROP_SHED_LEVEL_DESCRIPTIONS:
|
case PROP_SHED_LEVEL_DESCRIPTIONS:
|
||||||
/* Array element zero is the number of elements in the array */
|
/* Array element zero is the number of elements in the array */
|
||||||
if (array_index == BACNET_ARRAY_LENGTH_INDEX)
|
if (array_index == BACNET_ARRAY_LENGTH_INDEX)
|
||||||
apdu_len =
|
apdu_len = encode_tagged_unsigned(&apdu[0], MAX_SHED_LEVELS);
|
||||||
encode_tagged_unsigned(&apdu[0], MAX_SHED_LEVELS);
|
|
||||||
/* if no index was specified, then try to encode the entire list */
|
/* if no index was specified, then try to encode the entire list */
|
||||||
/* into one packet. */
|
/* into one packet. */
|
||||||
else if (array_index == BACNET_ARRAY_ALL) {
|
else if (array_index == BACNET_ARRAY_ALL) {
|
||||||
@@ -538,7 +530,7 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
} else {
|
} else {
|
||||||
if (array_index <= MAX_SHED_LEVELS) {
|
if (array_index <= MAX_SHED_LEVELS) {
|
||||||
characterstring_init_ansi(&char_string,
|
characterstring_init_ansi(&char_string,
|
||||||
Shed_Level_Descriptions[array_index-1]);
|
Shed_Level_Descriptions[array_index - 1]);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0],
|
apdu_len = encode_tagged_character_string(&apdu[0],
|
||||||
&char_string);
|
&char_string);
|
||||||
} else {
|
} else {
|
||||||
@@ -574,17 +566,15 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
object_index = Load_Control_Instance_To_Index(wp_data->object_instance);
|
object_index =
|
||||||
|
Load_Control_Instance_To_Index(wp_data->object_instance);
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
case PROP_REQUESTED_SHED_LEVEL:
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
len = bacapp_decode_context_data(
|
len = bacapp_decode_context_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
|
||||||
wp_data->application_data_len,
|
wp_data->application_data_len,
|
||||||
&value, PROP_REQUESTED_SHED_LEVEL);
|
&value, PROP_REQUESTED_SHED_LEVEL);
|
||||||
if (value.tag == 0) {
|
if (value.tag == 0) {
|
||||||
@@ -611,7 +601,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
case PROP_START_TIME:
|
case PROP_START_TIME:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_DATE) {
|
if (value.tag == BACNET_APPLICATION_TAG_DATE) {
|
||||||
memcpy(&Start_Time[object_index].date,
|
memcpy(&Start_Time[object_index].date,
|
||||||
&value.type.Date,sizeof(value.type.Date));
|
&value.type.Date, sizeof(value.type.Date));
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -619,13 +609,12 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
}
|
}
|
||||||
if (!status)
|
if (!status)
|
||||||
break;
|
break;
|
||||||
len = bacapp_decode_application_data(
|
len =
|
||||||
wp_data->application_data + len,
|
bacapp_decode_application_data(wp_data->application_data + len,
|
||||||
wp_data->application_data_len - len,
|
wp_data->application_data_len - len, &value);
|
||||||
&value);
|
|
||||||
if (len && value.tag == BACNET_APPLICATION_TAG_TIME) {
|
if (len && value.tag == BACNET_APPLICATION_TAG_TIME) {
|
||||||
memcpy(&Start_Time[object_index].time,
|
memcpy(&Start_Time[object_index].time,
|
||||||
&value.type.Time,sizeof(value.type.Time));
|
&value.type.Time, sizeof(value.type.Time));
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
status = false;
|
status = false;
|
||||||
@@ -635,8 +624,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
break;
|
break;
|
||||||
case PROP_SHED_DURATION:
|
case PROP_SHED_DURATION:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
Shed_Duration[object_index] =
|
Shed_Duration[object_index] = value.type.Unsigned_Int;
|
||||||
value.type.Unsigned_Int;
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -645,8 +633,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
break;
|
break;
|
||||||
case PROP_DUTY_WINDOW:
|
case PROP_DUTY_WINDOW:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
|
||||||
Duty_Window[object_index] =
|
Duty_Window[object_index] = value.type.Unsigned_Int;
|
||||||
value.type.Unsigned_Int;
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -659,13 +646,11 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
if (wp_data->array_index == 0) {
|
if (wp_data->array_index == 0) {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||||
}
|
} else if (wp_data->array_index == BACNET_ARRAY_ALL) {
|
||||||
else if (wp_data->array_index == BACNET_ARRAY_ALL) {
|
|
||||||
/* FIXME: write entire array */
|
/* FIXME: write entire array */
|
||||||
status = true;
|
status = true;
|
||||||
}
|
} else if (wp_data->array_index <= MAX_SHED_LEVELS) {
|
||||||
else if (wp_data->array_index <= MAX_SHED_LEVELS) {
|
Shed_Levels[object_index][wp_data->array_index - 1] =
|
||||||
Shed_Levels[object_index][wp_data->array_index-1] =
|
|
||||||
value.type.Unsigned_Int;
|
value.type.Unsigned_Int;
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -677,8 +662,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
break;
|
break;
|
||||||
case PROP_ENABLE:
|
case PROP_ENABLE:
|
||||||
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
Load_Control_Enable[object_index] =
|
Load_Control_Enable[object_index] = value.type.Boolean;
|
||||||
value.type.Boolean;
|
|
||||||
status = true;
|
status = true;
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
|||||||
@@ -254,10 +254,8 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
|
||||||
wp_data->application_data_len,
|
|
||||||
wp_data->application_data_len, &value);
|
wp_data->application_data_len, &value);
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
|
|||||||
@@ -237,15 +237,15 @@ int Multistate_Output_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
object_index =
|
object_index =
|
||||||
Multistate_Output_Instance_To_Index(object_instance);
|
Multistate_Output_Instance_To_Index(object_instance);
|
||||||
if (array_index <= BACNET_MAX_PRIORITY) {
|
if (array_index <= BACNET_MAX_PRIORITY) {
|
||||||
if (Multistate_Output_Level[object_index][array_index-1] ==
|
if (Multistate_Output_Level[object_index][array_index -
|
||||||
MULTISTATE_NULL)
|
1] == MULTISTATE_NULL)
|
||||||
apdu_len = encode_tagged_null(&apdu[0]);
|
apdu_len = encode_tagged_null(&apdu[0]);
|
||||||
else {
|
else {
|
||||||
present_value =
|
present_value =
|
||||||
Multistate_Output_Level[object_index][array_index-1];
|
Multistate_Output_Level[object_index][array_index -
|
||||||
|
1];
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_tagged_unsigned(&apdu[0],
|
encode_tagged_unsigned(&apdu[0], present_value);
|
||||||
present_value);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -292,10 +292,8 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
@@ -307,14 +305,14 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
object. */
|
object. */
|
||||||
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
|
||||||
(priority != 6 /* reserved */ ) &&
|
(priority != 6 /* reserved */ ) &&
|
||||||
(value.type.Unsigned_Int <=
|
(value.type.Unsigned_Int <= MULTISTATE_NUMBER_OF_STATES)) {
|
||||||
MULTISTATE_NUMBER_OF_STATES)) {
|
|
||||||
level = value.type.Unsigned_Int;
|
level = value.type.Unsigned_Int;
|
||||||
object_index =
|
object_index =
|
||||||
Multistate_Output_Instance_To_Index(wp_data->
|
Multistate_Output_Instance_To_Index(wp_data->
|
||||||
object_instance);
|
object_instance);
|
||||||
priority--;
|
priority--;
|
||||||
Multistate_Output_Level[object_index][priority] = (uint8_t)level;
|
Multistate_Output_Level[object_index][priority] =
|
||||||
|
(uint8_t) level;
|
||||||
/* Note: you could set the physical output here if we
|
/* Note: you could set the physical output here if we
|
||||||
are the highest priority.
|
are the highest priority.
|
||||||
However, if Out of Service is TRUE, then don't set the
|
However, if Out of Service is TRUE, then don't set the
|
||||||
@@ -339,7 +337,8 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
priority = wp_data->priority;
|
priority = wp_data->priority;
|
||||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||||
priority--;
|
priority--;
|
||||||
Multistate_Output_Level[object_index][priority] = (uint8_t)level;
|
Multistate_Output_Level[object_index][priority] =
|
||||||
|
(uint8_t) level;
|
||||||
/* Note: you could set the physical output here to the next
|
/* Note: you could set the physical output here to the next
|
||||||
highest priority, or to the relinquish default if no
|
highest priority, or to the relinquish default if no
|
||||||
priorities are set.
|
priorities are set.
|
||||||
|
|||||||
@@ -162,72 +162,73 @@ int main(int argc, char *argv[])
|
|||||||
printf("Usage: %s device-instance object-type object-instance "
|
printf("Usage: %s device-instance object-type object-instance "
|
||||||
"property tag value [priority] [index]\r\n",
|
"property tag value [priority] [index]\r\n",
|
||||||
filename_remove_path(argv[0]));
|
filename_remove_path(argv[0]));
|
||||||
if ((argc > 1) && (strcmp(argv[1],"--help") == 0)) {
|
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
|
||||||
printf("device-instance:\r\n"
|
printf("device-instance:\r\n"
|
||||||
"BACnet Device Object Instance number that you are trying to\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"
|
"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"
|
"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"
|
"writing to Device Object 123, the device-instance would be 123.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"object-type:\r\n"
|
"object-type:\r\n"
|
||||||
"The object type is the integer value of the enumeration\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"
|
"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"
|
"writing to. For example if you were writing to Analog Output 2, \r\n"
|
||||||
"the object-type would be 1.\r\n"
|
"the object-type would be 1.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"object-instance:\r\n"
|
"object-instance:\r\n"
|
||||||
"This is the object instance number of the object that you are \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"
|
"writing to. For example, if you were writing to Analog Output 2, \r\n"
|
||||||
"the object-instance would be 2.\r\n"
|
"the object-instance would be 2.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"property:\r\n"
|
"property:\r\n"
|
||||||
"The property is an integer value of the enumeration \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"
|
"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"
|
"writing to. For example, if you were writing to the Present Value\r\n"
|
||||||
"property, you would use 85 as the property.\r\n"
|
"property, you would use 85 as the property.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"tag:\r\n"
|
"tag:\r\n"
|
||||||
"Tag is the integer value of the enumeration BACNET_APPLICATION_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"
|
"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"
|
"writing. For example, if you were writing a REAL value, you would \r\n"
|
||||||
"use a tag of 4."
|
"use a tag of 4."
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"value:\r\n"
|
"value:\r\n"
|
||||||
"The value is an ASCII representation of some type of data that you\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"
|
"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"
|
"example, if you were writing a REAL value of 100.0, you would use \r\n"
|
||||||
"100.0 as the value.\r\n"
|
"100.0 as the value.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"[priority]:\r\n"
|
"[priority]:\r\n"
|
||||||
"This optional parameter is used for setting the priority of the\r\n"
|
"This optional parameter is used for setting the priority of the\r\n"
|
||||||
"write. If no priority is given, none is sent, and the BACnet \r\n"
|
"write. If no priority is given, none is sent, and the BACnet \r\n"
|
||||||
"standard requires that the value is written at the lowest \r\n"
|
"standard requires that the value is written at the lowest \r\n"
|
||||||
"priority (16) if the object property supports priorities.\r\n"
|
"priority (16) if the object property supports priorities.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"[index]\r\n"
|
"[index]\r\n"
|
||||||
"This optional integer parameter is the index number of an array.\r\n"
|
"This optional integer parameter is the index number of an array.\r\n"
|
||||||
"If the property is an array, individual elements can be written\r\n"
|
"If the property is an array, individual elements can be written\r\n"
|
||||||
"to if supported.\r\n"
|
"to if supported.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"Here is a brief overview of BACnet property and tags:\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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"to do negative testing by passing the wrong tag and have the server\r\n"
|
||||||
"return a reject message.\r\n"
|
"return a reject message.\r\n"
|
||||||
"\r\n"
|
"\r\n"
|
||||||
"Example:\r\n"
|
"Example:\r\n"
|
||||||
"If you want send a 100 to the Present-Value in the Analog Output\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"
|
"at priority 16, you could send the following command:\r\n"
|
||||||
"%s 123 1 0 85 4 100\r\n"
|
"%s 123 1 0 85 4 100\r\n"
|
||||||
"You could also send a relinquish command:\r\n"
|
"You could also send a relinquish command:\r\n"
|
||||||
"%s 123 1 0 85 0 0\r\n",
|
"%s 123 1 0 85 0 0\r\n",
|
||||||
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
|
filename_remove_path(argv[0]),
|
||||||
|
filename_remove_path(argv[0]));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-5
@@ -218,11 +218,8 @@ void testIAm(Test * pTest)
|
|||||||
|
|
||||||
#ifdef TEST_IAM
|
#ifdef TEST_IAM
|
||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
int datalink_send_pdu(
|
int datalink_send_pdu(BACNET_ADDRESS * dest,
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_NPDU_DATA * npdu_data, uint8_t * pdu, unsigned pdu_len)
|
||||||
BACNET_NPDU_DATA * npdu_data,
|
|
||||||
uint8_t * pdu,
|
|
||||||
unsigned pdu_len)
|
|
||||||
{
|
{
|
||||||
(void) dest;
|
(void) dest;
|
||||||
(void) npdu_data;
|
(void) npdu_data;
|
||||||
|
|||||||
+2
-1
@@ -337,7 +337,8 @@ void npdu_handler(BACNET_ADDRESS * src, /* source address */
|
|||||||
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
|
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
|
||||||
/* only handle the version that we know how to handle */
|
/* only handle the version that we know how to handle */
|
||||||
if (npdu_data.protocol_version == BACNET_PROTOCOL_VERSION)
|
if (npdu_data.protocol_version == BACNET_PROTOCOL_VERSION)
|
||||||
apdu_handler(src, &pdu[apdu_offset], (uint16_t)(pdu_len - apdu_offset));
|
apdu_handler(src, &pdu[apdu_offset],
|
||||||
|
(uint16_t) (pdu_len - apdu_offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -49,23 +49,23 @@ static uint32_t Object_Instance_Number = 12345;
|
|||||||
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
|
||||||
|
|
||||||
BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State =
|
BACNET_REINITIALIZED_STATE_OF_DEVICE Reinitialize_State =
|
||||||
REINITIALIZED_STATE_IDLE;
|
REINITIALIZED_STATE_IDLE;
|
||||||
|
|
||||||
void Device_Reinit(void)
|
void Device_Reinit(void)
|
||||||
{
|
{
|
||||||
dcc_set_status_duration(COMMUNICATION_ENABLE,0);
|
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
|
||||||
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device_Init(void)
|
void Device_Init(void)
|
||||||
{
|
{
|
||||||
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
Reinitialize_State = REINITIALIZED_STATE_IDLE;
|
||||||
dcc_set_status_duration(COMMUNICATION_ENABLE,0);
|
dcc_set_status_duration(COMMUNICATION_ENABLE, 0);
|
||||||
/* FIXME: Get the data from the eeprom */
|
/* FIXME: Get the data from the eeprom */
|
||||||
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
|
||||||
(char *)&Object_Instance_Number,
|
(char *)&Object_Instance_Number,
|
||||||
sizeof(Object_Instance_Number),
|
sizeof(Object_Instance_Number),
|
||||||
EEPROM_BACNET_ID_ADDR); */
|
EEPROM_BACNET_ID_ADDR); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* methods to manipulate the data */
|
/* methods to manipulate the data */
|
||||||
@@ -78,17 +78,15 @@ bool Device_Set_Object_Instance_Number(uint32_t object_id)
|
|||||||
{
|
{
|
||||||
bool status = true; /* return value */
|
bool status = true; /* return value */
|
||||||
|
|
||||||
if (object_id <= BACNET_MAX_INSTANCE)
|
if (object_id <= BACNET_MAX_INSTANCE) {
|
||||||
{
|
|
||||||
Object_Instance_Number = object_id;
|
Object_Instance_Number = object_id;
|
||||||
/* FIXME: Write the data to the eeprom */
|
/* FIXME: Write the data to the eeprom */
|
||||||
/* I2C_Write_Block(
|
/* I2C_Write_Block(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
(char *)&Object_Instance_Number,
|
(char *)&Object_Instance_Number,
|
||||||
sizeof(Object_Instance_Number),
|
sizeof(Object_Instance_Number),
|
||||||
EEPROM_BACNET_ID_ADDR); */
|
EEPROM_BACNET_ID_ADDR); */
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
status = false;
|
status = false;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -109,7 +107,7 @@ BACNET_DEVICE_STATUS Device_System_Status(void)
|
|||||||
void Device_Set_System_Status(BACNET_DEVICE_STATUS status)
|
void Device_Set_System_Status(BACNET_DEVICE_STATUS status)
|
||||||
{
|
{
|
||||||
if (status < MAX_DEVICE_STATUS)
|
if (status < MAX_DEVICE_STATUS)
|
||||||
System_Status = status;
|
System_Status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: put your vendor ID here! */
|
/* FIXME: put your vendor ID here! */
|
||||||
@@ -159,7 +157,7 @@ uint8_t Device_Database_Revision(void)
|
|||||||
/* for discovery, it must be consistent! */
|
/* for discovery, it must be consistent! */
|
||||||
unsigned Device_Object_List_Count(void)
|
unsigned Device_Object_List_Count(void)
|
||||||
{
|
{
|
||||||
unsigned count = 1;/* at least 1 for device object */
|
unsigned count = 1; /* at least 1 for device object */
|
||||||
|
|
||||||
/* FIXME: add objects as needed */
|
/* FIXME: add objects as needed */
|
||||||
#if 0
|
#if 0
|
||||||
@@ -186,7 +184,7 @@ bool Device_Object_List_Identifier(unsigned array_index,
|
|||||||
*instance = Object_Instance_Number;
|
*instance = Object_Instance_Number;
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
/* FIXME: add objects as needed */
|
/* FIXME: add objects as needed */
|
||||||
/* binary input objects */
|
/* binary input objects */
|
||||||
if (!status) {
|
if (!status) {
|
||||||
@@ -226,7 +224,7 @@ bool Device_Object_List_Identifier(unsigned array_index,
|
|||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -247,7 +245,7 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
BACNET_TIME local_time;
|
BACNET_TIME local_time;
|
||||||
BACNET_DATE local_date;
|
BACNET_DATE local_date;
|
||||||
uint8_t year = 0;
|
uint8_t year = 0;
|
||||||
char string_buffer[24];
|
char string_buffer[24];
|
||||||
int16_t TimeZone = 0;
|
int16_t TimeZone = 0;
|
||||||
|
|
||||||
@@ -258,7 +256,7 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
Object_Instance_Number);
|
Object_Instance_Number);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_NAME:
|
case PROP_OBJECT_NAME:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "PIC18F6720 Device");
|
(void) strcpypgm2ram(&string_buffer[0], "PIC18F6720 Device");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
@@ -266,38 +264,40 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE);
|
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE);
|
||||||
break;
|
break;
|
||||||
case PROP_DESCRIPTION:
|
case PROP_DESCRIPTION:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "BACnet Demo");
|
(void) strcpypgm2ram(&string_buffer[0], "BACnet Demo");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_SYSTEM_STATUS:
|
case PROP_SYSTEM_STATUS:
|
||||||
apdu_len = encode_tagged_enumerated(&apdu[0], Device_System_Status());
|
apdu_len =
|
||||||
|
encode_tagged_enumerated(&apdu[0], Device_System_Status());
|
||||||
break;
|
break;
|
||||||
case PROP_VENDOR_NAME:
|
case PROP_VENDOR_NAME:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "ASHRAE");
|
(void) strcpypgm2ram(&string_buffer[0], "ASHRAE");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_VENDOR_IDENTIFIER:
|
case PROP_VENDOR_IDENTIFIER:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0], Device_Vendor_Identifier());
|
apdu_len =
|
||||||
|
encode_tagged_unsigned(&apdu[0], Device_Vendor_Identifier());
|
||||||
break;
|
break;
|
||||||
case PROP_MODEL_NAME:
|
case PROP_MODEL_NAME:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "GNU Demo");
|
(void) strcpypgm2ram(&string_buffer[0], "GNU Demo");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_FIRMWARE_REVISION:
|
case PROP_FIRMWARE_REVISION:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "1.00");
|
(void) strcpypgm2ram(&string_buffer[0], "1.00");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_APPLICATION_SOFTWARE_VERSION:
|
case PROP_APPLICATION_SOFTWARE_VERSION:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "1.00");
|
(void) strcpypgm2ram(&string_buffer[0], "1.00");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
case PROP_LOCATION:
|
case PROP_LOCATION:
|
||||||
(void)strcpypgm2ram(&string_buffer[0], "USA");
|
(void) strcpypgm2ram(&string_buffer[0], "USA");
|
||||||
characterstring_init_ansi(&char_string, string_buffer);
|
characterstring_init_ansi(&char_string, string_buffer);
|
||||||
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
apdu_len = encode_tagged_character_string(&apdu[0], &char_string);
|
||||||
break;
|
break;
|
||||||
@@ -333,11 +333,11 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
}
|
}
|
||||||
/* FIXME: indicate the objects that YOU support */
|
/* FIXME: indicate the objects that YOU support */
|
||||||
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
|
||||||
#if 0
|
#if 0
|
||||||
bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true);
|
bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true);
|
||||||
bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true);
|
bitstring_set_bit(&bit_string, OBJECT_ANALOG_INPUT, true);
|
||||||
bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true);
|
bitstring_set_bit(&bit_string, OBJECT_BINARY_INPUT, true);
|
||||||
#endif
|
#endif
|
||||||
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
|
apdu_len = encode_tagged_bitstring(&apdu[0], &bit_string);
|
||||||
break;
|
break;
|
||||||
case PROP_OBJECT_LIST:
|
case PROP_OBJECT_LIST:
|
||||||
@@ -399,16 +399,19 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
break;
|
break;
|
||||||
case PROP_NUMBER_OF_APDU_RETRIES:
|
case PROP_NUMBER_OF_APDU_RETRIES:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
encode_tagged_unsigned(&apdu[0], Device_Number_Of_APDU_Retries());
|
encode_tagged_unsigned(&apdu[0],
|
||||||
|
Device_Number_Of_APDU_Retries());
|
||||||
break;
|
break;
|
||||||
case PROP_DEVICE_ADDRESS_BINDING:
|
case PROP_DEVICE_ADDRESS_BINDING:
|
||||||
/* FIXME: encode the list here, if it exists */
|
/* FIXME: encode the list here, if it exists */
|
||||||
break;
|
break;
|
||||||
case PROP_DATABASE_REVISION:
|
case PROP_DATABASE_REVISION:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0], Device_Database_Revision());
|
apdu_len =
|
||||||
|
encode_tagged_unsigned(&apdu[0], Device_Database_Revision());
|
||||||
break;
|
break;
|
||||||
case PROP_MAX_INFO_FRAMES:
|
case PROP_MAX_INFO_FRAMES:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0], dlmstp_max_info_frames());
|
apdu_len =
|
||||||
|
encode_tagged_unsigned(&apdu[0], dlmstp_max_info_frames());
|
||||||
break;
|
break;
|
||||||
case PROP_MAX_MASTER:
|
case PROP_MAX_MASTER:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0], dlmstp_max_master());
|
apdu_len = encode_tagged_unsigned(&apdu[0], dlmstp_max_master());
|
||||||
@@ -423,14 +426,14 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
break;
|
break;
|
||||||
case PROP_UTC_OFFSET:
|
case PROP_UTC_OFFSET:
|
||||||
/* Note: BACnet Time Zone is inverse of everybody else */
|
/* Note: BACnet Time Zone is inverse of everybody else */
|
||||||
apdu_len = encode_tagged_signed(&apdu[0], 5 /* EST */);
|
apdu_len = encode_tagged_signed(&apdu[0], 5 /* EST */ );
|
||||||
break;
|
break;
|
||||||
case PROP_LOCAL_DATE:
|
case PROP_LOCAL_DATE:
|
||||||
/* FIXME: if you support date */
|
/* FIXME: if you support date */
|
||||||
local_date.year = 2006; /* AD */
|
local_date.year = 2006; /* AD */
|
||||||
local_date.month = 4; /* Jan=1..Dec=12 */
|
local_date.month = 4; /* Jan=1..Dec=12 */
|
||||||
local_date.day = 11; /* 1..31 */
|
local_date.day = 11; /* 1..31 */
|
||||||
local_date.wday = 0; /* 1=Mon..7=Sun */
|
local_date.wday = 0; /* 1=Mon..7=Sun */
|
||||||
apdu_len = encode_tagged_date(&apdu[0], &local_date);
|
apdu_len = encode_tagged_date(&apdu[0], &local_date);
|
||||||
break;
|
break;
|
||||||
case PROP_DAYLIGHT_SAVINGS_STATUS:
|
case PROP_DAYLIGHT_SAVINGS_STATUS:
|
||||||
@@ -463,10 +466,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(wp_data->application_data,
|
||||||
wp_data->application_data,
|
wp_data->application_data_len, &value);
|
||||||
wp_data->application_data_len,
|
|
||||||
&value);
|
|
||||||
/* FIXME: len < application_data_len: more data? */
|
/* FIXME: len < application_data_len: more data? */
|
||||||
/* FIXME: len == 0: unable to decode? */
|
/* FIXME: len == 0: unable to decode? */
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
@@ -527,7 +528,7 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
if (len <= 20) {
|
if (len <= 20) {
|
||||||
/* FIXME: set the name */
|
/* FIXME: set the name */
|
||||||
/* Display_Set_Name(
|
/* Display_Set_Name(
|
||||||
characterstring_value(&value.type.Character_String)); */
|
characterstring_value(&value.type.Character_String)); */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
*error_class = ERROR_CLASS_PROPERTY;
|
*error_class = ERROR_CLASS_PROPERTY;
|
||||||
@@ -564,4 +565,3 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
#include "rs485.h"
|
#include "rs485.h"
|
||||||
#include "npdu.h"
|
#include "npdu.h"
|
||||||
|
|
||||||
// Number of MS/TP Packets Rx/Tx
|
/* Number of MS/TP Packets Rx/Tx
*/
|
||||||
uint16_t MSTP_Packets = 0;
|
uint16_t MSTP_Packets = 0;
|
||||||
|
|
||||||
/* receive buffer */
|
/* receive buffer */
|
||||||
@@ -49,9 +49,9 @@ volatile struct mstp_port_struct_t MSTP_Port;
|
|||||||
|
|
||||||
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
|
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
|
||||||
|
|
||||||
// This defines the number of edit fields for this module
|
/* This defines the number of edit fields for this module
*/
|
||||||
#define MAX_EDIT_FIELD 1
|
#define MAX_EDIT_FIELD 1
|
||||||
static uint8_t EditField = 0;
|
static uint8_t EditField = 0;
|
||||||
/* *************************************************************************
|
/* *************************************************************************
|
||||||
DESCRIPTION: This function handles incrementing or decrementing our
|
DESCRIPTION: This function handles incrementing or decrementing our
|
||||||
EditField
|
EditField
|
||||||
@@ -59,23 +59,18 @@ static uint8_t EditField = 0;
|
|||||||
ALGORITHM: none
|
ALGORITHM: none
|
||||||
NOTES: Pass a #>0 to increment #<0 to decrement
|
NOTES: Pass a #>0 to increment #<0 to decrement
|
||||||
*************************************************************************** */
|
*************************************************************************** */
|
||||||
void dlmstp_SetEditField(
|
void dlmstp_SetEditField(signed char state)
|
||||||
signed char state) /* direction our editfield is moving */
|
{ /* direction our editfield is moving */
|
||||||
{
|
if (state > 0) {
|
||||||
if (state > 0)
|
if (++EditField > MAX_EDIT_FIELD)
|
||||||
{
|
EditField = 0;
|
||||||
if (++EditField > MAX_EDIT_FIELD)
|
} else if (state < 0) {
|
||||||
EditField = 0;
|
if (EditField)
|
||||||
}
|
EditField--;
|
||||||
else if (state < 0)
|
else
|
||||||
{
|
EditField = MAX_EDIT_FIELD;
|
||||||
if (EditField)
|
} else
|
||||||
EditField--;
|
EditField = 0;
|
||||||
else
|
|
||||||
EditField = MAX_EDIT_FIELD;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
EditField = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *************************************************************************
|
/* *************************************************************************
|
||||||
@@ -86,12 +81,12 @@ void dlmstp_SetEditField(
|
|||||||
*************************************************************************** */
|
*************************************************************************** */
|
||||||
uint8_t dlmstp_GetEditField(void)
|
uint8_t dlmstp_GetEditField(void)
|
||||||
{
|
{
|
||||||
return (EditField);
|
return (EditField);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlmstp_millisecond_timer(void)
|
void dlmstp_millisecond_timer(void)
|
||||||
{
|
{
|
||||||
INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer);
|
INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dlmstp_reinit(void)
|
void dlmstp_reinit(void)
|
||||||
@@ -114,26 +109,26 @@ void dlmstp_init(void)
|
|||||||
MSTP_Port.InputBuffer = &Receive_Buffer.pdu[0];
|
MSTP_Port.InputBuffer = &Receive_Buffer.pdu[0];
|
||||||
MSTP_Init(&MSTP_Port);
|
MSTP_Init(&MSTP_Port);
|
||||||
/* FIXME: implement your data storage */
|
/* FIXME: implement your data storage */
|
||||||
data = 64; /* I2C_Read_Byte(
|
data = 64; /* I2C_Read_Byte(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
EEPROM_MSTP_MAC_ADDR); */
|
EEPROM_MSTP_MAC_ADDR); */
|
||||||
if (data <= 127)
|
if (data <= 127)
|
||||||
MSTP_Port.This_Station = data;
|
MSTP_Port.This_Station = data;
|
||||||
else
|
else
|
||||||
dlmstp_set_my_address(DEFAULT_MAC_ADDRESS);
|
dlmstp_set_my_address(DEFAULT_MAC_ADDRESS);
|
||||||
/* FIXME: implement your data storage */
|
/* FIXME: implement your data storage */
|
||||||
data = 127; /* I2C_Read_Byte(
|
data = 127; /* I2C_Read_Byte(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
EEPROM_MSTP_MAX_MASTER_ADDR); */
|
EEPROM_MSTP_MAX_MASTER_ADDR); */
|
||||||
if ((data <= 127) && (data >= MSTP_Port.This_Station))
|
if ((data <= 127) && (data >= MSTP_Port.This_Station))
|
||||||
MSTP_Port.Nmax_master = data;
|
MSTP_Port.Nmax_master = data;
|
||||||
else
|
else
|
||||||
dlmstp_set_max_master(DEFAULT_MAX_MASTER);
|
dlmstp_set_max_master(DEFAULT_MAX_MASTER);
|
||||||
/* FIXME: implement your data storage */
|
/* FIXME: implement your data storage */
|
||||||
data = 1;
|
data = 1;
|
||||||
/* I2C_Read_Byte(
|
/* I2C_Read_Byte(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
|
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
|
||||||
if (data >= 1)
|
if (data >= 1)
|
||||||
MSTP_Port.Nmax_info_frames = data;
|
MSTP_Port.Nmax_info_frames = data;
|
||||||
else
|
else
|
||||||
@@ -156,7 +151,7 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|||||||
uint8_t frame_type = 0;
|
uint8_t frame_type = 0;
|
||||||
uint8_t destination = 0; /* destination address */
|
uint8_t destination = 0; /* destination address */
|
||||||
BACNET_ADDRESS src;
|
BACNET_ADDRESS src;
|
||||||
unsigned i = 0; /* loop counter */
|
unsigned i = 0; /* loop counter */
|
||||||
|
|
||||||
if (MSTP_Port.TxReady == false) {
|
if (MSTP_Port.TxReady == false) {
|
||||||
if (npdu_data->data_expecting_reply)
|
if (npdu_data->data_expecting_reply)
|
||||||
@@ -172,15 +167,14 @@ int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
|
|||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
dlmstp_get_my_address(&src);
|
dlmstp_get_my_address(&src);
|
||||||
if ((8 /* header len */ + pdu_len) > MAX_MPDU) {
|
if ((8 /* header len */ + pdu_len) > MAX_MPDU) {
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
bytes_sent = MSTP_Create_Frame(
|
bytes_sent = MSTP_Create_Frame(
|
||||||
(uint8_t *) & MSTP_Port.TxBuffer[0],
|
(uint8_t *) & MSTP_Port.TxBuffer[0],
|
||||||
sizeof(MSTP_Port.TxBuffer),
|
sizeof(MSTP_Port.TxBuffer),
|
||||||
MSTP_Port.TxFrameType,
|
MSTP_Port.TxFrameType,
|
||||||
destination,
|
destination, MSTP_Port.This_Station, pdu, pdu_len);
|
||||||
MSTP_Port.This_Station, pdu, pdu_len);
|
|
||||||
MSTP_Port.TxLength = bytes_sent;
|
MSTP_Port.TxLength = bytes_sent;
|
||||||
MSTP_Port.TxReady = true;
|
MSTP_Port.TxReady = true;
|
||||||
MSTP_Packets++;
|
MSTP_Packets++;
|
||||||
@@ -196,8 +190,7 @@ void dlmstp_task(void)
|
|||||||
|
|
||||||
/* only do receive state machine while we don't have a frame */
|
/* only do receive state machine while we don't have a frame */
|
||||||
if ((MSTP_Port.ReceivedValidFrame == false) &&
|
if ((MSTP_Port.ReceivedValidFrame == false) &&
|
||||||
(MSTP_Port.ReceivedInvalidFrame == false))
|
(MSTP_Port.ReceivedInvalidFrame == false)) {
|
||||||
{
|
|
||||||
do {
|
do {
|
||||||
bytes_remaining = RS485_Check_UART_Data(&MSTP_Port);
|
bytes_remaining = RS485_Check_UART_Data(&MSTP_Port);
|
||||||
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
MSTP_Receive_Frame_FSM(&MSTP_Port);
|
||||||
@@ -209,18 +202,17 @@ void dlmstp_task(void)
|
|||||||
}
|
}
|
||||||
/* only do master state machine while rx is idle */
|
/* only do master state machine while rx is idle */
|
||||||
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) {
|
if (MSTP_Port.receive_state == MSTP_RECEIVE_STATE_IDLE) {
|
||||||
while (MSTP_Master_Node_FSM(&MSTP_Port)) {};
|
while (MSTP_Master_Node_FSM(&MSTP_Port)) {
|
||||||
//MSTP_Master_Node_FSM(&MSTP_Port);
|
};
|
||||||
|
/*MSTP_Master_Node_FSM(&MSTP_Port);
*/
|
||||||
}
|
}
|
||||||
/* see if there is a packet available, and a place
|
/* see if there is a packet available, and a place
|
||||||
to put the reply (if necessary) and process it */
|
to put the reply (if necessary) and process it */
|
||||||
if (Receive_Buffer.ready && !MSTP_Port.TxReady) {
|
if (Receive_Buffer.ready && !MSTP_Port.TxReady) {
|
||||||
if (Receive_Buffer.pdu_len) {
|
if (Receive_Buffer.pdu_len) {
|
||||||
MSTP_Packets++;
|
MSTP_Packets++;
|
||||||
npdu_handler(
|
npdu_handler(&Receive_Buffer.address,
|
||||||
&Receive_Buffer.address,
|
&Receive_Buffer.pdu[0], Receive_Buffer.pdu_len);
|
||||||
&Receive_Buffer.pdu[0],
|
|
||||||
Receive_Buffer.pdu_len);
|
|
||||||
}
|
}
|
||||||
Receive_Buffer.ready = false;
|
Receive_Buffer.ready = false;
|
||||||
}
|
}
|
||||||
@@ -252,11 +244,10 @@ void dlmstp_fill_bacnet_address(BACNET_ADDRESS * src, uint8_t mstp_address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* for the MS/TP state machine to use for putting received data */
|
/* for the MS/TP state machine to use for putting received data */
|
||||||
uint16_t dlmstp_put_receive(
|
uint16_t dlmstp_put_receive(uint8_t src, /* source MS/TP address */
|
||||||
uint8_t src, /* source MS/TP address */
|
uint8_t * pdu, /* PDU data */
|
||||||
uint8_t * pdu, /* PDU data */
|
uint16_t pdu_len)
|
||||||
uint16_t pdu_len) /* amount of PDU data */
|
{ /* amount of PDU data */
|
||||||
{
|
|
||||||
/* PDU is already in the Receive_Buffer */
|
/* PDU is already in the Receive_Buffer */
|
||||||
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
|
dlmstp_fill_bacnet_address(&Receive_Buffer.address, src);
|
||||||
Receive_Buffer.pdu_len = pdu_len;
|
Receive_Buffer.pdu_len = pdu_len;
|
||||||
@@ -270,9 +261,9 @@ void dlmstp_set_my_address(uint8_t mac_address)
|
|||||||
MSTP_Port.This_Station = mac_address;
|
MSTP_Port.This_Station = mac_address;
|
||||||
/* FIXME: implement your data storage */
|
/* FIXME: implement your data storage */
|
||||||
/* I2C_Write_Byte(
|
/* I2C_Write_Byte(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
mac_address,
|
mac_address,
|
||||||
EEPROM_MSTP_MAC_ADDR); */
|
EEPROM_MSTP_MAC_ADDR); */
|
||||||
if (mac_address > MSTP_Port.Nmax_master)
|
if (mac_address > MSTP_Port.Nmax_master)
|
||||||
dlmstp_set_max_master(mac_address);
|
dlmstp_set_max_master(mac_address);
|
||||||
}
|
}
|
||||||
@@ -298,9 +289,9 @@ void dlmstp_set_max_info_frames(uint8_t max_info_frames)
|
|||||||
MSTP_Port.Nmax_info_frames = max_info_frames;
|
MSTP_Port.Nmax_info_frames = max_info_frames;
|
||||||
/* FIXME: implement your data storage */
|
/* FIXME: implement your data storage */
|
||||||
/* I2C_Write_Byte(
|
/* I2C_Write_Byte(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
(uint8_t)max_info_frames,
|
(uint8_t)max_info_frames,
|
||||||
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
|
EEPROM_MSTP_MAX_INFO_FRAMES_ADDR); */
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -323,9 +314,9 @@ void dlmstp_set_max_master(uint8_t max_master)
|
|||||||
MSTP_Port.Nmax_master = max_master;
|
MSTP_Port.Nmax_master = max_master;
|
||||||
/* FIXME: implement your data storage */
|
/* FIXME: implement your data storage */
|
||||||
/* I2C_Write_Byte(
|
/* I2C_Write_Byte(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
max_master,
|
max_master,
|
||||||
EEPROM_MSTP_MAX_MASTER_ADDR); */
|
EEPROM_MSTP_MAX_MASTER_ADDR); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
typedef struct dlmstp_packet {
|
typedef struct dlmstp_packet {
|
||||||
bool ready; /* true if ready to be sent or received */
|
bool ready; /* true if ready to be sent or received */
|
||||||
BACNET_ADDRESS address; /* source address */
|
BACNET_ADDRESS address; /* source address */
|
||||||
uint8_t frame_type; /* type of message */
|
uint8_t frame_type; /* type of message */
|
||||||
unsigned pdu_len; /* packet length */
|
unsigned pdu_len; /* packet length */
|
||||||
uint8_t pdu[MAX_MPDU]; /* packet */
|
uint8_t pdu[MAX_MPDU]; /* packet */
|
||||||
} DLMSTP_PACKET;
|
} DLMSTP_PACKET;
|
||||||
|
|||||||
@@ -105,13 +105,13 @@
|
|||||||
|
|
||||||
#define ZERO_CROSS PORTBbits.RB0
|
#define ZERO_CROSS PORTBbits.RB0
|
||||||
|
|
||||||
#define PORT_A_TRIS_MASK 0x11 /* 0b00010001 */
|
#define PORT_A_TRIS_MASK 0x11 /* 0b00010001 */
|
||||||
#define PORT_B_TRIS_MASK 0xC7 /* 0b11000111 */
|
#define PORT_B_TRIS_MASK 0xC7 /* 0b11000111 */
|
||||||
#define PORT_C_TRIS_MASK 0x9C /* 0b10011100 */
|
#define PORT_C_TRIS_MASK 0x9C /* 0b10011100 */
|
||||||
#define PORT_D_TRIS_MASK 0xFF /* 0b11111111 */
|
#define PORT_D_TRIS_MASK 0xFF /* 0b11111111 */
|
||||||
#define PORT_E_TRIS_MASK 0x88 /* 0b10001000 */
|
#define PORT_E_TRIS_MASK 0x88 /* 0b10001000 */
|
||||||
#define PORT_F_TRIS_MASK 0x00 /* 0b00000000 */
|
#define PORT_F_TRIS_MASK 0x00 /* 0b00000000 */
|
||||||
#define PORT_G_TRIS_MASK 0x04 /* 0b00000100 */
|
#define PORT_G_TRIS_MASK 0x04 /* 0b00000100 */
|
||||||
|
|
||||||
#define TURN_OFF_COMPARATORS() CMCON = 0x07
|
#define TURN_OFF_COMPARATORS() CMCON = 0x07
|
||||||
|
|
||||||
@@ -121,86 +121,81 @@
|
|||||||
#define CLICK() Hardware_Sound_Piezo(SHORT_BEEP);
|
#define CLICK() Hardware_Sound_Piezo(SHORT_BEEP);
|
||||||
#define BEEP() Hardware_Sound_Piezo(LONG_BEEP);
|
#define BEEP() Hardware_Sound_Piezo(LONG_BEEP);
|
||||||
|
|
||||||
typedef union
|
typedef union {
|
||||||
{
|
struct {
|
||||||
struct
|
uint8_t:1;
|
||||||
{
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t Thursday:1;
|
||||||
uint8_t:1;
|
uint8_t Wednesday:1;
|
||||||
uint8_t Thursday : 1;
|
uint8_t Tuesday:1;
|
||||||
uint8_t Wednesday : 1;
|
uint8_t Monday:1;
|
||||||
uint8_t Tuesday : 1;
|
uint8_t Program:1;
|
||||||
uint8_t Monday : 1;
|
uint8_t Run:1;
|
||||||
uint8_t Program : 1;
|
|
||||||
uint8_t Run : 1;
|
|
||||||
|
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t Input1 : 1;
|
uint8_t Input1:1;
|
||||||
uint8_t Input2 : 1;
|
uint8_t Input2:1;
|
||||||
uint8_t Input3 : 1;
|
uint8_t Input3:1;
|
||||||
uint8_t Input4 : 1;
|
uint8_t Input4:1;
|
||||||
uint8_t Input5 : 1;
|
uint8_t Input5:1;
|
||||||
uint8_t Input6 : 1;
|
uint8_t Input6:1;
|
||||||
|
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t Input7 : 1;
|
uint8_t Input7:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t Input8 : 1;
|
uint8_t Input8:1;
|
||||||
uint8_t Photocell : 1;
|
uint8_t Photocell:1;
|
||||||
|
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t Remote : 1;
|
uint8_t Remote:1;
|
||||||
uint8_t Relay8 : 1;
|
uint8_t Relay8:1;
|
||||||
|
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t Relay7 : 1;
|
uint8_t Relay7:1;
|
||||||
uint8_t Relay6 : 1;
|
uint8_t Relay6:1;
|
||||||
uint8_t Relay5 : 1;
|
uint8_t Relay5:1;
|
||||||
uint8_t Relay4 : 1;
|
uint8_t Relay4:1;
|
||||||
uint8_t Relay3 : 1;
|
uint8_t Relay3:1;
|
||||||
|
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t:1;
|
uint8_t:1;
|
||||||
uint8_t Relay2 : 1;
|
uint8_t Relay2:1;
|
||||||
uint8_t Relay1 : 1;
|
uint8_t Relay1:1;
|
||||||
uint8_t Holiday : 1;
|
uint8_t Holiday:1;
|
||||||
uint8_t Sunday : 1;
|
uint8_t Sunday:1;
|
||||||
uint8_t Saturday : 1;
|
uint8_t Saturday:1;
|
||||||
uint8_t Friday : 1;
|
uint8_t Friday:1;
|
||||||
};
|
};
|
||||||
struct
|
struct {
|
||||||
{
|
uint8_t row1;
|
||||||
uint8_t row1;
|
uint8_t row2;
|
||||||
uint8_t row2;
|
uint8_t row3;
|
||||||
uint8_t row3;
|
uint8_t row4;
|
||||||
uint8_t row4;
|
uint8_t row5;
|
||||||
uint8_t row5;
|
uint8_t row6;
|
||||||
uint8_t row6;
|
};
|
||||||
};
|
|
||||||
} LED_REGS;
|
} LED_REGS;
|
||||||
|
|
||||||
union SWITCH_REGS
|
union SWITCH_REGS {
|
||||||
{
|
struct {
|
||||||
struct
|
uint8_t All_On:1;
|
||||||
{
|
uint8_t All_Off:1;
|
||||||
uint8_t All_On : 1;
|
uint8_t Addr:4;
|
||||||
uint8_t All_Off : 1;
|
uint8_t Pilot_Fault:1;
|
||||||
uint8_t Addr : 4;
|
uint8_t Master:1;
|
||||||
uint8_t Pilot_Fault : 1;
|
};
|
||||||
uint8_t Master : 1;
|
uint8_t Sw_Byte;
|
||||||
};
|
|
||||||
uint8_t Sw_Byte;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum INT_STATE { INT_DISABLED, INT_ENABLED, INT_RESTORE };
|
enum INT_STATE { INT_DISABLED, INT_ENABLED, INT_RESTORE };
|
||||||
@@ -259,10 +254,9 @@ enum INT_STATE { INT_DISABLED, INT_ENABLED, INT_RESTORE };
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Global Vars */
|
/* Global Vars */
|
||||||
extern volatile LED_REGS LEDS;
|
extern volatile LED_REGS LEDS;
|
||||||
extern volatile LED_REGS Blink;
|
extern volatile LED_REGS Blink;
|
||||||
extern uint8_t Piezo_Timer;
|
extern uint8_t Piezo_Timer;
|
||||||
extern volatile bool DataPortLocked;
|
extern volatile bool DataPortLocked;
|
||||||
|
|
||||||
#endif /* HARDWARE_H */
|
|
||||||
|
|
||||||
|
#endif /* HARDWARE_H */
|
||||||
|
|||||||
@@ -43,55 +43,44 @@ void Interrupt_CCP2(void);
|
|||||||
void INT0_Interrupt(void);
|
void INT0_Interrupt(void);
|
||||||
|
|
||||||
#pragma code InterruptVectorHigh = 0x308
|
#pragma code InterruptVectorHigh = 0x308
|
||||||
void InterruptVectorHigh (void)
|
void InterruptVectorHigh(void)
|
||||||
{
|
{
|
||||||
_asm goto InterruptHandlerHigh /* jump to interrupt routine */
|
_asm goto InterruptHandlerHigh /* jump to interrupt routine */
|
||||||
_endasm
|
_endasm}
|
||||||
}
|
|
||||||
#pragma code
|
#pragma code
|
||||||
|
|
||||||
#pragma code InterruptVectorLow = 0x318
|
#pragma code InterruptVectorLow = 0x318
|
||||||
void InterruptVectorLow (void)
|
void InterruptVectorLow(void)
|
||||||
{
|
{
|
||||||
_asm goto InterruptHandlerLow /* jump to interrupt routine */
|
_asm goto InterruptHandlerLow /* jump to interrupt routine */
|
||||||
_endasm
|
_endasm}
|
||||||
}
|
|
||||||
#pragma code
|
#pragma code
|
||||||
|
|
||||||
#pragma interrupt InterruptHandlerHigh
|
#pragma interrupt InterruptHandlerHigh
|
||||||
void InterruptHandlerHigh (void)
|
void InterruptHandlerHigh(void)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
/* check for USART Rx int */
|
/* check for USART Rx int */
|
||||||
if ((PIR1bits.RCIF) && (PIE1bits.RCIE))
|
if ((PIR1bits.RCIF) && (PIE1bits.RCIE)) {
|
||||||
{
|
if ((RCSTA1bits.FERR) || (RCSTA1bits.OERR)) {
|
||||||
if ((RCSTA1bits.FERR) || (RCSTA1bits.OERR))
|
Comstat.Rx_Bufferoverrun = TRUE;
|
||||||
{
|
PIE1bits.RC1IE = 0; /* Disable Interrupt on receipt */
|
||||||
Comstat.Rx_Bufferoverrun = TRUE;
|
} else if (Comstat.Rx_Bytes++ < RX_BUFFER_SIZE - 1) {
|
||||||
PIE1bits.RC1IE = 0; /* Disable Interrupt on receipt */
|
Rx_Buffer[Comstat.RxHead++] = RCREG1;
|
||||||
}
|
|
||||||
else if (Comstat.Rx_Bytes++ < RX_BUFFER_SIZE - 1)
|
|
||||||
{
|
|
||||||
Rx_Buffer[Comstat.RxHead++] = RCREG1;
|
|
||||||
|
|
||||||
/* Stick a Null on the end to let us use str functions on our
|
/* Stick a Null on the end to let us use str functions on our
|
||||||
* buffer */
|
* buffer */
|
||||||
Rx_Buffer[Comstat.RxHead] = 0;
|
Rx_Buffer[Comstat.RxHead] = 0;
|
||||||
|
} else {
|
||||||
|
Comstat.Rx_Bufferoverrun = TRUE;
|
||||||
|
PIE1bits.RC1IE = 0; /* Disable Interrupt on receipt */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
Comstat.Rx_Bufferoverrun = TRUE;
|
|
||||||
PIE1bits.RC1IE = 0; /* Disable Interrupt on receipt */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* check for timer0 int */
|
/* check for timer0 int */
|
||||||
if ((INTCONbits.TMR0IF) && (INTCONbits.TMR0IE))
|
if ((INTCONbits.TMR0IF) && (INTCONbits.TMR0IE)) {
|
||||||
{
|
INTCONbits.TMR0IF = 0;
|
||||||
INTCONbits.TMR0IF = 0;
|
System_Seconds++;
|
||||||
System_Seconds++;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma interruptlow InterruptHandlerLow save = PROD, section(".tmpdata"), TABLAT, TBLPTR, section \
|
#pragma interruptlow InterruptHandlerLow save = PROD, section(".tmpdata"), TABLAT, TBLPTR, section \
|
||||||
@@ -99,46 +88,40 @@ void InterruptHandlerHigh (void)
|
|||||||
|
|
||||||
void InterruptHandlerLow(void)
|
void InterruptHandlerLow(void)
|
||||||
{
|
{
|
||||||
/* check for timer2 int */
|
/* check for timer2 int */
|
||||||
if ((PIR1bits.TMR2IF) && (PIE1bits.TMR2IE))
|
if ((PIR1bits.TMR2IF) && (PIE1bits.TMR2IE)) {
|
||||||
{
|
PIR1bits.TMR2IF = 0;
|
||||||
PIR1bits.TMR2IF = 0;
|
Interrupt_Timer2();
|
||||||
Interrupt_Timer2();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check for timer3 int */
|
/* check for timer3 int */
|
||||||
if ((PIR2bits.TMR3IF) && (PIE2bits.TMR3IE))
|
if ((PIR2bits.TMR3IF) && (PIE2bits.TMR3IE)) {
|
||||||
{
|
PIR2bits.TMR3IF = 0;
|
||||||
PIR2bits.TMR3IF = 0;
|
Interrupt_Timer3();
|
||||||
Interrupt_Timer3();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check for timer4 int */
|
/* check for timer4 int */
|
||||||
if ((PIR3bits.TMR4IF) && (PIE3bits.TMR4IE))
|
if ((PIR3bits.TMR4IF) && (PIE3bits.TMR4IE)) {
|
||||||
{
|
PIR3bits.TMR4IF = 0;
|
||||||
PIR3bits.TMR4IF = 0;
|
dlmstp_millisecond_timer();
|
||||||
dlmstp_millisecond_timer();
|
Interrupt_Timer4();
|
||||||
Interrupt_Timer4();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check for compare int */
|
/* check for compare int */
|
||||||
if ((PIR2bits.CCP2IF) && (PIE2bits.CCP2IE))
|
if ((PIR2bits.CCP2IF) && (PIE2bits.CCP2IE)) {
|
||||||
{
|
PIR2bits.CCP2IF = 0;
|
||||||
PIR2bits.CCP2IF = 0;
|
Interrupt_CCP2();
|
||||||
Interrupt_CCP2();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check for USART Tx int */
|
/* check for USART Tx int */
|
||||||
if ((PIR3bits.TX2IF) && (PIE3bits.TX2IE))
|
if ((PIR3bits.TX2IF) && (PIE3bits.TX2IE)) {
|
||||||
{
|
RS485_Interrupt_Tx();
|
||||||
RS485_Interrupt_Tx();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check for USART Rx int */
|
/* check for USART Rx int */
|
||||||
if ((PIR3bits.RC2IF) && (PIE3bits.RC2IE))
|
if ((PIR3bits.RC2IF) && (PIE3bits.RC2IE)) {
|
||||||
{
|
RS485_Interrupt_Rx();
|
||||||
RS485_Interrupt_Rx();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Unused Interrupts
|
/* Unused Interrupts
|
||||||
//check for timer1 int
|
//check for timer1 int
|
||||||
@@ -198,13 +181,12 @@ void Interrupt_Timer3(void)
|
|||||||
/* Timer4 is set to go off every 1ms. This is our system tick */
|
/* Timer4 is set to go off every 1ms. This is our system tick */
|
||||||
void Interrupt_Timer4(void)
|
void Interrupt_Timer4(void)
|
||||||
{
|
{
|
||||||
/* Milisecond is our system tick */
|
/* Milisecond is our system tick */
|
||||||
if (Milliseconds < 0xFF)
|
if (Milliseconds < 0xFF)
|
||||||
++Milliseconds;
|
++Milliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interrupt_CCP2(void)
|
void Interrupt_CCP2(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,9 @@
|
|||||||
#include "iam.h"
|
#include "iam.h"
|
||||||
#include "txbuf.h"
|
#include "txbuf.h"
|
||||||
|
|
||||||
volatile uint8_t Milliseconds = 0;
|
volatile uint8_t Milliseconds = 0;
|
||||||
volatile uint8_t System_Seconds = 0;
|
volatile uint8_t System_Seconds = 0;
|
||||||
volatile uint8_t Zero_Cross_Timeout = 0;
|
volatile uint8_t Zero_Cross_Timeout = 0;
|
||||||
|
|
||||||
static void BACnet_Service_Handlers_Init(void)
|
static void BACnet_Service_Handlers_Init(void)
|
||||||
{
|
{
|
||||||
@@ -52,15 +52,15 @@ static void BACnet_Service_Handlers_Init(void)
|
|||||||
/* We must implement read property - it's required! */
|
/* We must implement read property - it's required! */
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
|
||||||
handler_read_property);
|
handler_read_property);
|
||||||
//apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
|
/*apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
*/
|
||||||
// handler_write_property);
|
/* handler_write_property);
*/
|
||||||
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
|
||||||
handler_reinitialize_device);
|
handler_reinitialize_device);
|
||||||
//apdu_set_unconfirmed_handler
|
/*apdu_set_unconfirmed_handler
*/
|
||||||
// (SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
|
/* (SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
*/
|
||||||
// handler_timesync_utc);
|
/* handler_timesync_utc);
*/
|
||||||
//apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
|
/*apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
*/
|
||||||
// handler_timesync);
|
/* handler_timesync);
*/
|
||||||
/* handle communication so we can shutup when asked */
|
/* handle communication so we can shutup when asked */
|
||||||
apdu_set_confirmed_handler
|
apdu_set_confirmed_handler
|
||||||
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
|
||||||
@@ -69,101 +69,93 @@ static void BACnet_Service_Handlers_Init(void)
|
|||||||
|
|
||||||
void Reinitialize(void)
|
void Reinitialize(void)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
char name = 0;
|
char name = 0;
|
||||||
|
|
||||||
_asm reset _endasm
|
_asm reset _endasm} void Global_Int(enum INT_STATE state)
|
||||||
}
|
{ /* FIX ME: add comment */
|
||||||
|
static uint8_t intstate = 0;
|
||||||
|
|
||||||
void Global_Int(
|
switch (state) {
|
||||||
enum INT_STATE state) /* FIX ME: add comment */
|
|
||||||
{
|
|
||||||
static uint8_t intstate = 0;
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case INT_DISABLED:
|
case INT_DISABLED:
|
||||||
intstate >>= 2;
|
intstate >>= 2;
|
||||||
intstate |= (INTCON & 0xC0);
|
intstate |= (INTCON & 0xC0);
|
||||||
break;
|
break;
|
||||||
case INT_ENABLED:
|
case INT_ENABLED:
|
||||||
INTCONbits.GIE = 1;
|
INTCONbits.GIE = 1;
|
||||||
INTCONbits.PEIE = 1;
|
INTCONbits.PEIE = 1;
|
||||||
intstate <<= 2;
|
intstate <<= 2;
|
||||||
break;
|
break;
|
||||||
case INT_RESTORE:
|
case INT_RESTORE:
|
||||||
INTCON |= (intstate & 0xC0);
|
INTCON |= (intstate & 0xC0);
|
||||||
intstate <<= 2;
|
intstate <<= 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize_Variables(void)
|
void Initialize_Variables(void)
|
||||||
{
|
{
|
||||||
/* Check to see if we need to initialize our eeproms */
|
/* Check to see if we need to initialize our eeproms */
|
||||||
ENABLE_TIMER4_INT();
|
ENABLE_TIMER4_INT();
|
||||||
/* interrupts must be enabled before we read our inputs */
|
/* interrupts must be enabled before we read our inputs */
|
||||||
Global_Int(INT_ENABLED);
|
Global_Int(INT_ENABLED);
|
||||||
BACnet_Service_Handlers_Init();
|
BACnet_Service_Handlers_Init();
|
||||||
dlmstp_init();
|
dlmstp_init();
|
||||||
/* Start our time from now */
|
/* Start our time from now */
|
||||||
Milliseconds = 0;
|
Milliseconds = 0;
|
||||||
System_Seconds = 0;
|
System_Seconds = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Verify_Ints(void)
|
void Verify_Ints(void)
|
||||||
{
|
{
|
||||||
/* Make sure the Abus data and clock lines are inputs. Also make sure
|
/* Make sure the Abus data and clock lines are inputs. Also make sure
|
||||||
* that global interrupts are enabled. */
|
* that global interrupts are enabled. */
|
||||||
if (!TRISCbits.TRISC3)
|
if (!TRISCbits.TRISC3)
|
||||||
TRISCbits.TRISC3 = 1;
|
TRISCbits.TRISC3 = 1;
|
||||||
if (!TRISCbits.TRISC4)
|
if (!TRISCbits.TRISC4)
|
||||||
TRISCbits.TRISC4 = 1;
|
TRISCbits.TRISC4 = 1;
|
||||||
if (!INTCONbits.GIE)
|
if (!INTCONbits.GIE)
|
||||||
INTCONbits.GIE = 1;
|
INTCONbits.GIE = 1;
|
||||||
if (!INTCONbits.PEIE)
|
if (!INTCONbits.PEIE)
|
||||||
INTCONbits.PEIE = 1;
|
INTCONbits.PEIE = 1;
|
||||||
/* if (!INTCONbits.INT0E) £
|
/* if (!INTCONbits.INT0E) £
|
||||||
* INTCONbits.INT0E=1; */
|
* INTCONbits.INT0E=1; */
|
||||||
if (!PIE1bits.TMR2IE)
|
if (!PIE1bits.TMR2IE)
|
||||||
PIE1bits.TMR2IE = 1;
|
PIE1bits.TMR2IE = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainTasks(void)
|
void MainTasks(void)
|
||||||
{
|
{
|
||||||
/* Handle our millisecond counters */
|
/* Handle our millisecond counters */
|
||||||
while (Milliseconds)
|
while (Milliseconds) {
|
||||||
{
|
--Milliseconds;
|
||||||
--Milliseconds;
|
}
|
||||||
}
|
/* Handle our seconds counters */
|
||||||
/* Handle our seconds counters */
|
while (System_Seconds) {
|
||||||
while (System_Seconds)
|
dcc_timer_seconds(1);
|
||||||
{
|
System_Seconds--;
|
||||||
dcc_timer_seconds(1);
|
}
|
||||||
System_Seconds--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
/* Note that before main is called, the SCL line is £
|
/* Note that before main is called, the SCL line is £
|
||||||
* toggled 256 times to clear any I2C devices that £
|
* toggled 256 times to clear any I2C devices that £
|
||||||
* may be holding the data line low £
|
* may be holding the data line low £
|
||||||
* Reset POR bit */
|
* Reset POR bit */
|
||||||
RCONbits.NOT_POR = 1;
|
RCONbits.NOT_POR = 1;
|
||||||
RCONbits.NOT_RI = 1;
|
RCONbits.NOT_RI = 1;
|
||||||
Initialize_Variables();
|
Initialize_Variables();
|
||||||
/* Handle anything that needs to be done on powerup */
|
/* Handle anything that needs to be done on powerup */
|
||||||
/* Greet the BACnet world! */
|
/* Greet the BACnet world! */
|
||||||
iam_send(&Handler_Transmit_Buffer[0]);
|
iam_send(&Handler_Transmit_Buffer[0]);
|
||||||
/* Main loop */
|
/* Main loop */
|
||||||
while (TRUE)
|
while (TRUE) {
|
||||||
{
|
RESTART_WDT();
|
||||||
RESTART_WDT();
|
Verify_Ints();
|
||||||
Verify_Ints();
|
dlmstp_task();
|
||||||
dlmstp_task();
|
MainTasks();
|
||||||
MainTasks();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,13 +56,13 @@
|
|||||||
|
|
||||||
/* debug print statements */
|
/* debug print statements */
|
||||||
#if PRINT_ENABLED
|
#if PRINT_ENABLED
|
||||||
#define PRINT_ENABLED_RECEIVE 0
|
#define PRINT_ENABLED_RECEIVE 0
|
||||||
#define PRINT_ENABLED_RECEIVE_DATA 1
|
#define PRINT_ENABLED_RECEIVE_DATA 1
|
||||||
#define PRINT_ENABLED_MASTER 0
|
#define PRINT_ENABLED_MASTER 0
|
||||||
#else
|
#else
|
||||||
#define PRINT_ENABLED_RECEIVE 0
|
#define PRINT_ENABLED_RECEIVE 0
|
||||||
#define PRINT_ENABLED_RECEIVE_DATA 0
|
#define PRINT_ENABLED_RECEIVE_DATA 0
|
||||||
#define PRINT_ENABLED_MASTER 0
|
#define PRINT_ENABLED_MASTER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MS/TP Frame Format */
|
/* MS/TP Frame Format */
|
||||||
@@ -450,7 +450,8 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* wait for the start of the next frame. */
|
/* wait for the start of the next frame. */
|
||||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
||||||
} else {
|
} else {
|
||||||
if ((mstp_port->DestinationAddress == mstp_port->This_Station)
|
if ((mstp_port->DestinationAddress ==
|
||||||
|
mstp_port->This_Station)
|
||||||
|| (mstp_port->DestinationAddress ==
|
|| (mstp_port->DestinationAddress ==
|
||||||
MSTP_BROADCAST_ADDRESS)) {
|
MSTP_BROADCAST_ADDRESS)) {
|
||||||
/* FrameTooLong */
|
/* FrameTooLong */
|
||||||
@@ -459,21 +460,24 @@ void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
/* unacceptable data length has been received */
|
/* unacceptable data length has been received */
|
||||||
mstp_port->ReceivedInvalidFrame = true;
|
mstp_port->ReceivedInvalidFrame = true;
|
||||||
/* wait for the start of the next frame. */
|
/* wait for the start of the next frame. */
|
||||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
mstp_port->receive_state =
|
||||||
|
MSTP_RECEIVE_STATE_IDLE;
|
||||||
}
|
}
|
||||||
/* NoData */
|
/* NoData */
|
||||||
else if (mstp_port->DataLength == 0) {
|
else if (mstp_port->DataLength == 0) {
|
||||||
/* indicate that a frame with no data has been received */
|
/* indicate that a frame with no data has been received */
|
||||||
mstp_port->ReceivedValidFrame = true;
|
mstp_port->ReceivedValidFrame = true;
|
||||||
/* wait for the start of the next frame. */
|
/* wait for the start of the next frame. */
|
||||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
|
mstp_port->receive_state =
|
||||||
|
MSTP_RECEIVE_STATE_IDLE;
|
||||||
}
|
}
|
||||||
/* Data */
|
/* Data */
|
||||||
else {
|
else {
|
||||||
mstp_port->Index = 0;
|
mstp_port->Index = 0;
|
||||||
mstp_port->DataCRC = 0xFFFF;
|
mstp_port->DataCRC = 0xFFFF;
|
||||||
/* receive the data portion of the frame. */
|
/* receive the data portion of the frame. */
|
||||||
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
|
mstp_port->receive_state =
|
||||||
|
MSTP_RECEIVE_STATE_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* NotForUs */
|
/* NotForUs */
|
||||||
@@ -655,7 +659,7 @@ char *mstp_frame_type_text(int type)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* returns true if we need to transition immediately */
|
/* returns true if we need to transition immediately */
|
||||||
bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t * mstp_port)
|
||||||
{
|
{
|
||||||
int mtu_len = 0;
|
int mtu_len = 0;
|
||||||
int frame_type = 0;
|
int frame_type = 0;
|
||||||
@@ -766,7 +770,7 @@ bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
mstp_port->DataLength);
|
mstp_port->DataLength);
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||||
//mstp_port->ReplyPostponedTimer = 0;
|
/*mstp_port->ReplyPostponedTimer = 0;
*/
|
||||||
/* indicate successful reception to the higher layers */
|
/* indicate successful reception to the higher layers */
|
||||||
dlmstp_put_receive(mstp_port->SourceAddress,
|
dlmstp_put_receive(mstp_port->SourceAddress,
|
||||||
(uint8_t *) & mstp_port->InputBuffer[0],
|
(uint8_t *) & mstp_port->InputBuffer[0],
|
||||||
@@ -1213,15 +1217,15 @@ void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
mstp_port->ReceivedValidFrame = false;
|
mstp_port->ReceivedValidFrame = false;
|
||||||
mstp_port->RetryCount = 0;
|
mstp_port->RetryCount = 0;
|
||||||
mstp_port->SilenceTimer = 0;
|
mstp_port->SilenceTimer = 0;
|
||||||
// mstp_port->ReplyPostponedTimer = 0;
|
/* mstp_port->ReplyPostponedTimer = 0;
*/
|
||||||
mstp_port->SoleMaster = false;
|
mstp_port->SoleMaster = false;
|
||||||
mstp_port->SourceAddress = 0;
|
mstp_port->SourceAddress = 0;
|
||||||
mstp_port->TokenCount = 0;
|
mstp_port->TokenCount = 0;
|
||||||
#if 0
|
#if 0
|
||||||
// these are adjustable, so should already be set
|
/* these are adjustable, so should already be set
*/
|
||||||
mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES;
|
mstp_port->Nmax_info_frames = DEFAULT_MAX_INFO_FRAMES;
|
||||||
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
|
mstp_port->Nmax_master = DEFAULT_MAX_MASTER;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* An array of octets, used to store PDU octets prior to being transmitted. */
|
/* An array of octets, used to store PDU octets prior to being transmitted. */
|
||||||
/* This array is only used for APDU messages */
|
/* This array is only used for APDU messages */
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ struct mstp_port_struct_t {
|
|||||||
/* Machine when a Data Expecting Reply Answer activity is completed. */
|
/* Machine when a Data Expecting Reply Answer activity is completed. */
|
||||||
/* note: we always send a reply postponed since a message other than
|
/* note: we always send a reply postponed since a message other than
|
||||||
the reply may be in the transmit queue */
|
the reply may be in the transmit queue */
|
||||||
// uint16_t ReplyPostponedTimer;
|
/* uint16_t ReplyPostponedTimer;
*/
|
||||||
|
|
||||||
/* Used to store the Source Address of a received frame. */
|
/* Used to store the Source Address of a received frame. */
|
||||||
uint8_t SourceAddress;
|
uint8_t SourceAddress;
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ extern volatile struct mstp_port_struct_t MSTP_Port;
|
|||||||
uint32_t RS485_Baud_Rate = 9600;
|
uint32_t RS485_Baud_Rate = 9600;
|
||||||
|
|
||||||
/* the ISR and other use this for status and control */
|
/* the ISR and other use this for status and control */
|
||||||
COMSTAT RS485_Comstat;
|
COMSTAT RS485_Comstat;
|
||||||
|
|
||||||
//#pragma udata MSTPPortData
|
/*#pragma udata MSTPPortData
*/
|
||||||
/* the buffer for receiving characters */
|
/* the buffer for receiving characters */
|
||||||
volatile uint8_t RS485_Rx_Buffer[MAX_MPDU];
|
volatile uint8_t RS485_Rx_Buffer[MAX_MPDU];
|
||||||
|
|
||||||
@@ -58,53 +58,55 @@ volatile uint8_t RS485_Tx_Buffer[MAX_MPDU];
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
|
void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
|
||||||
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||||
uint16_t nbytes) /* number of bytes of data (up to 501) */
|
uint16_t nbytes)
|
||||||
{
|
{ /* number of bytes of data (up to 501) */
|
||||||
uint16_t i = 0; /* loop counter */
|
uint16_t i = 0; /* loop counter */
|
||||||
uint8_t turnaround_time;
|
uint8_t turnaround_time;
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* bounds check */
|
||||||
|
if (nbytes >= sizeof(RS485_Tx_Buffer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* buffer is full. Wait for ISR to transmit. */
|
||||||
|
while (RS485_Comstat.Tx_Bytes) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* wait 40 bit times since reception */
|
||||||
|
if (RS485_Baud_Rate == 9600)
|
||||||
|
turnaround_time = 4;
|
||||||
|
else if (RS485_Baud_Rate == 19200)
|
||||||
|
turnaround_time = 2;
|
||||||
|
else
|
||||||
|
turnaround_time = 1;
|
||||||
|
|
||||||
|
while (mstp_port->SilenceTimer < turnaround_time) {
|
||||||
|
};
|
||||||
|
|
||||||
|
RS485_Comstat.TxHead = 0;
|
||||||
|
memcpy((void *) &RS485_Tx_Buffer[0], (void *) buffer, nbytes);
|
||||||
|
|
||||||
|
/*for (i = 0; i < nbytes; i++) {
*/
|
||||||
|
/* /* put the data into the buffer */
*/
|
||||||
|
/* RS485_Tx_Buffer[i] = *buffer;
*/
|
||||||
|
/* buffer++;
*/
|
||||||
|
/*}
*/
|
||||||
|
RS485_Comstat.Tx_Bytes = nbytes;
|
||||||
|
/* disable the receiver */
|
||||||
|
PIE3bits.RC2IE = 0;
|
||||||
|
RCSTA2bits.CREN = 0;
|
||||||
|
/* enable the transceiver */
|
||||||
|
RS485_TX_ENABLE = 1;
|
||||||
|
RS485_RX_DISABLE = 1;
|
||||||
|
/* enable the transmitter */
|
||||||
|
TXSTA2bits.TXEN = 1;
|
||||||
|
PIE3bits.TX2IE = 1;
|
||||||
|
/* per MSTP spec, sort of */
|
||||||
|
mstp_port->SilenceTimer = 0;
|
||||||
|
|
||||||
if (!buffer)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* bounds check */
|
|
||||||
if (nbytes >= sizeof(RS485_Tx_Buffer))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* buffer is full. Wait for ISR to transmit. */
|
|
||||||
while (RS485_Comstat.Tx_Bytes) {};
|
|
||||||
|
|
||||||
/* wait 40 bit times since reception */
|
|
||||||
if (RS485_Baud_Rate == 9600)
|
|
||||||
turnaround_time = 4;
|
|
||||||
else if (RS485_Baud_Rate == 19200)
|
|
||||||
turnaround_time = 2;
|
|
||||||
else
|
|
||||||
turnaround_time = 1;
|
|
||||||
|
|
||||||
while (mstp_port->SilenceTimer < turnaround_time) {};
|
|
||||||
|
|
||||||
RS485_Comstat.TxHead = 0;
|
|
||||||
memcpy((void *)&RS485_Tx_Buffer[0], (void *)buffer, nbytes);
|
|
||||||
|
|
||||||
//for (i = 0; i < nbytes; i++) {
|
|
||||||
// /* put the data into the buffer */
|
|
||||||
// RS485_Tx_Buffer[i] = *buffer;
|
|
||||||
// buffer++;
|
|
||||||
//}
|
|
||||||
RS485_Comstat.Tx_Bytes = nbytes;
|
|
||||||
/* disable the receiver */
|
|
||||||
PIE3bits.RC2IE = 0;
|
|
||||||
RCSTA2bits.CREN = 0;
|
|
||||||
/* enable the transceiver */
|
|
||||||
RS485_TX_ENABLE = 1;
|
|
||||||
RS485_RX_DISABLE = 1;
|
|
||||||
/* enable the transmitter */
|
|
||||||
TXSTA2bits.TXEN = 1;
|
|
||||||
PIE3bits.TX2IE = 1;
|
|
||||||
/* per MSTP spec, sort of */
|
|
||||||
mstp_port->SilenceTimer = 0;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -113,30 +115,30 @@ void RS485_Send_Frame(volatile struct mstp_port_struct_t *mstp_port, /* port
|
|||||||
* ALGORITHM: none
|
* ALGORITHM: none
|
||||||
* NOTES: none
|
* NOTES: none
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
|
uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *
|
||||||
|
mstp_port)
|
||||||
{
|
{
|
||||||
/* check for data */
|
/* check for data */
|
||||||
if (RS485_Comstat.Rx_Bytes)
|
if (RS485_Comstat.Rx_Bytes) {
|
||||||
{
|
mstp_port->DataRegister = RS485_Rx_Buffer[RS485_Comstat.RxTail];
|
||||||
mstp_port->DataRegister = RS485_Rx_Buffer[RS485_Comstat.RxTail];
|
if (RS485_Comstat.RxTail >= (sizeof(RS485_Rx_Buffer) - 1))
|
||||||
if (RS485_Comstat.RxTail >= (sizeof(RS485_Rx_Buffer)-1))
|
RS485_Comstat.RxTail = 0;
|
||||||
RS485_Comstat.RxTail = 0;
|
else
|
||||||
else
|
RS485_Comstat.RxTail++;
|
||||||
RS485_Comstat.RxTail++;
|
RS485_Comstat.Rx_Bytes--;
|
||||||
RS485_Comstat.Rx_Bytes--;
|
/* errors? let the state machine know */
|
||||||
/* errors? let the state machine know */
|
if (RS485_Comstat.Rx_Bufferoverrun) {
|
||||||
if (RS485_Comstat.Rx_Bufferoverrun)
|
RS485_Comstat.Rx_Bufferoverrun = FALSE;
|
||||||
{
|
mstp_port->ReceiveError = TRUE;
|
||||||
RS485_Comstat.Rx_Bufferoverrun = FALSE;
|
}
|
||||||
mstp_port->ReceiveError = TRUE;
|
/* We read a good byte */
|
||||||
}
|
else
|
||||||
/* We read a good byte */
|
mstp_port->DataAvailable = TRUE;
|
||||||
else
|
|
||||||
mstp_port->DataAvailable = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return RS485_Comstat.Rx_Bytes;
|
return RS485_Comstat.Rx_Bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *************************************************************************
|
/* *************************************************************************
|
||||||
DESCRIPTION: Receives RS485 data stream
|
DESCRIPTION: Receives RS485 data stream
|
||||||
|
|
||||||
@@ -148,31 +150,26 @@ uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
|
|||||||
*************************************************************************** */
|
*************************************************************************** */
|
||||||
void RS485_Interrupt_Rx(void)
|
void RS485_Interrupt_Rx(void)
|
||||||
{
|
{
|
||||||
char dummy;
|
char dummy;
|
||||||
|
|
||||||
if ((RCSTA2bits.FERR) || (RCSTA2bits.OERR))
|
if ((RCSTA2bits.FERR) || (RCSTA2bits.OERR)) {
|
||||||
{
|
/* Clear the error */
|
||||||
/* Clear the error */
|
RCSTA2bits.CREN = 0;
|
||||||
RCSTA2bits.CREN = 0;
|
RCSTA2bits.CREN = 1;
|
||||||
RCSTA2bits.CREN = 1;
|
RS485_Comstat.Rx_Bufferoverrun = TRUE;
|
||||||
RS485_Comstat.Rx_Bufferoverrun = TRUE;
|
dummy = RCREG2;
|
||||||
dummy = RCREG2;
|
} else if (RS485_Comstat.Rx_Bytes < sizeof(RS485_Rx_Buffer)) {
|
||||||
}
|
RS485_Rx_Buffer[RS485_Comstat.RxHead] = RCREG2;
|
||||||
else if (RS485_Comstat.Rx_Bytes < sizeof(RS485_Rx_Buffer))
|
if (RS485_Comstat.RxHead >= (sizeof(RS485_Rx_Buffer) - 1))
|
||||||
{
|
RS485_Comstat.RxHead = 0;
|
||||||
RS485_Rx_Buffer[RS485_Comstat.RxHead] = RCREG2;
|
else
|
||||||
if (RS485_Comstat.RxHead >= (sizeof(RS485_Rx_Buffer)-1))
|
RS485_Comstat.RxHead++;
|
||||||
RS485_Comstat.RxHead = 0;
|
RS485_Comstat.Rx_Bytes++;
|
||||||
else
|
} else {
|
||||||
RS485_Comstat.RxHead++;
|
RS485_Comstat.Rx_Bufferoverrun = TRUE;
|
||||||
RS485_Comstat.Rx_Bytes++;
|
dummy = RCREG2;
|
||||||
}
|
(void) dummy;
|
||||||
else
|
}
|
||||||
{
|
|
||||||
RS485_Comstat.Rx_Bufferoverrun = TRUE;
|
|
||||||
dummy = RCREG2;
|
|
||||||
(void)dummy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *************************************************************************
|
/* *************************************************************************
|
||||||
@@ -186,28 +183,25 @@ void RS485_Interrupt_Rx(void)
|
|||||||
*************************************************************************** */
|
*************************************************************************** */
|
||||||
void RS485_Interrupt_Tx(void)
|
void RS485_Interrupt_Tx(void)
|
||||||
{
|
{
|
||||||
if (RS485_Comstat.Tx_Bytes)
|
if (RS485_Comstat.Tx_Bytes) {
|
||||||
{
|
/* Get the data byte */
|
||||||
/* Get the data byte */
|
TXREG2 = RS485_Tx_Buffer[RS485_Comstat.TxHead];
|
||||||
TXREG2 = RS485_Tx_Buffer[RS485_Comstat.TxHead];
|
/* point to the next byte */
|
||||||
/* point to the next byte */
|
RS485_Comstat.TxHead++;
|
||||||
RS485_Comstat.TxHead++;
|
/* reduce the buffer size */
|
||||||
/* reduce the buffer size */
|
RS485_Comstat.Tx_Bytes--;
|
||||||
RS485_Comstat.Tx_Bytes--;
|
} else {
|
||||||
}
|
/* wait for the USART to be empty */
|
||||||
else
|
while (!TXSTA2bits.TRMT);
|
||||||
{
|
/* disable this interrupt */
|
||||||
/* wait for the USART to be empty */
|
PIE3bits.TX2IE = 0;
|
||||||
while (!TXSTA2bits.TRMT);
|
/* enable the receiver */
|
||||||
/* disable this interrupt */
|
RS485_TX_ENABLE = 0;
|
||||||
PIE3bits.TX2IE = 0;
|
RS485_RX_DISABLE = 0;
|
||||||
/* enable the receiver */
|
/* FIXME: might not be necessary
*/
|
||||||
RS485_TX_ENABLE = 0;
|
PIE3bits.RC2IE = 1;
|
||||||
RS485_RX_DISABLE = 0;
|
RCSTA2bits.CREN = 1;
|
||||||
// FIXME: might not be necessary
|
}
|
||||||
PIE3bits.RC2IE = 1;
|
|
||||||
RCSTA2bits.CREN = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -231,29 +225,28 @@ bool RS485_Set_Baud_Rate(uint32_t baud)
|
|||||||
{
|
{
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
|
|
||||||
switch (baud)
|
switch (baud) {
|
||||||
{
|
case 9600:
|
||||||
case 9600:
|
case 19200:
|
||||||
case 19200:
|
case 38400:
|
||||||
case 38400:
|
case 57600:
|
||||||
case 57600:
|
case 76800:
|
||||||
case 76800:
|
case 115200:
|
||||||
case 115200:
|
|
||||||
RS485_Baud_Rate = baud;
|
RS485_Baud_Rate = baud;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
/* FIXME: store the baud rate */
|
/* FIXME: store the baud rate */
|
||||||
/* I2C_Write_Block(
|
/* I2C_Write_Block(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
(char *)&RS485_Baud_Rate,
|
(char *)&RS485_Baud_Rate,
|
||||||
sizeof(RS485_Baud_Rate),
|
sizeof(RS485_Baud_Rate),
|
||||||
EEPROM_MSTP_BAUD_RATE_ADDR); */
|
EEPROM_MSTP_BAUD_RATE_ADDR); */
|
||||||
}
|
}
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
@@ -268,75 +261,74 @@ bool RS485_Set_Baud_Rate(uint32_t baud)
|
|||||||
void RS485_Initialize_Port(void)
|
void RS485_Initialize_Port(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Reset USART registers to POR state */
|
/* Reset USART registers to POR state */
|
||||||
TXSTA2 = 0;
|
TXSTA2 = 0;
|
||||||
RCSTA2 = 0;
|
RCSTA2 = 0;
|
||||||
/* configure USART for receiving */
|
/* configure USART for receiving */
|
||||||
/* since the TX will handle setting up for transmit */
|
/* since the TX will handle setting up for transmit */
|
||||||
RCSTA2bits.CREN = 1;
|
RCSTA2bits.CREN = 1;
|
||||||
/* Interrupt on receipt */
|
/* Interrupt on receipt */
|
||||||
PIE3bits.RC2IE = 1;
|
PIE3bits.RC2IE = 1;
|
||||||
/* enable the transmitter, disable its interrupt */
|
/* enable the transmitter, disable its interrupt */
|
||||||
TXSTA2bits.TXEN = 1;
|
TXSTA2bits.TXEN = 1;
|
||||||
PIE3bits.TX2IE = 0;
|
PIE3bits.TX2IE = 0;
|
||||||
/* setup USART Baud Rate Generator */
|
/* setup USART Baud Rate Generator */
|
||||||
/* see BAUD RATES FOR ASYNCHRONOUS MODE in Data Book */
|
/* see BAUD RATES FOR ASYNCHRONOUS MODE in Data Book */
|
||||||
/* Fosc=20MHz
|
/* Fosc=20MHz
|
||||||
BRGH=1 BRGH=0
|
BRGH=1 BRGH=0
|
||||||
Rate SPBRG Rate SPBRG
|
Rate SPBRG Rate SPBRG
|
||||||
------- ----- ------- -----
|
------- ----- ------- -----
|
||||||
9615 129 9469 32
|
9615 129 9469 32
|
||||||
19230 64 19530 15
|
19230 64 19530 15
|
||||||
37878 32 78130 3
|
37878 32 78130 3
|
||||||
56818 21 104200 2
|
56818 21 104200 2
|
||||||
113630 10 312500 0
|
113630 10 312500 0
|
||||||
250000 4
|
250000 4
|
||||||
625000 1
|
625000 1
|
||||||
1250000 0
|
1250000 0
|
||||||
*/
|
*/
|
||||||
switch (RS485_Baud_Rate)
|
switch (RS485_Baud_Rate) {
|
||||||
{
|
case 19200:
|
||||||
case 19200:
|
SPBRG2 = 64;
|
||||||
SPBRG2 = 64;
|
TXSTA2bits.BRGH = 1;
|
||||||
TXSTA2bits.BRGH = 1;
|
break;
|
||||||
break;
|
case 38400:
|
||||||
case 38400:
|
SPBRG2 = 32;
|
||||||
SPBRG2 = 32;
|
TXSTA2bits.BRGH = 1;
|
||||||
TXSTA2bits.BRGH = 1;
|
break;
|
||||||
break;
|
case 57600:
|
||||||
case 57600:
|
SPBRG2 = 21;
|
||||||
SPBRG2 = 21;
|
TXSTA2bits.BRGH = 1;
|
||||||
TXSTA2bits.BRGH = 1;
|
break;
|
||||||
break;
|
case 76800:
|
||||||
case 76800:
|
SPBRG2 = 3;
|
||||||
SPBRG2 = 3;
|
TXSTA2bits.BRGH = 0;
|
||||||
TXSTA2bits.BRGH = 0;
|
break;
|
||||||
break;
|
case 115200:
|
||||||
case 115200:
|
SPBRG2 = 10;
|
||||||
SPBRG2 = 10;
|
TXSTA2bits.BRGH = 1;
|
||||||
TXSTA2bits.BRGH = 1;
|
break;
|
||||||
break;
|
case 9600:
|
||||||
case 9600:
|
SPBRG2 = 129;
|
||||||
SPBRG2 = 129;
|
TXSTA2bits.BRGH = 1;
|
||||||
TXSTA2bits.BRGH = 1;
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
SPBRG2 = 129;
|
||||||
SPBRG2 = 129;
|
TXSTA2bits.BRGH = 1;
|
||||||
TXSTA2bits.BRGH = 1;
|
RS485_Set_Baud_Rate(9600);
|
||||||
RS485_Set_Baud_Rate(9600);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
/* select async mode */
|
||||||
/* select async mode */
|
TXSTA2bits.SYNC = 0;
|
||||||
TXSTA2bits.SYNC = 0;
|
/* enable transmitter */
|
||||||
/* enable transmitter */
|
TXSTA2bits.TXEN = 1;
|
||||||
TXSTA2bits.TXEN = 1;
|
/* serial port enable */
|
||||||
/* serial port enable */
|
RCSTA2bits.SPEN = 1;
|
||||||
RCSTA2bits.SPEN = 1;
|
/* since we are using RS485,
|
||||||
/* since we are using RS485,
|
we need to explicitly say
|
||||||
we need to explicitly say
|
transmit enable or not */
|
||||||
transmit enable or not */
|
RS485_RX_DISABLE = 0;
|
||||||
RS485_RX_DISABLE = 0;
|
RS485_TX_ENABLE = 0;
|
||||||
RS485_TX_ENABLE = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -347,9 +339,9 @@ void RS485_Initialize_Port(void)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void RS485_Disable_Port(void)
|
void RS485_Disable_Port(void)
|
||||||
{
|
{
|
||||||
RCSTA2 &= 0x4F; /* Disable the receiver */
|
RCSTA2 &= 0x4F; /* Disable the receiver */
|
||||||
TXSTA2bits.TXEN = 0; /* and transmitter */
|
TXSTA2bits.TXEN = 0; /* and transmitter */
|
||||||
PIE3 &= 0xCF; /* Disable both interrupts */
|
PIE3 &= 0xCF; /* Disable both interrupts */
|
||||||
}
|
}
|
||||||
|
|
||||||
void RS485_Reinit(void)
|
void RS485_Reinit(void)
|
||||||
@@ -365,21 +357,21 @@ void RS485_Reinit(void)
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
void RS485_Initialize(void)
|
void RS485_Initialize(void)
|
||||||
{
|
{
|
||||||
/* Init the Rs485 buffers */
|
/* Init the Rs485 buffers */
|
||||||
RS485_Comstat.RxHead = 0;
|
RS485_Comstat.RxHead = 0;
|
||||||
RS485_Comstat.RxTail = 0;
|
RS485_Comstat.RxTail = 0;
|
||||||
RS485_Comstat.Rx_Bytes = 0;
|
RS485_Comstat.Rx_Bytes = 0;
|
||||||
RS485_Comstat.Rx_Bufferoverrun = FALSE;
|
RS485_Comstat.Rx_Bufferoverrun = FALSE;
|
||||||
RS485_Comstat.TxHead = 0;
|
RS485_Comstat.TxHead = 0;
|
||||||
RS485_Comstat.TxTail = 0;
|
RS485_Comstat.TxTail = 0;
|
||||||
RS485_Comstat.Tx_Bytes = 0;
|
RS485_Comstat.Tx_Bytes = 0;
|
||||||
|
|
||||||
/* FIXME: read the data from storage */
|
/* FIXME: read the data from storage */
|
||||||
/* I2C_Read_Block(
|
/* I2C_Read_Block(
|
||||||
EEPROM_DEVICE_ADDRESS,
|
EEPROM_DEVICE_ADDRESS,
|
||||||
(char *)&RS485_Baud_Rate,
|
(char *)&RS485_Baud_Rate,
|
||||||
sizeof(RS485_Baud_Rate),
|
sizeof(RS485_Baud_Rate),
|
||||||
EEPROM_MSTP_BAUD_RATE_ADDR); */
|
EEPROM_MSTP_BAUD_RATE_ADDR); */
|
||||||
|
|
||||||
RS485_Initialize_Port();
|
RS485_Initialize_Port();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,16 +39,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "mstp.h"
|
#include "mstp.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
uint8_t RxHead;
|
||||||
uint8_t RxHead;
|
uint8_t RxTail;
|
||||||
uint8_t RxTail;
|
uint8_t Rx_Bytes;
|
||||||
uint8_t Rx_Bytes;
|
uint8_t TxHead;
|
||||||
uint8_t TxHead;
|
uint8_t TxTail;
|
||||||
uint8_t TxTail;
|
uint8_t Tx_Bytes;
|
||||||
uint8_t Tx_Bytes;
|
uint8_t Rx_Bufferoverrun:1;
|
||||||
uint8_t Rx_Bufferoverrun : 1;
|
uint8_t Tx_Bufferoverrun:1;
|
||||||
uint8_t Tx_Bufferoverrun : 1;
|
|
||||||
} COMSTAT;
|
} COMSTAT;
|
||||||
|
|
||||||
extern COMSTAT RS485_Comstat;
|
extern COMSTAT RS485_Comstat;
|
||||||
@@ -70,7 +69,7 @@ extern "C" {
|
|||||||
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
|
||||||
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
uint16_t nbytes); /* number of bytes of data (up to 501) */
|
||||||
|
|
||||||
uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port); /* port specific data */
|
uint8_t RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port); /* port specific data */
|
||||||
|
|
||||||
void RS485_Interrupt_Rx(void);
|
void RS485_Interrupt_Rx(void);
|
||||||
|
|
||||||
|
|||||||
+3
-6
@@ -298,11 +298,8 @@ bool tsm_invoke_id_failed(uint8_t invokeID)
|
|||||||
bool I_Am_Request = true;
|
bool I_Am_Request = true;
|
||||||
|
|
||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
int datalink_send_pdu(
|
int datalink_send_pdu(BACNET_ADDRESS * dest,
|
||||||
BACNET_ADDRESS * dest,
|
BACNET_NPDU_DATA * npdu_data, uint8_t * pdu, unsigned pdu_len)
|
||||||
BACNET_NPDU_DATA * npdu_data,
|
|
||||||
uint8_t * pdu,
|
|
||||||
unsigned pdu_len)
|
|
||||||
{
|
{
|
||||||
(void) dest;
|
(void) dest;
|
||||||
(void) npdu_data;
|
(void) npdu_data;
|
||||||
@@ -315,7 +312,7 @@ int datalink_send_pdu(
|
|||||||
/* dummy function stubs */
|
/* dummy function stubs */
|
||||||
void datalink_get_broadcast_address(BACNET_ADDRESS * dest)
|
void datalink_get_broadcast_address(BACNET_ADDRESS * dest)
|
||||||
{
|
{
|
||||||
(void)dest;
|
(void) dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testTSM(Test * pTest)
|
void testTSM(Test * pTest)
|
||||||
|
|||||||
+16
-24
@@ -68,7 +68,7 @@ int wp_encode_apdu(uint8_t * apdu,
|
|||||||
len = encode_opening_tag(&apdu[apdu_len], 3);
|
len = encode_opening_tag(&apdu[apdu_len], 3);
|
||||||
apdu_len += len;
|
apdu_len += len;
|
||||||
for (len = 0; len < data->application_data_len; len++) {
|
for (len = 0; len < data->application_data_len; len++) {
|
||||||
apdu[apdu_len+len] = data->application_data[len];
|
apdu[apdu_len + len] = data->application_data[len];
|
||||||
}
|
}
|
||||||
apdu_len += data->application_data_len;
|
apdu_len += data->application_data_len;
|
||||||
len = encode_closing_tag(&apdu[apdu_len], 3);
|
len = encode_closing_tag(&apdu[apdu_len], 3);
|
||||||
@@ -97,7 +97,7 @@ int wp_decode_service_request(uint8_t * apdu,
|
|||||||
int type = 0; /* for decoding */
|
int type = 0; /* for decoding */
|
||||||
int property = 0; /* for decoding */
|
int property = 0; /* for decoding */
|
||||||
uint32_t unsigned_value = 0;
|
uint32_t unsigned_value = 0;
|
||||||
int i = 0; /* loop counter */
|
int i = 0; /* loop counter */
|
||||||
|
|
||||||
/* check for value pointers */
|
/* check for value pointers */
|
||||||
if (apdu_len && data) {
|
if (apdu_len && data) {
|
||||||
@@ -129,12 +129,12 @@ int wp_decode_service_request(uint8_t * apdu,
|
|||||||
return -1;
|
return -1;
|
||||||
/* determine the length of the data blob */
|
/* determine the length of the data blob */
|
||||||
data->application_data_len = bacapp_data_len(&apdu[len],
|
data->application_data_len = bacapp_data_len(&apdu[len],
|
||||||
apdu_len-len, property);
|
apdu_len - len, property);
|
||||||
/* a tag number of 3 is not extended so only one octet */
|
/* a tag number of 3 is not extended so only one octet */
|
||||||
len++;
|
len++;
|
||||||
/* copy the data from the APDU */
|
/* copy the data from the APDU */
|
||||||
for (i = 0; i < data->application_data_len; i++) {
|
for (i = 0; i < data->application_data_len; i++) {
|
||||||
data->application_data[i] = apdu[len+i];
|
data->application_data[i] = apdu[len + i];
|
||||||
}
|
}
|
||||||
/* add on the data length */
|
/* add on the data length */
|
||||||
len += data->application_data_len;
|
len += data->application_data_len;
|
||||||
@@ -195,7 +195,8 @@ int wp_decode_apdu(uint8_t * apdu,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testWritePropertyTag(Test * pTest, BACNET_APPLICATION_DATA_VALUE * value)
|
void testWritePropertyTag(Test * pTest,
|
||||||
|
BACNET_APPLICATION_DATA_VALUE * value)
|
||||||
{
|
{
|
||||||
BACNET_WRITE_PROPERTY_DATA data = { 0 };
|
BACNET_WRITE_PROPERTY_DATA data = { 0 };
|
||||||
BACNET_WRITE_PROPERTY_DATA test_data = { 0 };
|
BACNET_WRITE_PROPERTY_DATA test_data = { 0 };
|
||||||
@@ -207,7 +208,7 @@ void testWritePropertyTag(Test * pTest, BACNET_APPLICATION_DATA_VALUE * value)
|
|||||||
uint8_t test_invoke_id = 0;
|
uint8_t test_invoke_id = 0;
|
||||||
|
|
||||||
data.application_data_len =
|
data.application_data_len =
|
||||||
bacapp_encode_application_data(&data.application_data[0],value);
|
bacapp_encode_application_data(&data.application_data[0], value);
|
||||||
len = wp_encode_apdu(&apdu[0], invoke_id, &data);
|
len = wp_encode_apdu(&apdu[0], invoke_id, &data);
|
||||||
ct_test(pTest, len != 0);
|
ct_test(pTest, len != 0);
|
||||||
/* decode the data */
|
/* decode the data */
|
||||||
@@ -219,17 +220,14 @@ void testWritePropertyTag(Test * pTest, BACNET_APPLICATION_DATA_VALUE * value)
|
|||||||
ct_test(pTest, test_data.object_property == data.object_property);
|
ct_test(pTest, test_data.object_property == data.object_property);
|
||||||
ct_test(pTest, test_data.array_index == data.array_index);
|
ct_test(pTest, test_data.array_index == data.array_index);
|
||||||
/* decode the application value of the request */
|
/* decode the application value of the request */
|
||||||
len = bacapp_decode_application_data(
|
len = bacapp_decode_application_data(test_data.application_data,
|
||||||
test_data.application_data,
|
test_data.application_data_len, &test_value);
|
||||||
test_data.application_data_len,
|
|
||||||
&test_value);
|
|
||||||
ct_test(pTest, test_value.tag == value->tag);
|
ct_test(pTest, test_value.tag == value->tag);
|
||||||
switch (test_value.tag) {
|
switch (test_value.tag) {
|
||||||
case BACNET_APPLICATION_TAG_NULL:
|
case BACNET_APPLICATION_TAG_NULL:
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_BOOLEAN:
|
case BACNET_APPLICATION_TAG_BOOLEAN:
|
||||||
ct_test(pTest, test_value.type.Boolean ==
|
ct_test(pTest, test_value.type.Boolean == value->type.Boolean);
|
||||||
value->type.Boolean);
|
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_UNSIGNED_INT:
|
case BACNET_APPLICATION_TAG_UNSIGNED_INT:
|
||||||
ct_test(pTest, test_value.type.Unsigned_Int ==
|
ct_test(pTest, test_value.type.Unsigned_Int ==
|
||||||
@@ -247,22 +245,16 @@ void testWritePropertyTag(Test * pTest, BACNET_APPLICATION_DATA_VALUE * value)
|
|||||||
value->type.Enumerated);
|
value->type.Enumerated);
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_DATE:
|
case BACNET_APPLICATION_TAG_DATE:
|
||||||
ct_test(pTest, test_value.type.Date.year ==
|
ct_test(pTest, test_value.type.Date.year == value->type.Date.year);
|
||||||
value->type.Date.year);
|
|
||||||
ct_test(pTest, test_value.type.Date.month ==
|
ct_test(pTest, test_value.type.Date.month ==
|
||||||
value->type.Date.month);
|
value->type.Date.month);
|
||||||
ct_test(pTest, test_value.type.Date.day ==
|
ct_test(pTest, test_value.type.Date.day == value->type.Date.day);
|
||||||
value->type.Date.day);
|
ct_test(pTest, test_value.type.Date.wday == value->type.Date.wday);
|
||||||
ct_test(pTest, test_value.type.Date.wday ==
|
|
||||||
value->type.Date.wday);
|
|
||||||
break;
|
break;
|
||||||
case BACNET_APPLICATION_TAG_TIME:
|
case BACNET_APPLICATION_TAG_TIME:
|
||||||
ct_test(pTest, test_value.type.Time.hour ==
|
ct_test(pTest, test_value.type.Time.hour == value->type.Time.hour);
|
||||||
value->type.Time.hour);
|
ct_test(pTest, test_value.type.Time.min == value->type.Time.min);
|
||||||
ct_test(pTest, test_value.type.Time.min ==
|
ct_test(pTest, test_value.type.Time.sec == value->type.Time.sec);
|
||||||
value->type.Time.min);
|
|
||||||
ct_test(pTest, test_value.type.Time.sec ==
|
|
||||||
value->type.Time.sec);
|
|
||||||
ct_test(pTest, test_value.type.Time.hundredths ==
|
ct_test(pTest, test_value.type.Time.hundredths ==
|
||||||
value->type.Time.hundredths);
|
value->type.Time.hundredths);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user