Feature/make pretty apps and ports (#80)

* Added pretty-apps and pretty-ports make targets

* pretty-fied apps folder C files

* Pretty-fied ports folder C and H files

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2020-04-30 10:13:11 -05:00
committed by GitHub
parent 0abcbea971
commit fdd49f1791
152 changed files with 9668 additions and 11674 deletions
+10
View File
@@ -137,6 +137,16 @@ pretty:
find ./apps -iname *.h -o -iname *.c -exec \ find ./apps -iname *.h -o -iname *.c -exec \
clang-format -i -style=file -fallback-style=none {} \; clang-format -i -style=file -fallback-style=none {} \;
.PHONY: pretty-apps
pretty-apps:
find ./apps -iname *.h -o -iname *.c -exec \
clang-format -i -style=file -fallback-style=none {} \;
.PHONY: pretty-ports
pretty-ports:
find ./ports -maxdepth 2 -type f -iname *.h -o -iname *.c -exec \
clang-format -i -style=file -fallback-style=none {} \;
.PHONY: tidy .PHONY: tidy
tidy: tidy:
find ./src -iname *.h -o -iname *.c -exec \ find ./src -iname *.h -o -iname *.c -exec \
+2 -2
View File
@@ -742,8 +742,8 @@ bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
* @param object_instance [in] The object instance number to be looked up. * @param object_instance [in] The object instance number to be looked up.
* @return True if found, else False if no such Object in this device. * @return True if found, else False if no such Object in this device.
*/ */
bool Device_Valid_Object_Id bool Device_Valid_Object_Id(
(BACNET_OBJECT_TYPE object_type, uint32_t object_instance) BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
+1 -2
View File
@@ -249,8 +249,7 @@ int main(int argc, char *argv[])
for (;;) { for (;;) {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
current_seconds = time(NULL); current_seconds = time(NULL);
if (current_seconds != last_seconds) { if (current_seconds != last_seconds) { }
}
/* returns 0 bytes on timeout */ /* returns 0 bytes on timeout */
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
+1 -2
View File
@@ -117,8 +117,7 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf( printf("Send a Read-Foreign-Device-Table message to a BBMD.\r\n"
"Send a Read-Foreign-Device-Table message to a BBMD.\r\n"
"\r\n" "\r\n"
"IP:\r\n" "IP:\r\n"
"IP address of the BBMD in dotted decimal notation\r\n" "IP address of the BBMD in dotted decimal notation\r\n"
+2 -2
View File
@@ -143,8 +143,8 @@ bool dl_ip_init(ROUTER_PORT *port, IP_DATA *ip_data)
ip_data->port = htons(port->params.bip_params.port); ip_data->port = htons(port->params.bip_params.port);
/* get local address */ /* get local address */
status = status = bip_get_local_address_ioctl(
bip_get_local_address_ioctl(port->iface, &ip_data->local_addr, SIOCGIFADDR); port->iface, &ip_data->local_addr, SIOCGIFADDR);
if (status < 0) { if (status < 0) {
return false; return false;
} }
+4 -3
View File
@@ -104,7 +104,8 @@ void apdu_handler(BACNET_ADDRESS * src,
/* PDU Type */ /* PDU Type */
switch (apdu[0] & 0xF0) { switch (apdu[0] & 0xF0) {
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ len = apdu_decode_confirmed_service_request(
&apdu[0], /* APDU data */
apdu_len, &service_data, &service_choice, &service_request, apdu_len, &service_data, &service_choice, &service_request,
&service_request_len); &service_request_len);
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
@@ -113,8 +114,8 @@ void apdu_handler(BACNET_ADDRESS * src,
} }
#ifdef WRITE_PROPERTY #ifdef WRITE_PROPERTY
else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) { else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
handler_write_property(service_request, handler_write_property(service_request, service_request_len,
service_request_len, src, &service_data); src, &service_data);
} }
#endif #endif
else { else {
+10 -15
View File
@@ -100,13 +100,12 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, &apdu[0], OBJECT_ANALOG_VALUE, object_instance);
object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Analog_Value_Name(object_instance)); &char_string, Analog_Value_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -116,9 +115,8 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], AV_Present_Value[object_index]);
AV_Present_Value[object_index]);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -170,9 +168,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 = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -218,14 +215,12 @@ void testAnalog_Value(Test * pTest)
BACNET_ERROR_CLASS error_class; BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
len = len = Analog_Value_Encode_Property_APDU(&apdu[0], instance,
Analog_Value_Encode_Property_APDU(&apdu[0], instance,
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = len = decode_object_id(&apdu[len], (int *)&decoded_type, &decoded_instance);
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE);
ct_test(pTest, decoded_instance == instance); ct_test(pTest, decoded_instance == instance);
-1
View File
@@ -71,7 +71,6 @@ long bip_getaddrbyname(const char *host_name)
*/ */
void bip_set_interface(char *ifname) void bip_set_interface(char *ifname)
{ {
uint8_t local_address[] = { 0, 0, 0, 0 }; uint8_t local_address[] = { 0, 0, 0, 0 };
uint8_t broadcast_address[] = { 0, 0, 0, 0 }; uint8_t broadcast_address[] = { 0, 0, 0, 0 };
uint8_t netmask[] = { 0, 0, 0, 0 }; uint8_t netmask[] = { 0, 0, 0, 0 };
+12 -19
View File
@@ -42,7 +42,6 @@
#include "socketWrapper.h" #include "socketWrapper.h"
#include "w5100Wrapper.h" #include "w5100Wrapper.h"
#if PRINT_ENABLED | DEBUG #if PRINT_ENABLED | DEBUG
#include <stdio.h> /* for standard i/o, like printing */ #include <stdio.h> /* for standard i/o, like printing */
#endif #endif
@@ -71,8 +70,7 @@ uint32_t convertBIP_Address2uint32(uint8_t * bip_address)
/** Convert from uint32_t IPv4 address to uint8_t[4] address /** Convert from uint32_t IPv4 address to uint8_t[4] address
* *
*/ */
void convertUint32Address_2_uint8Address(uint32_t ip, void convertUint32Address_2_uint8Address(uint32_t ip, uint8_t *address)
uint8_t * address)
{ {
address[0] = (uint8_t)(ip >> 24); address[0] = (uint8_t)(ip >> 24);
address[1] = (uint8_t)(ip >> 16); address[1] = (uint8_t)(ip >> 16);
@@ -127,7 +125,6 @@ uint8_t *bip_get_broadcast_addr(void)
return BIP_Broadcast_Address; return BIP_Broadcast_Address;
} }
void bip_set_port(uint16_t port) void bip_set_port(uint16_t port)
{ /* in network byte order */ { /* in network byte order */
BIP_Port = htons(port); BIP_Port = htons(port);
@@ -187,8 +184,8 @@ int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
} }
mtu[0] = BVLL_TYPE_BACNET_IP; mtu[0] = BVLL_TYPE_BACNET_IP;
if ((dest->net == BACNET_BROADCAST_NETWORK) || ((dest->net > 0) && if ((dest->net == BACNET_BROADCAST_NETWORK) ||
(dest->len == 0)) || (dest->mac_len == 0)) { ((dest->net > 0) && (dest->len == 0)) || (dest->mac_len == 0)) {
/* broadcast */ /* broadcast */
for (uint8_t i = 0; i < 4; i++) for (uint8_t i = 0; i < 4; i++)
address[i] = BIP_Broadcast_Address[i]; address[i] = BIP_Broadcast_Address[i];
@@ -196,16 +193,14 @@ int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU; mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0], fprintf(stderr, "Send Broadcast NPDU to %d.%d.%d.%d:%d\n", address[0],
address[1] address[1], address[2], address[3], port);
, address[2], address[3], port);
#endif #endif
} else if (dest->mac_len == 6) { } else if (dest->mac_len == 6) {
bip_decode_bip_address(dest, address, &port); bip_decode_bip_address(dest, address, &port);
mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU; mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0], fprintf(stderr, "Send Unicast NPDU to %d.%d.%d.%d:%d\n", address[0],
address[1] address[1], address[2], address[3], port);
, address[2], address[3], port);
#endif #endif
} else { } else {
/* invalid address */ /* invalid address */
@@ -213,9 +208,8 @@ int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
} }
mtu_len = 2; mtu_len = 2;
mtu_len += mtu_len += encode_unsigned16(
encode_unsigned16(&mtu[mtu_len], &mtu[mtu_len], (uint16_t)(pdu_len + 4 /*inclusive */));
(uint16_t) (pdu_len + 4 /*inclusive */ ));
memcpy(&mtu[mtu_len], pdu, pdu_len); memcpy(&mtu[mtu_len], pdu, pdu_len);
mtu_len += pdu_len; mtu_len += pdu_len;
@@ -224,8 +218,7 @@ int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
#endif #endif
/* Send the packet */ /* Send the packet */
bytes_sent = bytes_sent = sendto_func(BIP_Socket, mtu, (uint16_t)mtu_len, address, port);
sendto_func(BIP_Socket, mtu, (uint16_t) mtu_len, address, port);
return bytes_sent; return bytes_sent;
} }
@@ -236,7 +229,8 @@ int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
* *
* @param src [out] Source of the packet - who should receive any response. * @param src [out] Source of the packet - who should receive any response.
* @param pdu [out] A buffer to hold the PDU portion of the received packet, * @param pdu [out] A buffer to hold the PDU portion of the received packet,
* after the BVLC portion has been stripped off. * after the BVLC portion has been stripped
* off.
* @param max_pdu [in] Size of the pdu[] buffer. * @param max_pdu [in] Size of the pdu[] buffer.
* @param timeout [in] The number of milliseconds to wait for a packet. * @param timeout [in] The number of milliseconds to wait for a packet.
* @return The number of octets (remaining) in the PDU, or zero on failure. * @return The number of octets (remaining) in the PDU, or zero on failure.
@@ -263,9 +257,8 @@ uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */
if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) { if (getRXReceivedSize_func(CW5100Class_new(), BIP_Socket)) {
memcpy(&src_addr, &src->mac[0], 4); memcpy(&src_addr, &src->mac[0], 4);
memcpy(&src_port, &src->mac[4], 2); memcpy(&src_port, &src->mac[4], 2);
received_bytes = received_bytes = (int)recvfrom_func(
(int) recvfrom_func(BIP_Socket, &pdu[0], max_pdu, src_addr, BIP_Socket, &pdu[0], max_pdu, src_addr, &src_port);
&src_port);
} }
/* See if there is a problem */ /* See if there is a problem */
+10 -16
View File
@@ -113,15 +113,14 @@ int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, &apdu[0], OBJECT_BINARY_VALUE, object_instance);
object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Binary_Value_Name(object_instance)); &char_string, Binary_Value_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -186,9 +185,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 = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -201,9 +199,8 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value.type.Enumerated == BINARY_ACTIVE) || if ((value.type.Enumerated == BINARY_ACTIVE) ||
(value.type.Enumerated == BINARY_INACTIVE)) { (value.type.Enumerated == BINARY_INACTIVE)) {
object_index = object_index = Binary_Value_Instance_To_Index(
Binary_Value_Instance_To_Index(wp_data-> wp_data->object_instance);
object_instance);
/* NOTE: this Binary value has no priority array */ /* NOTE: this Binary value has no priority array */
Present_Value[object_index] = Present_Value[object_index] =
(BACNET_BINARY_PV)value.type.Enumerated; (BACNET_BINARY_PV)value.type.Enumerated;
@@ -265,15 +262,12 @@ void testBinary_Value(Test * pTest)
BACNET_ERROR_CLASS error_class; BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
len = Binary_Value_Encode_Property_APDU(&apdu[0], instance,
len =
Binary_Value_Encode_Property_APDU(&apdu[0], instance,
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = len = decode_object_id(&apdu[len], (int *)&decoded_type, &decoded_instance);
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE); ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE);
ct_test(pTest, decoded_instance == instance); ct_test(pTest, decoded_instance == instance);
+5 -7
View File
@@ -26,8 +26,7 @@ BACNET_BVLC_FUNCTION BVLC_Function_Code = BVLC_RESULT; /* A safe default */
* *
* @return number of bytes encoded * @return number of bytes encoded
*/ */
static int bvlc_encode_bvlc_result(uint8_t * pdu, static int bvlc_encode_bvlc_result(uint8_t *pdu, BACNET_BVLC_RESULT result_code)
BACNET_BVLC_RESULT result_code)
{ {
if (pdu) { if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP; pdu[0] = BVLL_TYPE_BACNET_IP;
@@ -101,10 +100,8 @@ static void bvlc_send_result(uint8_t * dest_addr,
* @return Non-zero BVLC_RESULT_ code if we sent a response (NAK) to this * @return Non-zero BVLC_RESULT_ code if we sent a response (NAK) to this
* BVLC message. If zero, may need further processing. * BVLC message. If zero, may need further processing.
*/ */
uint16_t bvlc_for_non_bbmd(uint8_t * addr, uint16_t bvlc_for_non_bbmd(
uint16_t * port, uint8_t *addr, uint16_t *port, uint8_t *npdu, uint16_t received_bytes)
uint8_t * npdu,
uint16_t received_bytes)
{ {
uint16_t result_code = 0; /* aka, BVLC_RESULT_SUCCESSFUL_COMPLETION */ uint16_t result_code = 0; /* aka, BVLC_RESULT_SUCCESSFUL_COMPLETION */
@@ -124,7 +121,8 @@ uint16_t bvlc_for_non_bbmd(uint8_t * addr,
} }
break; break;
case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE: case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE:
result_code = BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK; result_code =
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK;
break; break;
case BVLC_READ_BROADCAST_DIST_TABLE: case BVLC_READ_BROADCAST_DIST_TABLE:
result_code = BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK; result_code = BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK;
+31 -33
View File
@@ -106,9 +106,8 @@ unsigned Device_Object_List_Count(void)
return count; return count;
} }
bool Device_Object_List_Identifier(uint32_t array_index, bool Device_Object_List_Identifier(
BACNET_OBJECT_TYPE *object_type, uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
uint32_t * instance)
{ {
bool status = false; bool status = false;
uint32_t object_index = 0; uint32_t object_index = 0;
@@ -174,9 +173,8 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
/* FIXME: change the hardcoded names to suit your application */ /* FIXME: change the hardcoded names to suit your application */
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_DEVICE, &apdu[0], OBJECT_DEVICE, Object_Instance_Number);
Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, Object_Name); characterstring_init_ansi(&char_string, Object_Name);
@@ -195,9 +193,8 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_VENDOR_IDENTIFIER: case PROP_VENDOR_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Vendor_Identifier());
Device_Vendor_Identifier());
break; break;
case PROP_MODEL_NAME: case PROP_MODEL_NAME:
characterstring_init_ansi(&char_string, "GNU Demo"); characterstring_init_ansi(&char_string, "GNU Demo");
@@ -220,8 +217,7 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_REVISION);
BACNET_PROTOCOL_REVISION);
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */ /* Note: list of services that are executed, not initiated. */
@@ -260,9 +256,8 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
else if (array_index == BACNET_ARRAY_ALL) { else if (array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
Device_Object_List_Identifier(i, &object_type, &instance); Device_Object_List_Identifier(i, &object_type, &instance);
len = len = encode_application_object_id(
encode_application_object_id(&apdu[apdu_len], &apdu[apdu_len], object_type, instance);
object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
@@ -275,11 +270,10 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
} }
} }
} else { } else {
if (Device_Object_List_Identifier(array_index, &object_type, if (Device_Object_List_Identifier(
&instance)) array_index, &object_type, &instance))
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], object_type, &apdu[0], object_type, instance);
instance);
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;
@@ -313,18 +307,20 @@ int Device_Encode_Property_APDU(uint8_t * apdu,
// break; // break;
// case PROP_MAX_MASTER: // case PROP_MAX_MASTER:
// apdu_len = // apdu_len =
// encode_application_unsigned(&apdu[0], dlmstp_max_master()); // encode_application_unsigned(&apdu[0],
// dlmstp_max_master());
// break; // break;
// case 9600: // case 9600:
// apdu_len = // apdu_len =
// encode_application_unsigned(&apdu[0], RS485_Get_Baud_Rate()); // encode_application_unsigned(&apdu[0],
// RS485_Get_Baud_Rate());
// break; // break;
// case 512: // case 512:
// apdu_len = encode_application_unsigned(&apdu[0], stack_size()); // apdu_len = encode_application_unsigned(&apdu[0],
// break; // stack_size()); break;
// case 513: // case 513:
// apdu_len = encode_application_unsigned(&apdu[0], stack_unused()); // apdu_len = encode_application_unsigned(&apdu[0],
// break; // stack_unused()); break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
@@ -356,9 +352,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 = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -370,8 +365,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
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(value.type.Object_Id. (Device_Set_Object_Instance_Number(
instance))) { value.type.Object_Id.instance))) {
/* we could send an I-Am broadcast to let the world know */ /* we could send an I-Am broadcast to let the world know */
status = true; status = true;
} else { } else {
@@ -384,7 +379,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
} }
break; break;
// case PROP_MAX_INFO_FRAMES: // case PROP_MAX_INFO_FRAMES:
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { // if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)
// {
// if (value.type.Unsigned_Int <= 255) { // if (value.type.Unsigned_Int <= 255) {
// dlmstp_set_max_info_frames(value.type.Unsigned_Int); // dlmstp_set_max_info_frames(value.type.Unsigned_Int);
// status = true; // status = true;
@@ -398,7 +394,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
// } // }
// break; // break;
// case PROP_MAX_MASTER: // case PROP_MAX_MASTER:
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { // if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)
// {
// if ((value.type.Unsigned_Int > 0) && // if ((value.type.Unsigned_Int > 0) &&
// (value.type.Unsigned_Int <= 127)) { // (value.type.Unsigned_Int <= 127)) {
// dlmstp_set_max_master(value.type.Unsigned_Int); // dlmstp_set_max_master(value.type.Unsigned_Int);
@@ -437,7 +434,8 @@ bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
} }
break; break;
// case 9600: // case 9600:
// if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { // if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)
// {
// if (value.type.Unsigned_Int > 115200) { // if (value.type.Unsigned_Int > 115200) {
// RS485_Set_Baud_Rate(value.type.Unsigned_Int); // RS485_Set_Baud_Rate(value.type.Unsigned_Int);
// status = true; // status = true;
+17 -26
View File
@@ -54,24 +54,21 @@ int Encode_Property_APDU(uint8_t * apdu,
switch (rp_data->object_type) { switch (rp_data->object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
apdu_len = apdu_len = Device_Encode_Property_APDU(&apdu[0],
Device_Encode_Property_APDU(&apdu[0],
rp_data->object_instance, rp_data->object_property, rp_data->object_instance, rp_data->object_property,
rp_data->array_index, error_class, error_code); rp_data->array_index, error_class, error_code);
} }
break; break;
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Valid_Instance(rp_data->object_instance)) { if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
apdu_len = apdu_len = Analog_Value_Encode_Property_APDU(&apdu[0],
Analog_Value_Encode_Property_APDU(&apdu[0],
rp_data->object_instance, rp_data->object_property, rp_data->object_instance, rp_data->object_property,
rp_data->array_index, error_class, error_code); rp_data->array_index, error_class, error_code);
} }
break; break;
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Valid_Instance(rp_data->object_instance)) { if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
apdu_len = apdu_len = Binary_Value_Encode_Property_APDU(&apdu[0],
Binary_Value_Encode_Property_APDU(&apdu[0],
rp_data->object_instance, rp_data->object_property, rp_data->object_instance, rp_data->object_property,
rp_data->array_index, error_class, error_code); rp_data->array_index, error_class, error_code);
} }
@@ -103,13 +100,11 @@ void handler_read_property(uint8_t * service_request,
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
&npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
goto RP_ABORT; goto RP_ABORT;
@@ -117,36 +112,32 @@ void handler_read_property(uint8_t * service_request,
len = rp_decode_service_request(service_request, service_len, &data); len = rp_decode_service_request(service_request, service_len, &data);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RP_ABORT; goto RP_ABORT;
} }
/* most cases will be error */ /* most cases will be error */
ack_len = ack_len = rp_ack_encode_apdu_init(
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
service_data->invoke_id, &data);
/* FIXME: add buffer len as passed into function or use smart buffer */ /* FIXME: add buffer len as passed into function or use smart buffer */
property_len = property_len =
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], &data,
&data, &error_class, &error_code); &error_class, &error_code);
if (property_len >= 0) { if (property_len >= 0) {
len = len = rp_ack_encode_apdu_object_property_end(
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer &Handler_Transmit_Buffer[pdu_len + property_len + ack_len]);
[pdu_len + property_len + ack_len]);
len += ack_len + property_len; len += ack_len + property_len;
} else { } else {
switch (property_len) { switch (property_len) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is
* Abort */
case BACNET_STATUS_ABORT: case BACNET_STATUS_ABORT:
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
break; break;
default: default:
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
error_class, error_code); error_class, error_code);
break; break;
+5 -8
View File
@@ -39,8 +39,7 @@
bool Send_I_Am_Flag = true; bool Send_I_Am_Flag = true;
void sendIamUnicast(uint8_t * buffer, void sendIamUnicast(uint8_t *buffer, BACNET_ADDRESS *src)
BACNET_ADDRESS * src)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
int pdu_len = 0; int pdu_len = 0;
@@ -67,18 +66,16 @@ void sendIamUnicast(uint8_t * buffer,
int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); int bytes = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
} }
void handler_who_is(uint8_t * service_request, void handler_who_is(
uint16_t service_len, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
BACNET_ADDRESS * src)
{ {
int len = 0; int len = 0;
int32_t low_limit = 0; int32_t low_limit = 0;
int32_t high_limit = 0; int32_t high_limit = 0;
int32_t target_device; int32_t target_device;
len = len = whois_decode_service_request(
whois_decode_service_request(service_request, service_len, &low_limit, service_request, service_len, &low_limit, &high_limit);
&high_limit);
if (len == 0) { if (len == 0) {
sendIamUnicast(&Handler_Transmit_Buffer[0], src); sendIamUnicast(&Handler_Transmit_Buffer[0], src);
} else if (len != -1) { } else if (len != -1) {
+14 -20
View File
@@ -61,25 +61,22 @@ void handler_write_property(uint8_t * service_request,
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
&npdu_data);
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
} else if (service_data->segmented_message) { } else if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
} else { } else {
switch (wp_data.object_type) { switch (wp_data.object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Write_Property(&wp_data, &error_class, &error_code)) { if (Device_Write_Property(
len = &wp_data, &error_class, &error_code)) {
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
@@ -91,10 +88,9 @@ void handler_write_property(uint8_t * service_request,
} }
break; break;
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property(&wp_data, &error_class, if (Analog_Value_Write_Property(
&error_code)) { &wp_data, &error_class, &error_code)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
@@ -106,10 +102,9 @@ void handler_write_property(uint8_t * service_request,
} }
break; break;
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property(&wp_data, &error_class, if (Binary_Value_Write_Property(
&error_code)) { &wp_data, &error_class, &error_code)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
@@ -121,8 +116,7 @@ void handler_write_property(uint8_t * service_request,
} }
break; break;
default: default:
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code); error_class, error_code);
break; break;
+2 -4
View File
@@ -32,8 +32,8 @@
extern bool Send_I_Am_Flag; extern bool Send_I_Am_Flag;
/* local version override */ /* local version override */
const char *BACnet_Version = "1.0"; const char *BACnet_Version = "1.0";
static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = static uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0xDE, 0xAD, 0xBE, 0xEF,
{ 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xFE, 0xED };
uint8_t ipAddress[] = { 192, 168, 0, 185 }; uint8_t ipAddress[] = { 192, 168, 0, 185 };
uint8_t gateway[] = { 192, 168, 0, 1 }; uint8_t gateway[] = { 192, 168, 0, 1 };
uint8_t netmask[] = { 255, 255, 255, 0 }; uint8_t netmask[] = { 255, 255, 255, 0 };
@@ -68,7 +68,6 @@ void setup()
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Starting BACNET application..\n"); fprintf(stderr, "Starting BACNET application..\n");
#endif #endif
} }
static uint8_t PDUBuffer[MAX_MPDU]; static uint8_t PDUBuffer[MAX_MPDU];
@@ -83,7 +82,6 @@ int main(void)
datalink_init(NULL); datalink_init(NULL);
for (;;) { for (;;) {
/* other tasks */ /* other tasks */
/* BACnet handling */ /* BACnet handling */
pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0);
+1 -2
View File
@@ -27,8 +27,7 @@ void uart_init(void)
UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */ UCSR0B = _BV(RXEN0) | _BV(TXEN0); /* Enable RX and TX */
} }
void uart_putchar(char c, void uart_putchar(char c, FILE *stream)
FILE * stream)
{ {
if (c == '\n') { if (c == '\n') {
uart_putchar('\r', stream); uart_putchar('\r', stream);
+18 -44
View File
@@ -45,31 +45,16 @@
static float Present_Value[MAX_ANALOG_INPUTS]; static float Present_Value[MAX_ANALOG_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Input_Properties_Required[] = { static const int Analog_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Input_Properties_Optional[] = { static const int Analog_Input_Properties_Optional[] = { PROP_DESCRIPTION, -1 };
PROP_DESCRIPTION,
-1
};
static const int Analog_Input_Properties_Proprietary[] = { static const int Analog_Input_Properties_Proprietary[] = { -1 };
-1
};
void Analog_Input_Property_Lists( void Analog_Input_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Analog_Input_Properties_Required; *pRequired = Analog_Input_Properties_Required;
@@ -84,8 +69,7 @@ void Analog_Input_Property_Lists(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
@@ -94,22 +78,19 @@ bool Analog_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
bool Analog_Input_Object_Name( bool Analog_Input_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[16] = "AI-0"; /* okay for single thread */ static char text_string[16] = "AI-0"; /* okay for single thread */
bool status = false; bool status = false;
@@ -122,8 +103,7 @@ bool Analog_Input_Object_Name(
return status; return status;
} }
float Analog_Input_Present_Value( float Analog_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
@@ -133,9 +113,7 @@ float Analog_Input_Present_Value(
return value; return value;
} }
void Analog_Input_Present_Value_Set( void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
if (object_instance < MAX_ANALOG_INPUTS) { if (object_instance < MAX_ANALOG_INPUTS) {
Present_Value[object_instance] = value; Present_Value[object_instance] = value;
@@ -144,8 +122,7 @@ void Analog_Input_Present_Value_Set(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object has already exists */
int Analog_Input_Read_Property( int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -159,9 +136,8 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, &apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
@@ -176,9 +152,8 @@ int Analog_Input_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -214,8 +189,7 @@ int Analog_Input_Read_Property(
return apdu_len; return apdu_len;
} }
void Analog_Input_Init( void Analog_Input_Init(void)
void)
{ {
return; return;
} }
+24 -49
View File
@@ -55,35 +55,21 @@
static uint8_t Present_Value[MAX_ANALOG_VALUES]; static uint8_t Present_Value[MAX_ANALOG_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Value_Properties_Required[] = { static const int Analog_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Value_Properties_Optional[] = { static const int Analog_Value_Properties_Optional[] = { PROP_DESCRIPTION,
PROP_DESCRIPTION,
#if 0 #if 0
PROP_PRIORITY_ARRAY, PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT, PROP_RELINQUISH_DEFAULT,
#endif #endif
-1 -1 };
};
static const int Analog_Value_Properties_Proprietary[] = { static const int Analog_Value_Properties_Proprietary[] = { -1 };
-1
};
void Analog_Value_Property_Lists( void Analog_Value_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Analog_Value_Properties_Required; *pRequired = Analog_Value_Properties_Required;
@@ -95,8 +81,7 @@ void Analog_Value_Property_Lists(
return; return;
} }
void Analog_Value_Init( void Analog_Value_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -111,8 +96,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
return true; return true;
@@ -122,8 +106,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(void)
void)
{ {
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
} }
@@ -131,8 +114,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -140,8 +122,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_VALUES; unsigned index = MAX_ANALOG_VALUES;
@@ -151,8 +132,7 @@ unsigned Analog_Value_Instance_To_Index(
return index; return index;
} }
float Analog_Value_Present_Value( float Analog_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = ANALOG_RELINQUISH_DEFAULT; float value = ANALOG_RELINQUISH_DEFAULT;
unsigned index = 0; unsigned index = 0;
@@ -166,8 +146,7 @@ float Analog_Value_Present_Value(
} }
bool Analog_Value_Object_Name( bool Analog_Value_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[16] = "AV-0"; /* okay for single thread */ static char text_string[16] = "AV-0"; /* okay for single thread */
bool status = false; bool status = false;
@@ -181,8 +160,7 @@ bool Analog_Value_Object_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Read_Property( int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -203,9 +181,8 @@ int Analog_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, &apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
@@ -322,8 +299,7 @@ int Analog_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -338,9 +314,8 @@ bool Analog_Value_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -366,16 +341,16 @@ bool Analog_Value_Write_Property(
(priority != 6 /* reserved */) && (priority != 6 /* reserved */) &&
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) { (value.type.Real >= 0.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(
Analog_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
Present_Value[object_index] = level; Present_Value[object_index] = level;
/* Note: you could set the physical output here if we /* Note: you could set the physical output here if we
are the highest priority. are the highest priority.
However, if Out of Service is TRUE, then don't set the However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
status = true; status = true;
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
+16 -40
View File
@@ -43,31 +43,16 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Input_Properties_Required[] = { static const int Binary_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_POLARITY,
-1
};
static const int Binary_Input_Properties_Optional[] = { static const int Binary_Input_Properties_Optional[] = { PROP_DESCRIPTION, -1 };
PROP_DESCRIPTION,
-1
};
static const int Binary_Input_Properties_Proprietary[] = { static const int Binary_Input_Properties_Proprietary[] = { -1 };
-1
};
void Binary_Input_Property_Lists( void Binary_Input_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) { if (pRequired) {
*pRequired = Binary_Input_Properties_Required; *pRequired = Binary_Input_Properties_Required;
@@ -82,8 +67,7 @@ void Binary_Input_Property_Lists(
return; return;
} }
void Binary_Input_Init( void Binary_Input_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -93,8 +77,7 @@ void Binary_Input_Init(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance( bool Binary_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_INPUTS) if (object_instance < MAX_BINARY_INPUTS)
return true; return true;
@@ -103,15 +86,13 @@ bool Binary_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Input_Count( unsigned Binary_Input_Count(void)
void)
{ {
return MAX_BINARY_INPUTS; return MAX_BINARY_INPUTS;
} }
/* we simply have 0-n object instances.*/ /* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance( uint32_t Binary_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -119,8 +100,7 @@ uint32_t Binary_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index( unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_INPUTS; unsigned index = MAX_BINARY_INPUTS;
@@ -130,8 +110,7 @@ unsigned Binary_Input_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Input_Present_Value( BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0; unsigned index = 0;
@@ -145,8 +124,7 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
} }
bool Binary_Input_Object_Name( bool Binary_Input_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[16] = "BI-0"; /* okay for single thread */ static char text_string[16] = "BI-0"; /* okay for single thread */
bool status = false; bool status = false;
@@ -161,8 +139,7 @@ bool Binary_Input_Object_Name(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */ /* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property( int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -178,9 +155,8 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT, &apdu[0], OBJECT_BINARY_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
+9 -7
View File
@@ -15,11 +15,10 @@
/* global variables */ /* global variables */
unsigned long blinkcount; unsigned long blinkcount;
void blinker( void blinker(unsigned char code)
unsigned char code)
{ {
volatile AT91PS_PIO pPIO =
volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; /* pointer to PIO register structure */ AT91C_BASE_PIOA; /* pointer to PIO register structure */
volatile unsigned int j, k; /* loop counters */ volatile unsigned int j, k; /* loop counters */
/* endless loop */ /* endless loop */
@@ -29,14 +28,17 @@ void blinker(
/* turn LED1 (DS1) on */ /* turn LED1 (DS1) on */
pPIO->PIO_CODR = LED1; pPIO->PIO_CODR = LED1;
/* wait 250 msec */ /* wait 250 msec */
for (k = 600000; k != 0; k--); for (k = 600000; k != 0; k--)
;
/* turn LED1 (DS1) off */ /* turn LED1 (DS1) off */
pPIO->PIO_SODR = LED1; pPIO->PIO_SODR = LED1;
/* wait 250 msec */ /* wait 250 msec */
for (k = 600000; k != 0; k--); for (k = 600000; k != 0; k--)
;
} }
/* wait 2 seconds */ /* wait 2 seconds */
for (k = 5000000; (code != 0) && (k != 0); k--); for (k = 5000000; (code != 0) && (k != 0); k--)
;
blinkcount++; blinkcount++;
} }
} }
+22 -49
View File
@@ -45,30 +45,16 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Value_Properties_Required[] = { static const int Binary_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
-1
};
static const int Binary_Value_Properties_Optional[] = { static const int Binary_Value_Properties_Optional[] = { PROP_DESCRIPTION, -1 };
PROP_DESCRIPTION,
-1
};
static const int Binary_Value_Properties_Proprietary[] = { static const int Binary_Value_Properties_Proprietary[] = { -1 };
-1
};
void Binary_Value_Property_Lists( void Binary_Value_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Binary_Value_Properties_Required; *pRequired = Binary_Value_Properties_Required;
@@ -80,8 +66,7 @@ void Binary_Value_Property_Lists(
return; return;
} }
void Binary_Value_Init( void Binary_Value_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -91,8 +76,7 @@ void Binary_Value_Init(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance( bool Binary_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_VALUES) if (object_instance < MAX_BINARY_VALUES)
return true; return true;
@@ -101,22 +85,19 @@ bool Binary_Value_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Value_Count( unsigned Binary_Value_Count(void)
void)
{ {
return MAX_BINARY_VALUES; return MAX_BINARY_VALUES;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Binary_Value_Index_To_Instance( uint32_t Binary_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Value_Instance_To_Index( unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_VALUES; unsigned index = MAX_BINARY_VALUES;
@@ -126,8 +107,7 @@ unsigned Binary_Value_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Value_Present_Value( BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
@@ -140,8 +120,7 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Binary_Value_Object_Name( bool Binary_Value_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[16] = "BV-0"; /* okay for single thread */ static char text_string[16] = "BV-0"; /* okay for single thread */
bool status = false; bool status = false;
@@ -155,8 +134,7 @@ bool Binary_Value_Object_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Binary_Value_Read_Property( int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -173,9 +151,8 @@ int Binary_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, &apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
@@ -190,8 +167,7 @@ int Binary_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE); encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
present_value = present_value = Binary_Value_Present_Value(rpdata->object_instance);
Binary_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value); apdu_len = encode_application_enumerated(&apdu[0], present_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -232,8 +208,7 @@ int Binary_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Value_Write_Property( bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -248,9 +223,8 @@ bool Binary_Value_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -277,9 +251,8 @@ bool Binary_Value_Write_Property(
(value.type.Enumerated >= MIN_BINARY_PV) && (value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) { (value.type.Enumerated <= MAX_BINARY_PV)) {
level = value.type.Enumerated; level = value.type.Enumerated;
object_index = object_index = Binary_Value_Instance_To_Index(
Binary_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
/* NOTE: this Binary value has no priority array */ /* NOTE: this Binary value has no priority array */
Present_Value[object_index] = level; Present_Value[object_index] = level;
+96 -165
View File
@@ -50,10 +50,8 @@
static const char *BACnet_Version = BACNET_VERSION_TEXT; static const char *BACnet_Version = BACNET_VERSION_TEXT;
/* forward prototype */ /* forward prototype */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
BACNET_READ_PROPERTY_DATA * rpdata); bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
bool Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA * wp_data);
static struct my_object_functions { static struct my_object_functions {
BACNET_OBJECT_TYPE Object_Type; BACNET_OBJECT_TYPE Object_Type;
@@ -65,31 +63,28 @@ static struct my_object_functions {
read_property_function Object_Read_Property; read_property_function Object_Read_Property;
write_property_function Object_Write_Property; write_property_function Object_Write_Property;
rpm_property_lists_function Object_RPM_List; rpm_property_lists_function Object_RPM_List;
} Object_Table[] = { } Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
{
OBJECT_DEVICE, NULL, /* don't init - recursive! */
Device_Count, Device_Index_To_Instance, Device_Count, Device_Index_To_Instance,
Device_Valid_Object_Instance_Number, Device_Object_Name, Device_Valid_Object_Instance_Number,
Device_Read_Property_Local, Device_Write_Property_Local, Device_Object_Name, Device_Read_Property_Local,
Device_Property_Lists}, { Device_Write_Property_Local, Device_Property_Lists },
OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, { OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
Analog_Input_Object_Name, Analog_Input_Read_Property, NULL, Analog_Input_Object_Name, Analog_Input_Read_Property, NULL,
Analog_Input_Property_Lists}, { Analog_Input_Property_Lists },
OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count, { OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
Analog_Value_Object_Name, Analog_Value_Read_Property, Analog_Value_Object_Name, Analog_Value_Read_Property,
Analog_Value_Write_Property, Analog_Value_Property_Lists}, { Analog_Value_Write_Property, Analog_Value_Property_Lists },
OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, { OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
Binary_Input_Object_Name, Binary_Input_Read_Property, NULL, Binary_Input_Object_Name, Binary_Input_Read_Property, NULL,
Binary_Input_Property_Lists}, { Binary_Input_Property_Lists },
OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count, { OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count,
Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance, Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance,
Binary_Value_Object_Name, Binary_Value_Read_Property, Binary_Value_Object_Name, Binary_Value_Read_Property,
Binary_Value_Write_Property, Binary_Value_Property_Lists}, { Binary_Value_Write_Property, Binary_Value_Property_Lists },
MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL} { MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };
};
/* note: you really only need to define variables for /* note: you really only need to define variables for
properties that are writable or that may change. properties that are writable or that may change.
@@ -103,42 +98,21 @@ static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
static const char *Reinit_Password = "rehmite"; static const char *Reinit_Password = "rehmite";
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Device_Properties_Required[] = { static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
PROP_OBJECT_NAME, PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
PROP_OBJECT_TYPE, PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
PROP_SYSTEM_STATUS, PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_VENDOR_NAME, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST,
PROP_VENDOR_IDENTIFIER, PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
PROP_MODEL_NAME, PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_MAX_MASTER,
PROP_FIRMWARE_REVISION, PROP_MAX_INFO_FRAMES, PROP_DEVICE_ADDRESS_BINDING, PROP_DATABASE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION, -1 };
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_REVISION,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_OBJECT_LIST,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
PROP_DEVICE_ADDRESS_BINDING,
PROP_DATABASE_REVISION,
-1
};
static const int Device_Properties_Optional[] = { static const int Device_Properties_Optional[] = { PROP_DESCRIPTION,
PROP_DESCRIPTION, PROP_LOCATION, -1 };
PROP_LOCATION,
-1
};
static const int Device_Properties_Proprietary[] = { static const int Device_Properties_Proprietary[] = { 9600, -1 };
9600,
-1
};
static struct my_object_functions *Device_Objects_Find_Functions( static struct my_object_functions *Device_Objects_Find_Functions(
BACNET_OBJECT_TYPE Object_Type) BACNET_OBJECT_TYPE Object_Type)
@@ -159,8 +133,7 @@ static struct my_object_functions *Device_Objects_Find_Functions(
} }
static int Read_Property_Common( static int Read_Property_Common(
struct my_object_functions *pObject, struct my_object_functions *pObject, BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = BACNET_STATUS_ERROR; int apdu_len = BACNET_STATUS_ERROR;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
@@ -184,9 +157,8 @@ static int Read_Property_Common(
if (rpdata->object_type == OBJECT_DEVICE) { if (rpdata->object_type == OBJECT_DEVICE) {
rpdata->object_instance = Object_Instance_Number; rpdata->object_instance = Object_Instance_Number;
} }
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], rpdata->object_type, &apdu[0], rpdata->object_type, rpdata->object_instance);
rpdata->object_instance);
} }
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -198,12 +170,11 @@ static int Read_Property_Common(
} else { } else {
characterstring_init_ansi(&char_string, ""); characterstring_init_ansi(&char_string, "");
if (pObject->Object_Name) { if (pObject->Object_Name) {
(void) pObject->Object_Name(rpdata->object_instance, (void)pObject->Object_Name(
&char_string); rpdata->object_instance, &char_string);
} }
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], encode_application_character_string(&apdu[0], &char_string);
&char_string);
} }
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
@@ -213,9 +184,8 @@ static int Read_Property_Common(
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} else { } else {
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], rpdata->object_type);
rpdata->object_type);
} }
break; break;
default: default:
@@ -230,8 +200,7 @@ static int Read_Property_Common(
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns BACNET_STATUS_ERROR */ or sets the error, and returns BACNET_STATUS_ERROR */
int Device_Read_Property( int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = BACNET_STATUS_ERROR; int apdu_len = BACNET_STATUS_ERROR;
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -254,8 +223,7 @@ int Device_Read_Property(
return apdu_len; return apdu_len;
} }
bool Device_Write_Property( bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; bool status = false;
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -284,8 +252,7 @@ bool Device_Write_Property(
} }
/* for a given object type, returns the special property list */ /* for a given object type, returns the special property list */
void Device_Objects_Property_List( void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
struct special_property_list_t *pPropertyList) struct special_property_list_t *pPropertyList)
{ {
@@ -308,25 +275,23 @@ void Device_Objects_Property_List(
} }
/* Fetch the counts if available otherwise zero them */ /* Fetch the counts if available otherwise zero them */
pPropertyList->Required.count = pPropertyList->Required.count = pPropertyList->Required.pList == NULL
pPropertyList->Required.pList == ? 0
NULL ? 0 : property_list_count(pPropertyList->Required.pList); : property_list_count(pPropertyList->Required.pList);
pPropertyList->Optional.count = pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL
pPropertyList->Optional.pList == ? 0
NULL ? 0 : property_list_count(pPropertyList->Optional.pList); : property_list_count(pPropertyList->Optional.pList);
pPropertyList->Proprietary.count = pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL
pPropertyList->Proprietary.pList == ? 0
NULL ? 0 : property_list_count(pPropertyList->Proprietary.pList); : property_list_count(pPropertyList->Proprietary.pList);
return; return;
} }
void Device_Property_Lists( void Device_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Device_Properties_Required; *pRequired = Device_Properties_Required;
@@ -338,22 +303,19 @@ void Device_Property_Lists(
return; return;
} }
unsigned Device_Count( unsigned Device_Count(void)
void)
{ {
return 1; return 1;
} }
uint32_t Device_Index_To_Instance( uint32_t Device_Index_To_Instance(unsigned index)
unsigned index)
{ {
index = index; index = index;
return Object_Instance_Number; return Object_Instance_Number;
} }
bool Device_Object_Name( bool Device_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
bool status = false; bool status = false;
@@ -364,8 +326,7 @@ bool Device_Object_Name(
return status; return status;
} }
bool Device_Set_Object_Name( bool Device_Set_Object_Name(BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -378,8 +339,7 @@ bool Device_Set_Object_Name(
return status; return status;
} }
bool Device_Reinitialize( bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
BACNET_REINITIALIZE_DEVICE_DATA * rd_data)
{ {
bool status = false; bool status = false;
@@ -422,14 +382,12 @@ bool Device_Reinitialize(
return status; return status;
} }
BACNET_REINITIALIZED_STATE Device_Reinitialized_State( BACNET_REINITIALIZED_STATE Device_Reinitialized_State(void)
void)
{ {
return Reinitialize_State; return Reinitialize_State;
} }
void Device_Init( void Device_Init(object_functions_t *object_table)
object_functions_t * object_table)
{ {
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -450,14 +408,12 @@ void Device_Init(
} }
/* methods to manipulate the data */ /* methods to manipulate the data */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(void)
void)
{ {
return Object_Instance_Number; return Object_Instance_Number;
} }
bool Device_Set_Object_Instance_Number( bool Device_Set_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
@@ -469,21 +425,17 @@ bool Device_Set_Object_Instance_Number(
return status; return status;
} }
bool Device_Valid_Object_Instance_Number( bool Device_Valid_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
return (Object_Instance_Number == object_id); return (Object_Instance_Number == object_id);
} }
BACNET_DEVICE_STATUS Device_System_Status( BACNET_DEVICE_STATUS Device_System_Status(void)
void)
{ {
return System_Status; return System_Status;
} }
int Device_Set_System_Status( int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
BACNET_DEVICE_STATUS status,
bool local)
{ {
/*return value - 0 = ok, -1 = bad value, -2 = not allowed */ /*return value - 0 = ok, -1 = bad value, -2 = not allowed */
int result = -1; int result = -1;
@@ -496,34 +448,29 @@ int Device_Set_System_Status(
return result; return result;
} }
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(void)
void)
{ {
return BACNET_VENDOR_ID; return BACNET_VENDOR_ID;
} }
BACNET_SEGMENTATION Device_Segmentation_Supported( BACNET_SEGMENTATION Device_Segmentation_Supported(void)
void)
{ {
return SEGMENTATION_NONE; return SEGMENTATION_NONE;
} }
uint32_t Device_Database_Revision( uint32_t Device_Database_Revision(void)
void)
{ {
return Database_Revision; return Database_Revision;
} }
void Device_Inc_Database_Revision( void Device_Inc_Database_Revision(void)
void)
{ {
Database_Revision++; Database_Revision++;
} }
/* Since many network clients depend on the object list */ /* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */ /* for discovery, it must be consistent! */
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(void)
void)
{ {
unsigned count = 0; /* number of objects */ unsigned count = 0; /* number of objects */
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -541,9 +488,7 @@ unsigned Device_Object_List_Count(
} }
bool Device_Object_List_Identifier( bool Device_Object_List_Identifier(
uint32_t array_index, uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
BACNET_OBJECT_TYPE *object_type,
uint32_t * instance)
{ {
bool status = false; bool status = false;
uint32_t count = 0; uint32_t count = 0;
@@ -574,8 +519,7 @@ bool Device_Object_List_Identifier(
return status; return status;
} }
bool Device_Valid_Object_Name( bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
BACNET_CHARACTER_STRING * object_name1,
BACNET_OBJECT_TYPE *object_type, BACNET_OBJECT_TYPE *object_type,
uint32_t *object_instance) uint32_t *object_instance)
{ {
@@ -611,8 +555,7 @@ bool Device_Valid_Object_Name(
} }
bool Device_Valid_Object_Id( bool Device_Valid_Object_Id(
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
uint32_t object_instance)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -625,8 +568,7 @@ bool Device_Valid_Object_Id(
return status; return status;
} }
bool Device_Object_Name_Copy( bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
@@ -642,8 +584,7 @@ bool Device_Object_Name_Copy(
} }
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */ /* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */ int len = 0; /* apdu len intermediate value */
@@ -674,8 +615,7 @@ int Device_Read_Property_Local(
break; break;
case PROP_SYSTEM_STATUS: case PROP_SYSTEM_STATUS:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], Device_System_Status());
Device_System_Status());
break; break;
case PROP_VENDOR_NAME: case PROP_VENDOR_NAME:
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME); characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
@@ -706,8 +646,7 @@ int Device_Read_Property_Local(
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_REVISION);
BACNET_PROTOCOL_REVISION);
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */ /* Note: list of services that are executed, not initiated. */
@@ -749,11 +688,10 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */ /* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
if (Device_Object_List_Identifier(i, &object_type, if (Device_Object_List_Identifier(
&instance)) { i, &object_type, &instance)) {
len = len = encode_application_object_id(
encode_application_object_id(&apdu[apdu_len], &apdu[apdu_len], object_type, instance);
object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
@@ -773,11 +711,10 @@ int Device_Read_Property_Local(
} }
} }
} else { } else {
if (Device_Object_List_Identifier(rpdata->array_index, if (Device_Object_List_Identifier(
&object_type, &instance)) rpdata->array_index, &object_type, &instance))
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], object_type, &apdu[0], object_type, instance);
instance);
else { else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -789,9 +726,8 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break; break;
case PROP_SEGMENTATION_SUPPORTED: case PROP_SEGMENTATION_SUPPORTED:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Device_Segmentation_Supported());
Device_Segmentation_Supported());
break; break;
case PROP_APDU_TIMEOUT: case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout()); apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
@@ -803,14 +739,12 @@ int Device_Read_Property_Local(
/* 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 = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Database_Revision());
Device_Database_Revision());
break; break;
case PROP_MAX_INFO_FRAMES: case PROP_MAX_INFO_FRAMES:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
dlmstp_max_info_frames());
break; break;
case PROP_MAX_MASTER: case PROP_MAX_MASTER:
apdu_len = apdu_len =
@@ -837,8 +771,7 @@ int Device_Read_Property_Local(
return apdu_len; return apdu_len;
} }
bool Device_Write_Property_Local( bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value - false=error */ bool status = false; /* return value - false=error */
int len = 0; int len = 0;
@@ -847,9 +780,8 @@ bool Device_Write_Property_Local(
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -868,8 +800,8 @@ bool Device_Write_Property_Local(
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(value.type. (Device_Set_Object_Instance_Number(
Object_Id.instance))) { value.type.Object_Id.instance))) {
/* we could send an I-Am broadcast to let the world know */ /* we could send an I-Am broadcast to let the world know */
status = true; status = true;
} else { } else {
@@ -921,13 +853,13 @@ bool Device_Write_Property_Local(
characterstring_encoding(&value.type.Character_String); characterstring_encoding(&value.type.Character_String);
if (encoding < MAX_CHARACTER_STRING_ENCODING) { if (encoding < MAX_CHARACTER_STRING_ENCODING) {
/* All the object names in a device must be unique. */ /* All the object names in a device must be unique. */
if (Device_Valid_Object_Name(&value.type. if (Device_Valid_Object_Name(
Character_String, NULL, NULL)) { &value.type.Character_String, NULL, NULL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_DUPLICATE_NAME; wp_data->error_code = ERROR_CODE_DUPLICATE_NAME;
} else { } else {
Device_Set_Object_Name(&value.type. Device_Set_Object_Name(
Character_String); &value.type.Character_String);
status = true; status = true;
} }
} else { } else {
@@ -937,8 +869,7 @@ bool Device_Write_Property_Local(
} }
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
} }
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
+42 -61
View File
@@ -178,7 +178,11 @@ static uint8_t Nmax_master = 127;
#define Tusage_delay 15 #define Tusage_delay 15
/* we need to be able to increment without rolling over */ /* we need to be able to increment without rolling over */
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} #define INCREMENT_AND_LIMIT_UINT8(x) \
{ \
if (x < 0xFF) \
x++; \
}
/* data structure for MS/TP PDU Queue */ /* data structure for MS/TP PDU Queue */
struct mstp_pdu_packet { struct mstp_pdu_packet {
@@ -194,8 +198,7 @@ struct mstp_pdu_packet {
static struct mstp_pdu_packet PDU_Buffer[MSTP_PDU_PACKET_COUNT]; static struct mstp_pdu_packet PDU_Buffer[MSTP_PDU_PACKET_COUNT];
static RING_BUFFER PDU_Queue; static RING_BUFFER PDU_Queue;
bool dlmstp_init( bool dlmstp_init(char *ifname)
char *ifname)
{ {
(void)ifname; (void)ifname;
/* initialize hardware */ /* initialize hardware */
@@ -206,15 +209,12 @@ bool dlmstp_init(
return true; return true;
} }
void dlmstp_cleanup( void dlmstp_cleanup(void)
void)
{ {
/* nothing to do for static buffers */ /* nothing to do for static buffers */
} }
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
BACNET_ADDRESS * src,
uint8_t mstp_address)
{ {
int i = 0; int i = 0;
@@ -237,8 +237,7 @@ void dlmstp_fill_bacnet_address(
} }
} }
static bool dlmstp_compare_data_expecting_reply( static bool dlmstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint8_t * request_pdu,
uint16_t request_pdu_len, uint16_t request_pdu_len,
uint8_t src_address, uint8_t src_address,
uint8_t *reply_pdu, uint8_t *reply_pdu,
@@ -262,9 +261,8 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the request data */ /* decode the request data */
request.address.mac[0] = src_address; request.address.mac[0] = src_address;
request.address.mac_len = 1; request.address.mac_len = 1;
offset = offset = npdu_decode(
npdu_decode(&request_pdu[0], NULL, &request.address, &request_pdu[0], NULL, &request.address, &request.npdu_data);
&request.npdu_data);
if (request.npdu_data.network_layer_message) { if (request.npdu_data.network_layer_message) {
return false; return false;
} }
@@ -281,8 +279,7 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */ /* decode the reply data */
reply.address.mac[0] = dest_address; reply.address.mac[0] = dest_address;
reply.address.mac_len = 1; reply.address.mac_len = 1;
offset = offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
return false; return false;
} }
@@ -323,7 +320,8 @@ static bool dlmstp_compare_data_expecting_reply(
return false; return false;
} }
} }
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) { if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false; return false;
} }
#if 0 #if 0
@@ -397,8 +395,7 @@ static void MSTP_Send_Frame(
RS485_Transmitter_Enable(false); RS485_Transmitter_Enable(false);
} }
static void MSTP_Receive_Frame_FSM( static void MSTP_Receive_Frame_FSM(void)
void)
{ {
/* stores the latest received data octet */ /* stores the latest received data octet */
uint8_t DataRegister = 0; uint8_t DataRegister = 0;
@@ -633,8 +630,7 @@ static void MSTP_Receive_Frame_FSM(
} }
/* returns true if we need to transition immediately */ /* returns true if we need to transition immediately */
static bool MSTP_Master_Node_FSM( static bool MSTP_Master_Node_FSM(void)
void)
{ {
/* The number of frames sent by this node during a single token hold. */ /* The number of frames sent by this node during a single token hold. */
/* When this counter reaches the value Nmax_info_frames, the node must */ /* When this counter reaches the value Nmax_info_frames, the node must */
@@ -719,8 +715,7 @@ static bool MSTP_Master_Node_FSM(
/* ReceivedPFM */ /* ReceivedPFM */
/* DestinationAddress is equal to TS */ /* DestinationAddress is equal to TS */
if (DestinationAddress == This_Station) { if (DestinationAddress == This_Station) {
MSTP_Send_Frame( MSTP_Send_Frame(FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER,
SourceAddress, This_Station, NULL, 0); SourceAddress, This_Station, NULL, 0);
} }
break; break;
@@ -738,9 +733,8 @@ static bool MSTP_Master_Node_FSM(
} }
break; break;
case FRAME_TYPE_TEST_REQUEST: case FRAME_TYPE_TEST_REQUEST:
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress,
SourceAddress, This_Station, &InputBuffer[0], This_Station, &InputBuffer[0], DataLength);
DataLength);
break; break;
case FRAME_TYPE_TEST_RESPONSE: case FRAME_TYPE_TEST_RESPONSE:
default: default:
@@ -903,8 +897,8 @@ static bool MSTP_Master_Node_FSM(
may be found in that case. */ may be found in that case. */
TokenCount++; TokenCount++;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
RetryCount = 0; RetryCount = 0;
EventCount = 0; EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN; Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
@@ -926,8 +920,8 @@ static bool MSTP_Master_Node_FSM(
/* ResetMaintenancePFM */ /* ResetMaintenancePFM */
Poll_Station = This_Station; Poll_Station = This_Station;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
RetryCount = 0; RetryCount = 0;
TokenCount = 1; /* changed in Errata SSPC-135-2004 */ TokenCount = 1; /* changed in Errata SSPC-135-2004 */
EventCount = 0; EventCount = 0;
@@ -959,8 +953,8 @@ static bool MSTP_Master_Node_FSM(
/* RetrySendToken */ /* RetrySendToken */
RetryCount++; RetryCount++;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
EventCount = 0; EventCount = 0;
/* re-enter the current state to listen for NS */ /* re-enter the current state to listen for NS */
/* to begin using the token. */ /* to begin using the token. */
@@ -1024,15 +1018,15 @@ static bool MSTP_Master_Node_FSM(
/* a successor node. */ /* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (MSTP_Flag.ReceivedValidFrame == true) { if (MSTP_Flag.ReceivedValidFrame == true) {
if ((DestinationAddress == This_Station) if ((DestinationAddress == This_Station) &&
&& (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */ /* ReceivedReplyToPFM */
MSTP_Flag.SoleMaster = false; MSTP_Flag.SoleMaster = false;
Next_Station = SourceAddress; Next_Station = SourceAddress;
EventCount = 0; EventCount = 0;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
Poll_Station = This_Station; Poll_Station = This_Station;
TokenCount = 0; TokenCount = 0;
RetryCount = 0; RetryCount = 0;
@@ -1097,8 +1091,7 @@ static bool MSTP_Master_Node_FSM(
case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST: case MSTP_MASTER_STATE_ANSWER_DATA_REQUEST:
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched = dlmstp_compare_data_expecting_reply(&InputBuffer[0],
dlmstp_compare_data_expecting_reply(&InputBuffer[0],
DataLength, SourceAddress, &pkt->buffer[0], pkt->length, DataLength, SourceAddress, &pkt->buffer[0], pkt->length,
pkt->destination_mac); pkt->destination_mac);
} else { } else {
@@ -1150,8 +1143,7 @@ static bool MSTP_Master_Node_FSM(
return transition_now; return transition_now;
} }
static void MSTP_Slave_Node_FSM( static void MSTP_Slave_Node_FSM(void)
void)
{ {
/* packet from the PDU Queue */ /* packet from the PDU Queue */
struct mstp_pdu_packet *pkt; struct mstp_pdu_packet *pkt;
@@ -1186,8 +1178,7 @@ static void MSTP_Slave_Node_FSM(
} else if (MSTP_Flag.ReceivePacketPending) { } else if (MSTP_Flag.ReceivePacketPending) {
if (!Ringbuf_Empty(&PDU_Queue)) { if (!Ringbuf_Empty(&PDU_Queue)) {
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
matched = matched = dlmstp_compare_data_expecting_reply(&InputBuffer[0],
dlmstp_compare_data_expecting_reply(&InputBuffer[0],
DataLength, SourceAddress, &pkt->buffer[0], pkt->length, DataLength, SourceAddress, &pkt->buffer[0], pkt->length,
pkt->destination_mac); pkt->destination_mac);
if (matched) { if (matched) {
@@ -1222,8 +1213,7 @@ static void MSTP_Slave_Node_FSM(
} }
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu( int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -1254,8 +1244,7 @@ int dlmstp_send_pdu(
} }
/* Return the length of the packet */ /* Return the length of the packet */
uint16_t dlmstp_receive( uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -1302,8 +1291,7 @@ uint16_t dlmstp_receive(
return pdu_len; return pdu_len;
} }
void dlmstp_set_mac_address( void dlmstp_set_mac_address(uint8_t mac_address)
uint8_t mac_address)
{ {
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
@@ -1320,8 +1308,7 @@ void dlmstp_set_mac_address(
return; return;
} }
uint8_t dlmstp_mac_address( uint8_t dlmstp_mac_address(void)
void)
{ {
return This_Station; return This_Station;
} }
@@ -1333,8 +1320,7 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */ /* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(uint8_t max_info_frames)
uint8_t max_info_frames)
{ {
if (max_info_frames >= 1) { if (max_info_frames >= 1) {
Nmax_info_frames = max_info_frames; Nmax_info_frames = max_info_frames;
@@ -1348,8 +1334,7 @@ void dlmstp_set_max_info_frames(
return; return;
} }
uint8_t dlmstp_max_info_frames( uint8_t dlmstp_max_info_frames(void)
void)
{ {
return Nmax_info_frames; return Nmax_info_frames;
} }
@@ -1359,8 +1344,7 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */ /* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
void dlmstp_set_max_master( void dlmstp_set_max_master(uint8_t max_master)
uint8_t max_master)
{ {
if (max_master <= 127) { if (max_master <= 127) {
if (This_Station <= max_master) { if (This_Station <= max_master) {
@@ -1376,14 +1360,12 @@ void dlmstp_set_max_master(
return; return;
} }
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void)
void)
{ {
return Nmax_master; return Nmax_master;
} }
void dlmstp_get_my_address( void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
@@ -1398,8 +1380,7 @@ void dlmstp_get_my_address(
return; return;
} }
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
+30 -24
View File
@@ -1,39 +1,42 @@
/* ---------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------
*/
/* ATMEL Microcontroller Software Support - ROUSSET - */ /* ATMEL Microcontroller Software Support - ROUSSET - */
/* ---------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------
*/
/* The software is delivered "AS IS" without warranty or condition of any */ /* The software is delivered "AS IS" without warranty or condition of any */
/* kind, either express, implied or statutory. This includes without */ /* kind, either express, implied or statutory. This includes without */
/* limitation any warranty or condition with respect to merchantability or */ /* limitation any warranty or condition with respect to merchantability or */
/* fitness for any particular purpose, or against the infringements of */ /* fitness for any particular purpose, or against the infringements of */
/* intellectual property rights of others. */ /* intellectual property rights of others. */
/* ---------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------
*/
/* File Name : Cstartup_SAM7.c */ /* File Name : Cstartup_SAM7.c */
/* Object : Low level initializations written in C for IAR tools */ /* Object : Low level initializations written in C for IAR tools
*/
/* 1.0 08/Sep/04 JPP : Creation */ /* 1.0 08/Sep/04 JPP : Creation */
/* 1.10 10/Sep/04 JPP : Update AT91C_CKGR_PLLCOUNT filed */ /* 1.10 10/Sep/04 JPP : Update AT91C_CKGR_PLLCOUNT filed */
/* ---------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------
*/
/* Include the board file description */ /* Include the board file description */
#include "board.h" #include "board.h"
/* The following functions must be write in ARM mode this function called directly */ /* The following functions must be write in ARM mode this function called
* directly */
/* by exception vector */ /* by exception vector */
extern void AT91F_Spurious_handler( extern void AT91F_Spurious_handler(void);
void); extern void AT91F_Default_IRQ_handler(void);
extern void AT91F_Default_IRQ_handler( extern void AT91F_Default_FIQ_handler(void);
void);
extern void AT91F_Default_FIQ_handler(
void);
/**---------------------------------------------------------------------------- */ /**----------------------------------------------------------------------------
*/
/** \fn AT91F_LowLevelInit */ /** \fn AT91F_LowLevelInit */
/** \brief This function performs very low level HW initialization */ /** \brief This function performs very low level HW initialization */
/** this function can be use a Stack, depending the compilation */ /** this function can be use a Stack, depending the compilation */
/** optimization mode */ /** optimization mode */
/**---------------------------------------------------------------------------- */ /**----------------------------------------------------------------------------
void LowLevelInit( */
void) void LowLevelInit(void)
{ {
int i; int i;
AT91PS_PMC pPMC = AT91C_BASE_PMC; AT91PS_PMC pPMC = AT91C_BASE_PMC;
@@ -57,7 +60,8 @@ void LowLevelInit(
pPMC->PMC_MOR = ((AT91C_CKGR_OSCOUNT & (0x06 << 8)) | AT91C_CKGR_MOSCEN); pPMC->PMC_MOR = ((AT91C_CKGR_OSCOUNT & (0x06 << 8)) | AT91C_CKGR_MOSCEN);
/* Wait the startup time */ /* Wait the startup time */
while (!(pPMC->PMC_SR & AT91C_PMC_MOSCS)); while (!(pPMC->PMC_SR & AT91C_PMC_MOSCS))
;
/* PMC Clock Generator PLL Register setup */ /* PMC Clock Generator PLL Register setup */
/* */ /* */
@@ -65,9 +69,11 @@ void LowLevelInit(
/* MUL = 72 */ /* MUL = 72 */
/* PLLCOUNT = 10 */ /* PLLCOUNT = 10 */
/* */ /* */
/* Main Clock (MAINCK from crystal oscillator) = 18432000 hz (see AT91SAM7-EK schematic) */ /* Main Clock (MAINCK from crystal oscillator) = 18432000 hz (see
* AT91SAM7-EK schematic) */
/* MAINCK / DIV = 18432000/14 = 1316571 hz */ /* MAINCK / DIV = 18432000/14 = 1316571 hz */
/* PLLCK = 1316571 * (MUL + 1) = 1316571 * (72 + 1) = 1316571 * 73 = 96109683 hz */ /* PLLCK = 1316571 * (MUL + 1) = 1316571 * (72 + 1) = 1316571 * 73 =
* 96109683 hz */
/* */ /* */
/* PLLCOUNT = number of slow clock cycles before the LOCK bit is set */ /* PLLCOUNT = number of slow clock cycles before the LOCK bit is set */
/* in PMC_SR after CKGR_PLLR is written. */ /* in PMC_SR after CKGR_PLLR is written. */
@@ -76,12 +82,12 @@ void LowLevelInit(
/* */ /* */
/* OUT = 0 (not used) */ /* OUT = 0 (not used) */
/* result: AT91C_CKGR_PLLR = 0x00000000480A0E (PLL Register) */ /* result: AT91C_CKGR_PLLR = 0x00000000480A0E (PLL Register) */
pPMC->PMC_PLLR = pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) |
((AT91C_CKGR_DIV & 14) | (AT91C_CKGR_PLLCOUNT & (10 << 8)) | (AT91C_CKGR_PLLCOUNT & (10 << 8)) | (AT91C_CKGR_MUL & (72 << 16)));
(AT91C_CKGR_MUL & (72 << 16)));
/* Wait the startup time (until PMC Status register LOCK bit is set) */ /* Wait the startup time (until PMC Status register LOCK bit is set) */
while (!(pPMC->PMC_SR & AT91C_PMC_LOCK)); while (!(pPMC->PMC_SR & AT91C_PMC_LOCK))
;
/* PMC Master Clock (MCK) Register setup */ /* PMC Master Clock (MCK) Register setup */
/* */ /* */
+25 -17
View File
@@ -1,32 +1,40 @@
/* The following functions must be written in ARM mode */ /* The following functions must be written in ARM mode */
/* these functions are called directly by an exception vector */ /* these functions are called directly by an exception vector */
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
*/
/* Internal functions */ /* Internal functions */
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
/*------------------------------------------------------------------------------ */ */
/*------------------------------------------------------------------------------
*/
/* Default spurious interrupt handler. Infinite loop. */ /* Default spurious interrupt handler. Infinite loop. */
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
void AT91F_Spurious_handler( */
void) void AT91F_Spurious_handler(void)
{ {
while (1); while (1)
;
} }
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
*/
/* Default handler for fast interrupt requests. Infinite loop. */ /* Default handler for fast interrupt requests. Infinite loop. */
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
void AT91F_Default_FIQ_handler( */
void) void AT91F_Default_FIQ_handler(void)
{ {
while (1); while (1)
;
} }
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
*/
/* Default handler for standard interrupt requests. Infinite loop. */ /* Default handler for standard interrupt requests. Infinite loop. */
/*------------------------------------------------------------------------------ */ /*------------------------------------------------------------------------------
void AT91F_Default_IRQ_handler( */
void) void AT91F_Default_IRQ_handler(void)
{ {
while (1); while (1)
;
} }
+17 -22
View File
@@ -1,4 +1,5 @@
/* ********************************************************************************************** */ /* **********************************************************************************************
*/
/* */ /* */
/* File Name : isr.c */ /* File Name : isr.c */
/* Title : interrupt enable/disable functions */ /* Title : interrupt enable/disable functions */
@@ -12,10 +13,13 @@
/* notice remains intact. */ /* notice remains intact. */
/* */ /* */
/* Note from Jim Lynch: */ /* Note from Jim Lynch: */
/* This module was developed by Bill Knight, RO Software and used with his permission. */ /* This module was developed by Bill Knight, RO Software and used with his
* permission. */
/* Taken from the Yahoo LPC2000 User's Group - Files Section 'UT050418A.ZIP' */ /* Taken from the Yahoo LPC2000 User's Group - Files Section 'UT050418A.ZIP' */
/* Specifically, the module armVIC.c with the include file references removed */ /* Specifically, the module armVIC.c with the include file references removed
/* ********************************************************************************************** */ */
/* **********************************************************************************************
*/
#include "at91sam7s256.h" #include "at91sam7s256.h"
#include "isr.h" #include "isr.h"
@@ -23,23 +27,19 @@
#define FIQ_MASK 0x00000040 #define FIQ_MASK 0x00000040
#define INT_MASK (IRQ_MASK | FIQ_MASK) #define INT_MASK (IRQ_MASK | FIQ_MASK)
static inline unsigned __get_cpsr( static inline unsigned __get_cpsr(void)
void)
{ {
unsigned long retval; unsigned long retval;
asm volatile(" mrs %0, cpsr" : "=r"(retval) : /* no inputs */); asm volatile(" mrs %0, cpsr" : "=r"(retval) : /* no inputs */);
return retval; return retval;
} }
static inline void __set_cpsr( static inline void __set_cpsr(unsigned val)
unsigned val)
{ {
asm volatile ( asm volatile(" msr cpsr, %0" : /* no outputs */ : "r"(val));
" msr cpsr, %0": /* no outputs */ :"r" (val));
} }
unsigned disableIRQ( unsigned disableIRQ(void)
void)
{ {
unsigned _cpsr; unsigned _cpsr;
_cpsr = __get_cpsr(); _cpsr = __get_cpsr();
@@ -47,8 +47,7 @@ unsigned disableIRQ(
return _cpsr; return _cpsr;
} }
unsigned restoreIRQ( unsigned restoreIRQ(unsigned oldCPSR)
unsigned oldCPSR)
{ {
unsigned _cpsr; unsigned _cpsr;
@@ -57,8 +56,7 @@ unsigned restoreIRQ(
return _cpsr; return _cpsr;
} }
unsigned enableIRQ( unsigned enableIRQ(void)
void)
{ {
unsigned _cpsr; unsigned _cpsr;
@@ -67,8 +65,7 @@ unsigned enableIRQ(
return _cpsr; return _cpsr;
} }
unsigned disableFIQ( unsigned disableFIQ(void)
void)
{ {
unsigned _cpsr; unsigned _cpsr;
@@ -77,8 +74,7 @@ unsigned disableFIQ(
return _cpsr; return _cpsr;
} }
unsigned restoreFIQ( unsigned restoreFIQ(unsigned oldCPSR)
unsigned oldCPSR)
{ {
unsigned _cpsr; unsigned _cpsr;
@@ -87,8 +83,7 @@ unsigned restoreFIQ(
return _cpsr; return _cpsr;
} }
unsigned enableFIQ( unsigned enableFIQ(void)
void)
{ {
unsigned _cpsr; unsigned _cpsr;
+16 -24
View File
@@ -48,12 +48,9 @@
/* ******************************************************* */ /* ******************************************************* */
/* FIXME: use header files? External References */ /* FIXME: use header files? External References */
/* ******************************************************* */ /* ******************************************************* */
extern void LowLevelInit( extern void LowLevelInit(void);
void); extern unsigned enableIRQ(void);
extern unsigned enableIRQ( extern unsigned enableFIQ(void);
void);
extern unsigned enableFIQ(
void);
/* used by crt.s file */ /* used by crt.s file */
unsigned FiqCount = 0; unsigned FiqCount = 0;
@@ -64,8 +61,7 @@ static unsigned long LED_Timer_3 = 0;
static unsigned long LED_Timer_4 = 1000; static unsigned long LED_Timer_4 = 1000;
static unsigned long DCC_Timer = 1000; static unsigned long DCC_Timer = 1000;
static inline void millisecond_timer( static inline void millisecond_timer(void)
void)
{ {
while (Timer_Milliseconds) { while (Timer_Milliseconds) {
Timer_Milliseconds--; Timer_Milliseconds--;
@@ -88,8 +84,7 @@ static inline void millisecond_timer(
/* note: MS/TP silence timer is updated in ISR */ /* note: MS/TP silence timer is updated in ISR */
} }
static inline void init( static inline void init(void)
void)
{ {
unsigned int pcsr; unsigned int pcsr;
@@ -133,8 +128,7 @@ static inline void init(
pAIC->AIC_IECR = (1 << AT91C_ID_FIQ); pAIC->AIC_IECR = (1 << AT91C_ID_FIQ);
} }
static inline void bacnet_init( static inline void bacnet_init(void)
void)
{ {
#if defined(BACDL_MSTP) #if defined(BACDL_MSTP)
uint8_t MAC_Address = 0x55; uint8_t MAC_Address = 0x55;
@@ -149,29 +143,27 @@ static inline void bacnet_init(
/* initialize objects */ /* initialize objects */
Device_Init(NULL); Device_Init(NULL);
/* set up our confirmed service unrecognized service handler - required! */ /* set up our confirmed service unrecognized service handler - required! */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* we need to handle who-is to support dynamic device binding */ /* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(
handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, apdu_set_confirmed_handler(
handler_read_property_multiple); SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, apdu_set_confirmed_handler(
handler_reinitialize_device); SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, apdu_set_confirmed_handler(
handler_write_property); SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
} }
static uint8_t Receive_PDU[MAX_MPDU]; /* PDU data */ static uint8_t Receive_PDU[MAX_MPDU]; /* PDU data */
int main( int main(void)
void)
{ {
unsigned long IdleCount = 0; /* idle loop blink counter */ unsigned long IdleCount = 0; /* idle loop blink counter */
bool LED1_Off_Enabled = true; bool LED1_Off_Enabled = true;
+12 -22
View File
@@ -62,8 +62,7 @@ static int RS485_Baud = 38400;
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Initialize( void RS485_Initialize(void)
void)
{ {
unsigned int pcsr; unsigned int pcsr;
/* Enable the USART0 clock in the Power Management Controller */ /* Enable the USART0 clock in the Power Management Controller */
@@ -87,7 +86,8 @@ void RS485_Initialize(
AT91C_US_RXDIS | /* Receiver Disable */ AT91C_US_RXDIS | /* Receiver Disable */
AT91C_US_TXDIS; /* Transmitter Disable */ AT91C_US_TXDIS; /* Transmitter Disable */
RS485_Interface->US_MR = AT91C_US_USMODE_RS485 | /* RS-485 Mode - RTS auto assert */ RS485_Interface->US_MR =
AT91C_US_USMODE_RS485 | /* RS-485 Mode - RTS auto assert */
AT91C_US_CLKS_CLOCK | /* Clock = MCK */ AT91C_US_CLKS_CLOCK | /* Clock = MCK */
AT91C_US_CHRL_8_BITS | /* 8-bit Data */ AT91C_US_CHRL_8_BITS | /* 8-bit Data */
AT91C_US_PAR_NONE | /* No Parity */ AT91C_US_PAR_NONE | /* No Parity */
@@ -108,10 +108,8 @@ void RS485_Initialize(
return; return;
} }
void RS485_Cleanup( void RS485_Cleanup(void)
void)
{ {
} }
/**************************************************************************** /****************************************************************************
@@ -120,8 +118,7 @@ void RS485_Cleanup(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(void)
void)
{ {
return RS485_Baud; return RS485_Baud;
} }
@@ -132,8 +129,7 @@ uint32_t RS485_Get_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(uint32_t baud)
uint32_t baud)
{ {
bool valid = true; bool valid = true;
@@ -162,8 +158,7 @@ bool RS485_Set_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Turnaround_Delay( void RS485_Turnaround_Delay(void)
void)
{ {
uint16_t turnaround_time; uint16_t turnaround_time;
@@ -182,8 +177,7 @@ void RS485_Turnaround_Delay(
* ALGORITHM: none * ALGORITHM: none
* NOTES: The Atmel ARM7 has an automatic enable/disable in RS485 mode. * NOTES: The Atmel ARM7 has an automatic enable/disable in RS485 mode.
*****************************************************************************/ *****************************************************************************/
void RS485_Transmitter_Enable( void RS485_Transmitter_Enable(bool enable)
bool enable)
{ {
(void)enable; (void)enable;
} }
@@ -194,8 +188,7 @@ void RS485_Transmitter_Enable(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Send_Data( void RS485_Send_Data(uint8_t *buffer, /* data to send */
uint8_t * buffer, /* data to send */
uint16_t nbytes) uint16_t nbytes)
{ /* number of bytes of data */ { /* number of bytes of data */
/* LED on send */ /* LED on send */
@@ -224,8 +217,7 @@ void RS485_Send_Data(
* ALGORITHM: none * ALGORITHM: none
* NOTES: Clears any error flags. * NOTES: Clears any error flags.
*****************************************************************************/ *****************************************************************************/
bool RS485_ReceiveError( bool RS485_ReceiveError(void)
void)
{ {
bool ReceiveError = false; bool ReceiveError = false;
/* LED on send */ /* LED on send */
@@ -249,8 +241,7 @@ bool RS485_ReceiveError(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_DataAvailable( bool RS485_DataAvailable(uint8_t *DataRegister)
uint8_t * DataRegister)
{ {
bool DataAvailable = false; bool DataAvailable = false;
/* LED on send */ /* LED on send */
@@ -270,8 +261,7 @@ bool RS485_DataAvailable(
} }
#ifdef TEST_RS485 #ifdef TEST_RS485
int main( int main(void)
void)
{ {
unsigned i = 0; unsigned i = 0;
uint8_t DataRegister; uint8_t DataRegister;
+90 -57
View File
@@ -1,4 +1,5 @@
/* ***************************************************************************** */ /* *****************************************************************************
*/
/* */ /* */
/* Purpose: Set up the 16-bit Timer/Counter */ /* Purpose: Set up the 16-bit Timer/Counter */
/* */ /* */
@@ -34,8 +35,8 @@
/* Modified by Steve Karg */ /* Modified by Steve Karg */
/* Changed timer to 1ms. */ /* Changed timer to 1ms. */
/* Encapsulated the intialization */ /* Encapsulated the intialization */
/* ***************************************************************************** */ /* *****************************************************************************
*/
/********************************************************** /**********************************************************
Header files Header files
@@ -50,18 +51,21 @@ volatile unsigned long Timer_Milliseconds;
/* MS/TP Silence Timer */ /* MS/TP Silence Timer */
static volatile int SilenceTime; static volatile int SilenceTime;
static void Timer0_Setup( static void Timer0_Setup(int milliseconds)
int milliseconds)
{ {
/* TC Block Control Register TC_BCR (read/write) */ /* TC Block Control Register TC_BCR (read/write) */
/* */ /* */
/* |------------------------------------------------------------------|------| */ /* |------------------------------------------------------------------|------|
*/
/* | SYNC | */ /* | SYNC | */
/* |------------------------------------------------------------------|------| */ /* |------------------------------------------------------------------|------|
/* 31 1 0 */ */
/* 31 1 0
*/
/* */ /* */
/* SYNC = 0 (no effect) <===== take default */ /* SYNC = 0 (no effect) <===== take default */
/* SYNC = 1 (generate software trigger for all 3 timer channels simultaneously) */ /* SYNC = 1 (generate software trigger for all 3 timer channels
* simultaneously) */
/* */ /* */
/* create a pointer to TC Global Register structure */ /* create a pointer to TC Global Register structure */
AT91PS_TCB pTCB = AT91C_BASE_TCB; AT91PS_TCB pTCB = AT91C_BASE_TCB;
@@ -70,9 +74,12 @@ static void Timer0_Setup(
/* TC Block Mode Register TC_BMR (read/write) */ /* TC Block Mode Register TC_BMR (read/write) */
/* */ /* */
/* |-------------------------------------|-----------|-----------|-----------| */ /* |-------------------------------------|-----------|-----------|-----------|
/* | TC2XC2S TCXC1S TC0XC0S | */ */
/* |-------------------------------------|-----------|-----------|-----------| */ /* | TC2XC2S TCXC1S TC0XC0S
* | */
/* |-------------------------------------|-----------|-----------|-----------|
*/
/* 31 5 4 3 2 1 0 */ /* 31 5 4 3 2 1 0 */
/* */ /* */
/* TC0XC0S Select = 00 TCLK0 (PA4) */ /* TC0XC0S Select = 00 TCLK0 (PA4) */
@@ -93,13 +100,16 @@ static void Timer0_Setup(
/* external clocks not used */ /* external clocks not used */
pTCB->TCB_BMR = 0x15; pTCB->TCB_BMR = 0x15;
/* TC Channel Control Register TC_CCR (read/write) */ /* TC Channel Control Register TC_CCR (read/write) */
/* */ /* */
/* |----------------------------------|--------------|------------|-----------| */ /* |----------------------------------|--------------|------------|-----------|
/* | SWTRG CLKDIS CLKENS | */ */
/* |----------------------------------|--------------|------------|-----------| */ /* | SWTRG CLKDIS CLKENS
/* 31 2 1 0 */ * | */
/* |----------------------------------|--------------|------------|-----------|
*/
/* 31 2 1 0
*/
/* */ /* */
/* CLKEN = 0 no effect */ /* CLKEN = 0 no effect */
/* CLKEN = 1 enables the clock <===== we select this one */ /* CLKEN = 1 enables the clock <===== we select this one */
@@ -108,7 +118,8 @@ static void Timer0_Setup(
/* CLKDIS = 1 disables the clock */ /* CLKDIS = 1 disables the clock */
/* */ /* */
/* SWTRG = 0 no effect */ /* SWTRG = 0 no effect */
/* SWTRG = 1 software trigger aserted counter reset and clock starts <===== we select this one */ /* SWTRG = 1 software trigger aserted counter reset and clock starts
* <===== we select this one */
/* */ /* */
/* create a pointer to channel 0 Register structure */ /* create a pointer to channel 0 Register structure */
AT91PS_TC pTC = AT91C_BASE_TC0; AT91PS_TC pTC = AT91C_BASE_TC0;
@@ -137,27 +148,32 @@ static void Timer0_Setup(
/* 001 TIMER_CLOCK2 (MCK/8 = 6006855 hz) */ /* 001 TIMER_CLOCK2 (MCK/8 = 6006855 hz) */
/* 010 TIMER_CLOCK3 (MCK/32 = 1501713 hz) */ /* 010 TIMER_CLOCK3 (MCK/32 = 1501713 hz) */
/* 011 TIMER_CLOCK4 (MCK/128 = 375428 hz) */ /* 011 TIMER_CLOCK4 (MCK/128 = 375428 hz) */
/* 100 TIMER_CLOCK5 (MCK/1024 = 46928 hz) <===== we select this one */ /* 100 TIMER_CLOCK5 (MCK/1024 = 46928 hz) <===== we
* select this one */
/* 101 XC0 */ /* 101 XC0 */
/* 101 XC1 */ /* 101 XC1 */
/* 101 XC2 */ /* 101 XC2 */
/* */ /* */
/* CLOCK INVERT */ /* CLOCK INVERT */
/* CLKI = 0 counter incremented on rising clock edge <===== we select this one */ /* CLKI = 0 counter incremented on rising clock edge <===== we
* select this one */
/* CLKI = 1 counter incremented on falling clock edge */ /* CLKI = 1 counter incremented on falling clock edge */
/* */ /* */
/* BURST SIGNAL SELECTION */ /* BURST SIGNAL SELECTION */
/* BURST = 00 clock is not gated by any external system <===== take default */ /* BURST = 00 clock is not gated by any external system <===== take
* default */
/* 01 XC0 is anded with the clock */ /* 01 XC0 is anded with the clock */
/* 10 XC1 is anded with the clock */ /* 10 XC1 is anded with the clock */
/* 11 XC2 is anded with the clock */ /* 11 XC2 is anded with the clock */
/* */ /* */
/* COUNTER CLOCK STOPPED WITH RB LOADING */ /* COUNTER CLOCK STOPPED WITH RB LOADING */
/* LDBSTOP = 0 counter clock is not stopped when RB loading occurs <===== take default */ /* LDBSTOP = 0 counter clock is not stopped when RB loading occurs
* <===== take default */
/* = 1 counter clock is stopped when RB loading occur */ /* = 1 counter clock is stopped when RB loading occur */
/* */ /* */
/* COUNTER CLOCK DISABLE WITH RB LOADING */ /* COUNTER CLOCK DISABLE WITH RB LOADING */
/* LDBDIS = 0 counter clock is not disabled when RB loading occurs <===== take default */ /* LDBDIS = 0 counter clock is not disabled when RB loading occurs
* <===== take default */
/* = 1 counter clock is disabled when RB loading occurs */ /* = 1 counter clock is disabled when RB loading occurs */
/* */ /* */
/* EXTERNAL TRIGGER EDGE SELECTION */ /* EXTERNAL TRIGGER EDGE SELECTION */
@@ -172,7 +188,8 @@ static void Timer0_Setup(
/* */ /* */
/* RC COMPARE TRIGGER ENABLE */ /* RC COMPARE TRIGGER ENABLE */
/* CPCTRG = 0 (RC Compare has no effect on the counter and its clock) */ /* CPCTRG = 0 (RC Compare has no effect on the counter and its clock) */
/* 1 (RC Compare resets the counter and starts the clock) <===== we select this one */ /* 1 (RC Compare resets the counter and starts the clock)
* <===== we select this one */
/* */ /* */
/* WAVE */ /* WAVE */
/* WAVE = 0 Capture Mode is enabled <===== we select this one */ /* WAVE = 0 Capture Mode is enabled <===== we select this one */
@@ -195,11 +212,14 @@ static void Timer0_Setup(
/* WAVE = 0 (Capture mode enabled) */ /* WAVE = 0 (Capture mode enabled) */
pTC->TC_CMR = 0x4004; pTC->TC_CMR = 0x4004;
/* TC Register C TC_RC (read/write) Compare Register 16-bits */ /* TC Register C TC_RC (read/write) Compare Register 16-bits
*/
/* */ /* */
/* |----------------------------------|----------------------------------------| */ /* |----------------------------------|----------------------------------------|
*/
/* | not used RC | */ /* | not used RC | */
/* |----------------------------------|----------------------------------------| */ /* |----------------------------------|----------------------------------------|
*/
/* 31 16 15 0 */ /* 31 16 15 0 */
/* */ /* */
/* Timer Calculation: What count gives 1 msec time-out? */ /* Timer Calculation: What count gives 1 msec time-out? */
@@ -221,10 +241,14 @@ static void Timer0_Setup(
/* TC Interrupt Enable Register TC_IER (write-only) */ /* TC Interrupt Enable Register TC_IER (write-only) */
/* */ /* */
/* */ /* */
/* |------------|-------|-------|-------|-------|--------|--------|--------|--------| */ /* |------------|-------|-------|-------|-------|--------|--------|--------|--------|
/* | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS COVFS | */ */
/* |------------|-------|-------|-------|-------|--------|--------|--------|--------| */ /* | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS
/* 31 8 7 6 5 4 3 2 1 0 */ * COVFS | */
/* |------------|-------|-------|-------|-------|--------|--------|--------|--------|
*/
/* 31 8 7 6 5 4 3 2 1
* 0 */
/* */ /* */
/* COVFS = 0 no effect <===== take default */ /* COVFS = 0 no effect <===== take default */
/* 1 enable counter overflow interrupt */ /* 1 enable counter overflow interrupt */
@@ -239,7 +263,8 @@ static void Timer0_Setup(
/* 1 enable RB compare interrupt */ /* 1 enable RB compare interrupt */
/* */ /* */
/* CPCS = 0 no effect */ /* CPCS = 0 no effect */
/* 1 enable RC compare interrupt <===== we select this one */ /* 1 enable RC compare interrupt <===== we select this one
*/
/* */ /* */
/* LDRAS = 0 no effect <===== take default */ /* LDRAS = 0 no effect <===== take default */
/* 1 enable RA load interrupt */ /* 1 enable RA load interrupt */
@@ -256,22 +281,30 @@ static void Timer0_Setup(
/* TC Interrupt Disable Register TC_IDR (write-only) */ /* TC Interrupt Disable Register TC_IDR (write-only) */
/* */ /* */
/* */ /* */
/* |------------|-------|-------|-------|-------|--------|--------|--------|--------| */ /* |------------|-------|-------|-------|-------|--------|--------|--------|--------|
/* | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS COVFS | */ */
/* |------------|-------|-------|-------|-------|--------|--------|--------|--------| */ /* | ETRGS LDRBS LDRAS CPCS CPBS CPAS LOVRS
/* 31 8 7 6 5 4 3 2 1 0 */ * COVFS | */
/* |------------|-------|-------|-------|-------|--------|--------|--------|--------|
*/
/* 31 8 7 6 5 4 3 2 1
* 0 */
/* */ /* */
/* COVFS = 0 no effect */ /* COVFS = 0 no effect */
/* 1 disable counter overflow interrupt <===== we select this one */ /* 1 disable counter overflow interrupt <===== we select
* this one */
/* */ /* */
/* LOVRS = 0 no effect */ /* LOVRS = 0 no effect */
/* 1 disable load overrun interrupt <===== we select this one */ /* 1 disable load overrun interrupt <===== we select this
* one */
/* */ /* */
/* CPAS = 0 no effect */ /* CPAS = 0 no effect */
/* 1 disable RA compare interrupt <===== we select this one */ /* 1 disable RA compare interrupt <===== we select this one
*/
/* */ /* */
/* CPBS = 0 no effect */ /* CPBS = 0 no effect */
/* 1 disable RB compare interrupt <===== we select this one */ /* 1 disable RB compare interrupt <===== we select this one
*/
/* */ /* */
/* CPCS = 0 no effect <===== take default */ /* CPCS = 0 no effect <===== take default */
/* 1 disable RC compare interrupt */ /* 1 disable RC compare interrupt */
@@ -283,13 +316,15 @@ static void Timer0_Setup(
/* 1 disable RB load interrupt <===== we select this one */ /* 1 disable RB load interrupt <===== we select this one */
/* */ /* */
/* ETRGS = 0 no effect */ /* ETRGS = 0 no effect */
/* 1 disable External Trigger interrupt <===== we select this one */ /* 1 disable External Trigger interrupt <===== we select
* this one */
/* */ /* */
/* disable all except RC compare interrupt */ /* disable all except RC compare interrupt */
pTC->TC_IDR = 0xEF; pTC->TC_IDR = 0xEF;
} }
/* ***************************************************************************** */ /* *****************************************************************************
*/
/* */ /* */
/* Timer 0 Interrupt Service Routine */ /* Timer 0 Interrupt Service Routine */
/* */ /* */
@@ -298,12 +333,12 @@ static void Timer0_Setup(
/* Author: James P Lynch May 12, 2007 */ /* Author: James P Lynch May 12, 2007 */
/* Modified by Steve Karg */ /* Modified by Steve Karg */
/* simplified and changed to a millisecond count-up timer */ /* simplified and changed to a millisecond count-up timer */
/* ***************************************************************************** */ /* *****************************************************************************
static void Timer0IrqHandler( */
void) static void Timer0IrqHandler(void)
{ {
volatile AT91PS_TC pTC =
volatile AT91PS_TC pTC = AT91C_BASE_TC0; /* pointer to timer channel 0 register structure */ AT91C_BASE_TC0; /* pointer to timer channel 0 register structure */
volatile unsigned int dummy; /* temporary */ volatile unsigned int dummy; /* temporary */
/* read TC0 Status Register to clear interrupt */ /* read TC0 Status Register to clear interrupt */
@@ -316,19 +351,18 @@ static void Timer0IrqHandler(
(void)dummy; (void)dummy;
} }
int Timer_Silence( int Timer_Silence(void)
void)
{ {
return SilenceTime; return SilenceTime;
} }
void Timer_Silence_Reset( void Timer_Silence_Reset(void)
void)
{ {
SilenceTime = 0; SilenceTime = 0;
} }
/* ***************************************************************************** */ /* *****************************************************************************
*/
/* */ /* */
/* Timer 0 Initialization */ /* Timer 0 Initialization */
/* */ /* */
@@ -336,9 +370,9 @@ void Timer_Silence_Reset(
/* Modified by Steve Karg */ /* Modified by Steve Karg */
/* Moved timer startup code from main */ /* Moved timer startup code from main */
/* modified the peripheral clock init */ /* modified the peripheral clock init */
/* ***************************************************************************** */ /* *****************************************************************************
void TimerInit( */
void) void TimerInit(void)
{ {
unsigned int pcsr; unsigned int pcsr;
/* enable the Timer0 peripheral clock */ /* enable the Timer0 peripheral clock */
@@ -356,8 +390,7 @@ void TimerInit(
pAIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int)Timer0IrqHandler; pAIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int)Timer0IrqHandler;
/* Set the interrupt source type and priority */ /* Set the interrupt source type and priority */
/* in AIC Source Mode Register[12] */ /* in AIC Source Mode Register[12] */
pAIC->AIC_SMR[AT91C_ID_TC0] = pAIC->AIC_SMR[AT91C_ID_TC0] = (AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4);
(AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4);
/* Clear the TC0 interrupt */ /* Clear the TC0 interrupt */
/* in AIC Interrupt Clear Command Register */ /* in AIC Interrupt Clear Command Register */
pAIC->AIC_ICCR = (1 << AT91C_ID_TC0); pAIC->AIC_ICCR = (1 << AT91C_ID_TC0);
+10 -19
View File
@@ -44,8 +44,7 @@ float Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
@@ -54,29 +53,24 @@ bool Analog_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Instance_To_Index( unsigned Analog_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
return object_instance; return object_instance;
} }
char *Analog_Input_Name(uint32_t object_instance)
char *Analog_Input_Name(
uint32_t object_instance)
{ {
static char text_string[5] = "AI-0"; /* okay for single thread */ static char text_string[5] = "AI-0"; /* okay for single thread */
@@ -90,8 +84,7 @@ char *Analog_Input_Name(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object has already exists */
int Analog_Input_Encode_Property_APDU( int Analog_Input_Encode_Property_APDU(uint8_t *apdu,
uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
uint32_t array_index, uint32_t array_index,
@@ -103,21 +96,19 @@ int Analog_Input_Encode_Property_APDU(
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
unsigned object_index; unsigned object_index;
(void)array_index; (void)array_index;
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, &apdu[0], OBJECT_ANALOG_INPUT, object_instance);
object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different. You could make Description writable and different.
Note that Object-Name must be unique in this device */ Note that Object-Name must be unique in this device */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Analog_Input_Name(object_instance)); &char_string, Analog_Input_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
+7 -9
View File
@@ -41,8 +41,7 @@
#include "bacnet/bacenum.h" #include "bacnet/bacenum.h"
#include "bacnet/basic/services.h" #include "bacnet/basic/services.h"
bool apdu_service_supported( bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
BACNET_SERVICES_SUPPORTED service_supported)
{ {
bool status = false; bool status = false;
@@ -61,8 +60,7 @@ bool apdu_service_supported(
return status; return status;
} }
uint16_t apdu_decode_confirmed_service_request( uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
uint8_t * apdu, /* APDU data */
uint16_t apdu_len, uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA *service_data, BACNET_CONFIRMED_SERVICE_DATA *service_data,
uint8_t *service_choice, uint8_t *service_choice,
@@ -90,8 +88,7 @@ uint16_t apdu_decode_confirmed_service_request(
return len; return len;
} }
void apdu_handler( void apdu_handler(BACNET_ADDRESS *src,
BACNET_ADDRESS * src,
uint8_t *apdu, /* APDU data */ uint8_t *apdu, /* APDU data */
uint16_t apdu_len) uint16_t apdu_len)
{ {
@@ -105,7 +102,8 @@ void apdu_handler(
/* PDU Type */ /* PDU Type */
switch (apdu[0] & 0xF0) { switch (apdu[0] & 0xF0) {
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ len = apdu_decode_confirmed_service_request(
&apdu[0], /* APDU data */
apdu_len, &service_data, &service_choice, &service_request, apdu_len, &service_data, &service_choice, &service_request,
&service_request_len); &service_request_len);
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
@@ -114,8 +112,8 @@ void apdu_handler(
} }
#ifdef WRITE_PROPERTY #ifdef WRITE_PROPERTY
else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) { else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
handler_write_property(service_request, handler_write_property(service_request, service_request_len,
service_request_len, src, &service_data); src, &service_data);
} }
#endif #endif
else { else {
+22 -37
View File
@@ -49,8 +49,7 @@ float AV_Present_Value[MAX_ANALOG_VALUES];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
return true; return true;
@@ -60,8 +59,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(void)
void)
{ {
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
} }
@@ -69,8 +67,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -78,15 +75,13 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
return object_instance; return object_instance;
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
char *Analog_Value_Name( char *Analog_Value_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[5] = "AV-"; /* okay for single thread */ static char text_string[5] = "AV-"; /* okay for single thread */
@@ -96,8 +91,7 @@ char *Analog_Value_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Read_Property( int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -108,13 +102,12 @@ int Analog_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, &apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Analog_Value_Name(rpdata->object_instance)); &char_string, Analog_Value_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -123,11 +116,10 @@ int Analog_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
object_index = Analog_Value_Instance_To_Index( object_index =
rpdata->object_instance); Analog_Value_Instance_To_Index(rpdata->object_instance);
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], AV_Present_Value[object_index]);
AV_Present_Value[object_index]);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -154,8 +146,7 @@ int Analog_Value_Read_Property(
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) {
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -165,8 +156,7 @@ int Analog_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -179,9 +169,8 @@ bool Analog_Value_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -233,8 +222,7 @@ bool Analog_Value_Write_Property(
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
void testAnalog_Value( void testAnalog_Value(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = { 0 }; uint8_t apdu[MAX_APDU] = { 0 };
int len = 0; int len = 0;
@@ -246,14 +234,12 @@ void testAnalog_Value(
BACNET_ERROR_CLASS error_class; BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
len = len = Analog_Value_Encode_Property_APDU(&apdu[0], instance,
Analog_Value_Encode_Property_APDU(&apdu[0], instance,
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = len = decode_object_id(&apdu[len], (int *)&decoded_type, &decoded_instance);
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE);
ct_test(pTest, decoded_instance == instance); ct_test(pTest, decoded_instance == instance);
@@ -261,8 +247,7 @@ void testAnalog_Value(
} }
#ifdef TEST_ANALOG_VALUE #ifdef TEST_ANALOG_VALUE
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+20 -36
View File
@@ -47,8 +47,7 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance( bool Binary_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_VALUES) if (object_instance < MAX_BINARY_VALUES)
return true; return true;
@@ -57,22 +56,19 @@ bool Binary_Value_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Value_Count( unsigned Binary_Value_Count(void)
void)
{ {
return MAX_BINARY_VALUES; return MAX_BINARY_VALUES;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Binary_Value_Index_To_Instance( uint32_t Binary_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Value_Instance_To_Index( unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_VALUES; unsigned index = MAX_BINARY_VALUES;
@@ -82,8 +78,7 @@ unsigned Binary_Value_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Value_Present_Value( BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
@@ -95,8 +90,7 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
char *Binary_Value_Name( char *Binary_Value_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[5] = "BV-0"; /* okay for single thread */ static char text_string[5] = "BV-0"; /* okay for single thread */
@@ -109,8 +103,7 @@ char *Binary_Value_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Binary_Value_Read_Property( int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -122,15 +115,14 @@ int Binary_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, &apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Binary_Value_Name(rpdata->object_instance)); &char_string, Binary_Value_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -180,8 +172,7 @@ int Binary_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Value_Write_Property( bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -194,9 +185,8 @@ bool Binary_Value_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -216,9 +206,8 @@ bool Binary_Value_Write_Property(
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) { if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value.type.Enumerated == BINARY_ACTIVE) || if ((value.type.Enumerated == BINARY_ACTIVE) ||
(value.type.Enumerated == BINARY_INACTIVE)) { (value.type.Enumerated == BINARY_INACTIVE)) {
object_index = object_index = Binary_Value_Instance_To_Index(
Binary_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
/* NOTE: this Binary value has no priority array */ /* NOTE: this Binary value has no priority array */
Present_Value[object_index] = Present_Value[object_index] =
(BACNET_BINARY_PV)value.type.Enumerated; (BACNET_BINARY_PV)value.type.Enumerated;
@@ -277,8 +266,7 @@ bool Binary_Value_Write_Property(
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
void testBinary_Value( void testBinary_Value(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = { 0 }; uint8_t apdu[MAX_APDU] = { 0 };
int len = 0; int len = 0;
@@ -290,15 +278,12 @@ void testBinary_Value(
BACNET_ERROR_CLASS error_class; BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
len = Binary_Value_Encode_Property_APDU(&apdu[0], instance,
len =
Binary_Value_Encode_Property_APDU(&apdu[0], instance,
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = len = decode_object_id(&apdu[len], (int *)&decoded_type, &decoded_instance);
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE); ct_test(pTest, decoded_type == OBJECT_BINARY_VALUE);
ct_test(pTest, decoded_instance == instance); ct_test(pTest, decoded_instance == instance);
@@ -306,8 +291,7 @@ void testBinary_Value(
} }
#ifdef TEST_BINARY_VALUE #ifdef TEST_BINARY_VALUE
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+29 -44
View File
@@ -50,8 +50,7 @@ static uint32_t Object_Instance_Number = 260001;
static char Object_Name[20] = "My Device"; static char Object_Name[20] = "My Device";
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
void Device_Init( void Device_Init(object_functions_t *object_table)
object_functions_t * object_table)
{ {
(void)object_table; (void)object_table;
/* Reinitialize_State = BACNET_REINIT_IDLE; */ /* Reinitialize_State = BACNET_REINIT_IDLE; */
@@ -64,14 +63,12 @@ void Device_Init(
} }
/* methods to manipulate the data */ /* methods to manipulate the data */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(void)
void)
{ {
return Object_Instance_Number; return Object_Instance_Number;
} }
bool Device_Set_Object_Instance_Number( bool Device_Set_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
@@ -89,21 +86,18 @@ bool Device_Set_Object_Instance_Number(
return status; return status;
} }
bool Device_Valid_Object_Instance_Number( bool Device_Valid_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
/* BACnet allows for a wildcard instance number */ /* BACnet allows for a wildcard instance number */
return (Object_Instance_Number == object_id); return (Object_Instance_Number == object_id);
} }
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(void)
void)
{ {
return BACNET_VENDOR_ID; return BACNET_VENDOR_ID;
} }
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(void)
void)
{ {
unsigned count = 1; /* at least 1 for device object */ unsigned count = 1; /* at least 1 for device object */
@@ -115,9 +109,7 @@ unsigned Device_Object_List_Count(
} }
bool Device_Object_List_Identifier( bool Device_Object_List_Identifier(
uint32_t array_index, uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
BACNET_OBJECT_TYPE *object_type,
uint32_t * instance)
{ {
bool status = false; bool status = false;
uint32_t object_index = 0; uint32_t object_index = 0;
@@ -163,8 +155,7 @@ bool Device_Object_List_Identifier(
} }
/* return the length of the apdu encoded or -1 for error */ /* return the length of the apdu encoded or -1 for error */
int Device_Read_Property( int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
uint8_t *apdu; uint8_t *apdu;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -179,9 +170,8 @@ int Device_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_DEVICE, &apdu[0], OBJECT_DEVICE, Object_Instance_Number);
Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, Object_Name); characterstring_init_ansi(&char_string, Object_Name);
@@ -200,9 +190,8 @@ int Device_Read_Property(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_VENDOR_IDENTIFIER: case PROP_VENDOR_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Vendor_Identifier());
Device_Vendor_Identifier());
break; break;
case PROP_MODEL_NAME: case PROP_MODEL_NAME:
characterstring_init_ansi(&char_string, "GNU Demo"); characterstring_init_ansi(&char_string, "GNU Demo");
@@ -225,8 +214,7 @@ int Device_Read_Property(
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_REVISION);
BACNET_PROTOCOL_REVISION);
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */ /* Note: list of services that are executed, not initiated. */
@@ -265,9 +253,8 @@ int Device_Read_Property(
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
Device_Object_List_Identifier(i, &object_type, &instance); Device_Object_List_Identifier(i, &object_type, &instance);
len = len = encode_application_object_id(
encode_application_object_id(&apdu[apdu_len], &apdu[apdu_len], object_type, instance);
object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
@@ -280,11 +267,10 @@ int Device_Read_Property(
} }
} }
} else { } else {
if (Device_Object_List_Identifier(rpdata->array_index, if (Device_Object_List_Identifier(
&object_type, &instance)) rpdata->array_index, &object_type, &instance))
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], object_type, &apdu[0], object_type, instance);
instance);
else { else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -313,8 +299,7 @@ int Device_Read_Property(
break; break;
case PROP_MAX_INFO_FRAMES: case PROP_MAX_INFO_FRAMES:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
dlmstp_max_info_frames());
break; break;
case PROP_MAX_MASTER: case PROP_MAX_MASTER:
apdu_len = apdu_len =
@@ -347,8 +332,7 @@ int Device_Read_Property(
return apdu_len; return apdu_len;
} }
bool Device_Write_Property( bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -360,9 +344,8 @@ bool Device_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -381,8 +364,8 @@ bool Device_Write_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(value.type. (Device_Set_Object_Instance_Number(
Object_Id.instance))) { value.type.Object_Id.instance))) {
/* we could send an I-Am broadcast to let the world know */ /* we could send an I-Am broadcast to let the world know */
status = true; status = true;
} else { } else {
@@ -436,11 +419,13 @@ bool Device_Write_Property(
status = true; status = true;
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY; wp_data->error_code =
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
} }
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED; wp_data->error_code =
ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
} }
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
+79 -70
View File
@@ -165,10 +165,13 @@ static uint8_t TransmitPacketDest;
#define Treply_delay 250 #define Treply_delay 250
/* we need to be able to increment without rolling over */ /* we need to be able to increment without rolling over */
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} #define INCREMENT_AND_LIMIT_UINT8(x) \
{ \
if (x < 0xFF) \
x++; \
}
bool dlmstp_init( bool dlmstp_init(char *ifname)
char *ifname)
{ {
ifname = ifname; ifname = ifname;
/* initialize hardware */ /* initialize hardware */
@@ -177,15 +180,12 @@ bool dlmstp_init(
return true; return true;
} }
void dlmstp_cleanup( void dlmstp_cleanup(void)
void)
{ {
/* nothing to do for static buffers */ /* nothing to do for static buffers */
} }
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
BACNET_ADDRESS * src,
uint8_t mstp_address)
{ {
int i = 0; int i = 0;
@@ -212,8 +212,7 @@ void dlmstp_fill_bacnet_address(
extern bool Send_I_Am_Flag; extern bool Send_I_Am_Flag;
/* look at any of the unconfirmed message bits and encode if set */ /* look at any of the unconfirmed message bits and encode if set */
static uint16_t dlmstp_encode_unconfirmed_frame( static uint16_t dlmstp_encode_unconfirmed_frame(void)
void)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
@@ -290,8 +289,7 @@ static void MSTP_Send_Frame(
RS485_Transmitter_Enable(false); RS485_Transmitter_Enable(false);
} }
static void MSTP_Receive_Frame_FSM( static void MSTP_Receive_Frame_FSM(void)
void)
{ {
/* stores the latest received data octet */ /* stores the latest received data octet */
uint8_t DataRegister = 0; uint8_t DataRegister = 0;
@@ -305,7 +303,8 @@ static void MSTP_Receive_Frame_FSM(
switch (Receive_State) { switch (Receive_State) {
case MSTP_RECEIVE_STATE_IDLE: case MSTP_RECEIVE_STATE_IDLE:
/* In the IDLE state, the node waits for the beginning of a frame. */ /* In the IDLE state, the node waits for the beginning of a frame.
*/
if (RS485_ReceiveError()) { if (RS485_ReceiveError()) {
/* EatAnError */ /* EatAnError */
Timer_Silence_Reset(); Timer_Silence_Reset();
@@ -355,10 +354,12 @@ static void MSTP_Receive_Frame_FSM(
} }
break; break;
case MSTP_RECEIVE_STATE_HEADER: case MSTP_RECEIVE_STATE_HEADER:
/* In the HEADER state, the node waits for the fixed message header. */ /* In the HEADER state, the node waits for the fixed message header.
*/
if (Timer_Silence() > Tframe_abort) { if (Timer_Silence() > Tframe_abort) {
/* Timeout */ /* Timeout */
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
MSTP_Flag.ReceivedInvalidFrame = true; MSTP_Flag.ReceivedInvalidFrame = true;
/* wait for the start of a frame. */ /* wait for the start of a frame. */
Receive_State = MSTP_RECEIVE_STATE_IDLE; Receive_State = MSTP_RECEIVE_STATE_IDLE;
@@ -366,7 +367,8 @@ static void MSTP_Receive_Frame_FSM(
/* Error */ /* Error */
Timer_Silence_Reset(); Timer_Silence_Reset();
INCREMENT_AND_LIMIT_UINT8(EventCount); INCREMENT_AND_LIMIT_UINT8(EventCount);
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
MSTP_Flag.ReceivedInvalidFrame = true; MSTP_Flag.ReceivedInvalidFrame = true;
/* wait for the start of a frame. */ /* wait for the start of a frame. */
Receive_State = MSTP_RECEIVE_STATE_IDLE; Receive_State = MSTP_RECEIVE_STATE_IDLE;
@@ -454,10 +456,12 @@ static void MSTP_Receive_Frame_FSM(
} }
break; break;
case MSTP_RECEIVE_STATE_DATA: case MSTP_RECEIVE_STATE_DATA:
/* In the DATA state, the node waits for the data portion of a frame. */ /* In the DATA state, the node waits for the data portion of a
* frame. */
if (Timer_Silence() > Tframe_abort) { if (Timer_Silence() > Tframe_abort) {
/* Timeout */ /* Timeout */
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
MSTP_Flag.ReceivedInvalidFrame = true; MSTP_Flag.ReceivedInvalidFrame = true;
/* wait for the start of the next frame. */ /* wait for the start of the next frame. */
Receive_State = MSTP_RECEIVE_STATE_IDLE; Receive_State = MSTP_RECEIVE_STATE_IDLE;
@@ -512,15 +516,16 @@ static void MSTP_Receive_Frame_FSM(
} }
/* returns true if we need to transition immediately */ /* returns true if we need to transition immediately */
static bool MSTP_Master_Node_FSM( static bool MSTP_Master_Node_FSM(void)
void)
{ {
/* The number of frames sent by this node during a single token hold. */ /* The number of frames sent by this node during a single token hold. */
/* When this counter reaches the value Nmax_info_frames, the node must */ /* When this counter reaches the value Nmax_info_frames, the node must */
/* pass the token. */ /* pass the token. */
static uint8_t FrameCount; static uint8_t FrameCount;
/* "Next Station," the MAC address of the node to which This Station passes */ /* "Next Station," the MAC address of the node to which This Station passes
/* the token. If the Next_Station is unknown, Next_Station shall be equal to */ */
/* the token. If the Next_Station is unknown, Next_Station shall be equal to
*/
/* This_Station. */ /* This_Station. */
static uint8_t Next_Station; static uint8_t Next_Station;
/* "Poll Station," the MAC address of the node to which This Station last */ /* "Poll Station," the MAC address of the node to which This Station last */
@@ -529,7 +534,8 @@ static bool MSTP_Master_Node_FSM(
/* A counter of transmission retries used for Token and Poll For Master */ /* A counter of transmission retries used for Token and Poll For Master */
/* transmission. */ /* transmission. */
static unsigned RetryCount; static unsigned RetryCount;
/* The number of tokens received by this node. When this counter reaches the */ /* The number of tokens received by this node. When this counter reaches the
*/
/* value Npoll, the node polls the address range between TS and NS for */ /* value Npoll, the node polls the address range between TS and NS for */
/* additional master nodes. TokenCount is set to zero at the end of the */ /* additional master nodes. TokenCount is set to zero at the end of the */
/* polling process. */ /* polling process. */
@@ -612,9 +618,8 @@ static bool MSTP_Master_Node_FSM(
} }
break; break;
case FRAME_TYPE_TEST_REQUEST: case FRAME_TYPE_TEST_REQUEST:
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress,
SourceAddress, This_Station, &InputBuffer[0], This_Station, &InputBuffer[0], DataLength);
DataLength);
break; break;
case FRAME_TYPE_TEST_RESPONSE: case FRAME_TYPE_TEST_RESPONSE:
default: default:
@@ -656,8 +661,10 @@ static bool MSTP_Master_Node_FSM(
FrameCount = Nmax_info_frames; FrameCount = Nmax_info_frames;
Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN; Master_State = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
/* Any retry of the data frame shall await the next entry */ /* Any retry of the data frame shall await the next entry */
/* to the USE_TOKEN state. (Because of the length of the timeout, */ /* to the USE_TOKEN state. (Because of the length of the
/* this transition will cause the token to be passed regardless */ * timeout, */
/* this transition will cause the token to be passed regardless
*/
/* of the initial value of FrameCount.) */ /* of the initial value of FrameCount.) */
transition_now = true; transition_now = true;
} else { } else {
@@ -682,8 +689,10 @@ static bool MSTP_Master_Node_FSM(
break; break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* ReceivedReply */ /* ReceivedReply */
/* or a proprietary type that indicates a reply */ /* or a proprietary type that indicates a reply
/* indicate successful reception to the higher layers */ */
/* indicate successful reception to the higher
* layers */
MSTP_Flag.ReceivePacketPending = true; MSTP_Flag.ReceivePacketPending = true;
Master_State = Master_State =
MSTP_MASTER_STATE_DONE_WITH_TOKEN; MSTP_MASTER_STATE_DONE_WITH_TOKEN;
@@ -735,7 +744,8 @@ static bool MSTP_Master_Node_FSM(
(Next_Station != next_this_station)) { (Next_Station != next_this_station)) {
/* SoleMaster */ /* SoleMaster */
/* there are no other known master nodes to */ /* there are no other known master nodes to */
/* which the token may be sent (true master-slave operation). */ /* which the token may be sent (true master-slave
* operation). */
FrameCount = 0; FrameCount = 0;
TokenCount++; TokenCount++;
Master_State = MSTP_MASTER_STATE_USE_TOKEN; Master_State = MSTP_MASTER_STATE_USE_TOKEN;
@@ -743,13 +753,16 @@ static bool MSTP_Master_Node_FSM(
} else { } else {
/* SendToken */ /* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */ /* The comparison of NS and TS+1 eliminates the Poll For
/* if there are no addresses between TS and NS, since there is no */ * Master */
/* address at which a new master node may be found in that case. */ /* if there are no addresses between TS and NS, since there
* is no */
/* address at which a new master node may be found in that
* case. */
TokenCount++; TokenCount++;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
RetryCount = 0; RetryCount = 0;
EventCount = 0; EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN; Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
@@ -771,8 +784,8 @@ static bool MSTP_Master_Node_FSM(
/* ResetMaintenancePFM */ /* ResetMaintenancePFM */
Poll_Station = This_Station; Poll_Station = This_Station;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
RetryCount = 0; RetryCount = 0;
TokenCount = 1; /* changed in Errata SSPC-135-2004 */ TokenCount = 1; /* changed in Errata SSPC-135-2004 */
EventCount = 0; EventCount = 0;
@@ -793,7 +806,8 @@ static bool MSTP_Master_Node_FSM(
if (Timer_Silence() <= Tusage_timeout) { if (Timer_Silence() <= Tusage_timeout) {
if (EventCount > Nmin_octets) { if (EventCount > Nmin_octets) {
/* SawTokenUser */ /* SawTokenUser */
/* Assume that a frame has been sent by the new token user. */ /* Assume that a frame has been sent by the new token user.
*/
/* Enter the IDLE state to process the frame. */ /* Enter the IDLE state to process the frame. */
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;
transition_now = true; transition_now = true;
@@ -803,8 +817,8 @@ static bool MSTP_Master_Node_FSM(
/* RetrySendToken */ /* RetrySendToken */
RetryCount++; RetryCount++;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
EventCount = 0; EventCount = 0;
/* re-enter the current state to listen for NS */ /* re-enter the current state to listen for NS */
/* to begin using the token. */ /* to begin using the token. */
@@ -826,8 +840,10 @@ static bool MSTP_Master_Node_FSM(
} }
} }
break; break;
/* The NO_TOKEN state is entered if Timer_Silence() becomes greater */ /* The NO_TOKEN state is entered if Timer_Silence() becomes greater
/* than Tno_token, indicating that there has been no network activity */ */
/* than Tno_token, indicating that there has been no network
* activity */
/* for that period of time. The timeout is continued to determine */ /* for that period of time. The timeout is continued to determine */
/* whether or not this node may create a token. */ /* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN: case MSTP_MASTER_STATE_NO_TOKEN:
@@ -836,7 +852,8 @@ static bool MSTP_Master_Node_FSM(
if (EventCount > Nmin_octets) { if (EventCount > Nmin_octets) {
/* SawFrame */ /* SawFrame */
/* Some other node exists at a lower address. */ /* Some other node exists at a lower address. */
/* Enter the IDLE state to receive and process the incoming frame. */ /* Enter the IDLE state to receive and process the incoming
* frame. */
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;
transition_now = true; transition_now = true;
} }
@@ -855,7 +872,8 @@ static bool MSTP_Master_Node_FSM(
RetryCount = 0; RetryCount = 0;
TokenCount = 0; TokenCount = 0;
/* EventCount = 0; removed Addendum 135-2004d-8 */ /* EventCount = 0; removed Addendum 135-2004d-8 */
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */ /* enter the POLL_FOR_MASTER state to find a new successor
* to TS. */
Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER; Master_State = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
} }
@@ -865,15 +883,15 @@ static bool MSTP_Master_Node_FSM(
/* a successor node. */ /* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (MSTP_Flag.ReceivedValidFrame == true) { if (MSTP_Flag.ReceivedValidFrame == true) {
if ((DestinationAddress == This_Station) if ((DestinationAddress == This_Station) &&
&& (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */ /* ReceivedReplyToPFM */
MSTP_Flag.SoleMaster = false; MSTP_Flag.SoleMaster = false;
Next_Station = SourceAddress; Next_Station = SourceAddress;
EventCount = 0; EventCount = 0;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
Poll_Station = This_Station; Poll_Station = This_Station;
TokenCount = 0; TokenCount = 0;
RetryCount = 0; RetryCount = 0;
@@ -920,7 +938,8 @@ static bool MSTP_Master_Node_FSM(
/* Re-enter the current state. */ /* Re-enter the current state. */
} else { } else {
/* DeclareSoleMaster */ /* DeclareSoleMaster */
/* to indicate that this station is the only master */ /* to indicate that this station is the only master
*/
MSTP_Flag.SoleMaster = true; MSTP_Flag.SoleMaster = true;
FrameCount = 0; FrameCount = 0;
Master_State = MSTP_MASTER_STATE_USE_TOKEN; Master_State = MSTP_MASTER_STATE_USE_TOKEN;
@@ -977,8 +996,7 @@ static bool MSTP_Master_Node_FSM(
} }
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu( int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -1003,8 +1021,7 @@ int dlmstp_send_pdu(
} }
/* Return the length of the packet */ /* Return the length of the packet */
uint16_t dlmstp_receive( uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -1051,8 +1068,7 @@ uint16_t dlmstp_receive(
return pdu_len; return pdu_len;
} }
void dlmstp_set_mac_address( void dlmstp_set_mac_address(uint8_t mac_address)
uint8_t mac_address)
{ {
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
@@ -1069,8 +1085,7 @@ void dlmstp_set_mac_address(
return; return;
} }
uint8_t dlmstp_mac_address( uint8_t dlmstp_mac_address(void)
void)
{ {
return This_Station; return This_Station;
} }
@@ -1082,8 +1097,7 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */ /* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(uint8_t max_info_frames)
uint8_t max_info_frames)
{ {
if (max_info_frames >= 1) { if (max_info_frames >= 1) {
Nmax_info_frames = max_info_frames; Nmax_info_frames = max_info_frames;
@@ -1097,8 +1111,7 @@ void dlmstp_set_max_info_frames(
return; return;
} }
uint8_t dlmstp_max_info_frames( uint8_t dlmstp_max_info_frames(void)
void)
{ {
return Nmax_info_frames; return Nmax_info_frames;
} }
@@ -1108,8 +1121,7 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */ /* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
void dlmstp_set_max_master( void dlmstp_set_max_master(uint8_t max_master)
uint8_t max_master)
{ {
if (max_master <= 127) { if (max_master <= 127) {
if (This_Station <= max_master) { if (This_Station <= max_master) {
@@ -1125,14 +1137,12 @@ void dlmstp_set_max_master(
return; return;
} }
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void)
void)
{ {
return Nmax_master; return Nmax_master;
} }
void dlmstp_get_my_address( void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
@@ -1147,8 +1157,7 @@ void dlmstp_get_my_address(
return; return;
} }
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
+18 -29
View File
@@ -44,9 +44,7 @@
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */ or sets the error, and returns -1 */
int Encode_Property_APDU( int Encode_Property_APDU(uint8_t *apdu, BACNET_READ_PROPERTY_DATA *rpdata)
uint8_t * apdu,
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = -1; int apdu_len = -1;
@@ -80,8 +78,7 @@ int Encode_Property_APDU(
return apdu_len; return apdu_len;
} }
void handler_read_property( void handler_read_property(uint8_t *service_request,
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)
@@ -98,13 +95,11 @@ void handler_read_property(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
&npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
goto RP_ABORT; goto RP_ABORT;
@@ -112,38 +107,33 @@ void handler_read_property(
len = rp_decode_service_request(service_request, service_len, &data); len = rp_decode_service_request(service_request, service_len, &data);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RP_ABORT; goto RP_ABORT;
} }
/* most cases will be error */ /* most cases will be error */
ack_len = ack_len = rp_ack_encode_apdu_init(
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, &data);
service_data->invoke_id, &data);
/* FIXME: add buffer len as passed into function or use smart buffer */ /* FIXME: add buffer len as passed into function or use smart buffer */
data.error_class = ERROR_CLASS_OBJECT; data.error_class = ERROR_CLASS_OBJECT;
data.error_code = ERROR_CODE_UNKNOWN_OBJECT; data.error_code = ERROR_CODE_UNKNOWN_OBJECT;
property_len = property_len = Encode_Property_APDU(
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], &Handler_Transmit_Buffer[pdu_len + ack_len], &data);
&data);
if (property_len >= 0) { if (property_len >= 0) {
len = len = rp_ack_encode_apdu_object_property_end(
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer &Handler_Transmit_Buffer[pdu_len + property_len + ack_len]);
[pdu_len + property_len + ack_len]);
len += ack_len + property_len; len += ack_len + property_len;
} else { } else {
switch (property_len) { switch (property_len) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is
* Abort */
case BACNET_STATUS_ABORT: case BACNET_STATUS_ABORT:
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
break; break;
default: default:
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
data.error_class, data.error_code); data.error_class, data.error_code);
break; break;
@@ -151,9 +141,8 @@ void handler_read_property(
} }
RP_ABORT: RP_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
(void)bytes_sent; (void)bytes_sent;
return; return;
+3 -6
View File
@@ -40,9 +40,7 @@
bool Send_I_Am_Flag = true; bool Send_I_Am_Flag = true;
void handler_who_is( void handler_who_is(
uint8_t * service_request, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
uint16_t service_len,
BACNET_ADDRESS * src)
{ {
int len = 0; int len = 0;
int32_t low_limit = 0; int32_t low_limit = 0;
@@ -50,9 +48,8 @@ void handler_who_is(
int32_t target_device; int32_t target_device;
(void)src; (void)src;
len = len = whois_decode_service_request(
whois_decode_service_request(service_request, service_len, &low_limit, service_request, service_len, &low_limit, &high_limit);
&high_limit);
if (len == 0) { if (len == 0) {
Send_I_Am_Flag = true; Send_I_Am_Flag = true;
} else if (len != BACNET_STATUS_ERROR) { } else if (len != BACNET_STATUS_ERROR) {
+17 -26
View File
@@ -45,8 +45,7 @@
/* too big to reside on stack frame for PIC */ /* too big to reside on stack frame for PIC */
static BACNET_WRITE_PROPERTY_DATA wp_data; static BACNET_WRITE_PROPERTY_DATA wp_data;
void handler_write_property( void handler_write_property(uint8_t *service_request,
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)
@@ -62,17 +61,14 @@ void handler_write_property(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, &Handler_Transmit_Buffer[0], src, &my_address, &npdu_data);
&npdu_data);
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
} else if (service_data->segmented_message) { } else if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
} else { } else {
@@ -81,58 +77,53 @@ void handler_write_property(
switch (wp_data.object_type) { switch (wp_data.object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Write_Property(&wp_data)) { if (Device_Write_Property(&wp_data)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class, SERVICE_CONFIRMED_WRITE_PROPERTY,
wp_data.error_code); wp_data.error_class, wp_data.error_code);
} }
break; break;
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property(&wp_data)) { if (Analog_Value_Write_Property(&wp_data)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class, SERVICE_CONFIRMED_WRITE_PROPERTY,
wp_data.error_code); wp_data.error_class, wp_data.error_code);
} }
break; break;
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property(&wp_data)) { if (Binary_Value_Write_Property(&wp_data)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, wp_data.error_class, SERVICE_CONFIRMED_WRITE_PROPERTY,
wp_data.error_code); wp_data.error_class, wp_data.error_code);
} }
break; break;
default: default:
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
wp_data.error_class, wp_data.error_code); wp_data.error_class, wp_data.error_code);
break; break;
} }
} }
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], src, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
(void)bytes_sent; (void)bytes_sent;
return; return;
+5 -10
View File
@@ -45,14 +45,12 @@ const char *BACnet_Version = "1.0";
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
/* dummy function - so we can use default demo handlers */ /* dummy function - so we can use default demo handlers */
bool dcc_communication_enabled( bool dcc_communication_enabled(void)
void)
{ {
return true; return true;
} }
static void init( static void init(void)
void)
{ {
/* Initialize the Clock Prescaler for ATmega48/88/168 */ /* Initialize the Clock Prescaler for ATmega48/88/168 */
/* The default CLKPSx bits are factory set to 0011 */ /* The default CLKPSx bits are factory set to 0011 */
@@ -105,8 +103,7 @@ static void init(
__enable_interrupt(); __enable_interrupt();
} }
static void task_milliseconds( static void task_milliseconds(void)
void)
{ {
while (Timer_Milliseconds) { while (Timer_Milliseconds) {
Timer_Milliseconds--; Timer_Milliseconds--;
@@ -117,8 +114,7 @@ static void task_milliseconds(
static uint8_t Address_Switch; static uint8_t Address_Switch;
static void input_switch_read( static void input_switch_read(void)
void)
{ {
uint8_t value; uint8_t value;
static uint8_t old_value = 0; static uint8_t old_value = 0;
@@ -140,8 +136,7 @@ static void input_switch_read(
} }
static uint8_t PDUBuffer[MAX_MPDU]; static uint8_t PDUBuffer[MAX_MPDU];
int main( int main(void)
void)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
BACNET_ADDRESS src; /* source address */ BACNET_ADDRESS src; /* source address */
+12 -24
View File
@@ -51,8 +51,7 @@ static uint32_t RS485_Baud = 9600;
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Initialize( void RS485_Initialize(void)
void)
{ {
/* enable Transmit and Receive */ /* enable Transmit and Receive */
UCSR0B = _BV(TXEN0) | _BV(RXEN0); UCSR0B = _BV(TXEN0) | _BV(RXEN0);
@@ -86,8 +85,7 @@ void RS485_Initialize(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(void)
void)
{ {
return RS485_Baud; return RS485_Baud;
} }
@@ -98,8 +96,7 @@ uint32_t RS485_Get_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(uint32_t baud)
uint32_t baud)
{ {
bool valid = true; bool valid = true;
@@ -131,8 +128,7 @@ bool RS485_Set_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Transmitter_Enable( void RS485_Transmitter_Enable(bool enable)
bool enable)
{ {
if (enable) { if (enable) {
BIT_SET(PORTD, PD2); BIT_SET(PORTD, PD2);
@@ -147,8 +143,7 @@ void RS485_Transmitter_Enable(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Turnaround_Delay( void RS485_Turnaround_Delay(void)
void)
{ {
uint8_t nbytes = 4; uint8_t nbytes = 4;
@@ -176,8 +171,7 @@ void RS485_Turnaround_Delay(
* ALGORITHM: none * ALGORITHM: none
* NOTES: expected to be called once a millisecond * NOTES: expected to be called once a millisecond
*****************************************************************************/ *****************************************************************************/
void RS485_LED_Timers( void RS485_LED_Timers(void)
void)
{ {
if (LED1_Off_Timer) { if (LED1_Off_Timer) {
LED1_Off_Timer--; LED1_Off_Timer--;
@@ -199,8 +193,7 @@ void RS485_LED_Timers(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void RS485_LED1_On( static void RS485_LED1_On(void)
void)
{ {
BIT_CLEAR(PORTD, PD6); BIT_CLEAR(PORTD, PD6);
LED1_Off_Timer = 20; LED1_Off_Timer = 20;
@@ -212,8 +205,7 @@ static void RS485_LED1_On(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void RS485_LED3_On( static void RS485_LED3_On(void)
void)
{ {
BIT_CLEAR(PORTD, PD7); BIT_CLEAR(PORTD, PD7);
LED3_Off_Timer = 20; LED3_Off_Timer = 20;
@@ -225,8 +217,7 @@ static void RS485_LED3_On(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Send_Data( void RS485_Send_Data(uint8_t *buffer, /* data to send */
uint8_t * buffer, /* data to send */
uint16_t nbytes) uint16_t nbytes)
{ /* number of bytes of data */ { /* number of bytes of data */
RS485_LED3_On(); RS485_LED3_On();
@@ -256,8 +247,7 @@ void RS485_Send_Data(
* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate * ALGORITHM: autobaud - if there are a lot of errors, switch baud rate
* NOTES: Clears any error flags. * NOTES: Clears any error flags.
*****************************************************************************/ *****************************************************************************/
bool RS485_ReceiveError( bool RS485_ReceiveError(void)
void)
{ {
bool ReceiveError = false; bool ReceiveError = false;
volatile uint8_t dummy_data; volatile uint8_t dummy_data;
@@ -292,8 +282,7 @@ bool RS485_ReceiveError(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_DataAvailable( bool RS485_DataAvailable(uint8_t *data)
uint8_t * data)
{ {
bool DataAvailable = false; bool DataAvailable = false;
@@ -308,8 +297,7 @@ bool RS485_DataAvailable(
} }
#ifdef TEST_RS485 #ifdef TEST_RS485
int main( int main(void)
void)
{ {
unsigned i = 0; unsigned i = 0;
uint8_t DataRegister; uint8_t DataRegister;
+17 -15
View File
@@ -33,12 +33,10 @@ extern uint8_t __stack;
#if defined(__GNUC__) #if defined(__GNUC__)
#define STACK_CANARY (0xC5) #define STACK_CANARY (0xC5)
void stack_init( void stack_init(void) __attribute__((naked)) __attribute__((section(".init1")));
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
#endif #endif
void stack_init( void stack_init(void)
void)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
#if 0 #if 0
@@ -49,17 +47,23 @@ void stack_init(
p++; p++;
} }
#else #else
__asm volatile ( __asm volatile(" ldi r30,lo8(_end)\n"
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */ " ldi r31,hi8(_end)\n"
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n" " ldi r25,hi8(__stack)\n"
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::); " rjmp .cmp\n"
".loop:\n"
" st Z+,r24\n"
".cmp:\n"
" cpi r30,lo8(__stack)\n"
" cpc r31,r25\n"
" brlo .loop\n"
" breq .loop" ::);
#endif #endif
#endif #endif
} }
unsigned stack_size( unsigned stack_size(void)
void)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
return (&__stack) - (&_end); return (&__stack) - (&_end);
@@ -68,8 +72,7 @@ unsigned stack_size(
#endif #endif
} }
uint8_t stack_byte( uint8_t stack_byte(unsigned offset)
unsigned offset)
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
return *(&_end + offset); return *(&_end + offset);
@@ -79,8 +82,7 @@ uint8_t stack_byte(
#endif #endif
} }
unsigned stack_unused( unsigned stack_unused(void)
void)
{ {
unsigned count = 0; unsigned count = 0;
#if defined(__GNUC__) #if defined(__GNUC__)
+3 -6
View File
@@ -41,8 +41,7 @@ volatile uint8_t Timer_Milliseconds = 0;
static volatile uint16_t SilenceTime; static volatile uint16_t SilenceTime;
/* Configure the Timer */ /* Configure the Timer */
void Timer_Initialize( void Timer_Initialize(void)
void)
{ {
/* Normal Operation */ /* Normal Operation */
TCCR1A = 0; TCCR1A = 0;
@@ -84,8 +83,7 @@ ISR(TIMER0_OVF_vect)
} }
/* Public access to the Silence Timer */ /* Public access to the Silence Timer */
uint16_t Timer_Silence( uint16_t Timer_Silence(void)
void)
{ {
uint16_t timer; uint16_t timer;
@@ -97,8 +95,7 @@ uint16_t Timer_Silence(
} }
/* Public reset of the Silence Timer */ /* Public reset of the Silence Timer */
void Timer_Silence_Reset( void Timer_Silence_Reset(void)
void)
{ {
BIT_CLEAR(TIMSK0, TOIE0); BIT_CLEAR(TIMSK0, TOIE0);
SilenceTime = 0; SilenceTime = 0;
+12 -12
View File
@@ -59,8 +59,7 @@
ADATE = Auto Trigger Enable ADATE = Auto Trigger Enable
*/ */
void adc_enable( void adc_enable(uint8_t index)
uint8_t index)
{ {
index = index; index = index;
/* do nothing */ /* do nothing */
@@ -71,19 +70,20 @@ void adc_enable(
* Returns: none * Returns: none
* Notes: none * Notes: none
**************************************************/ **************************************************/
uint8_t adc_result_8bit( uint8_t adc_result_8bit(uint8_t channel)
uint8_t channel)
{ /* 0..7 = ADC0..ADC7, respectively */ { /* 0..7 = ADC0..ADC7, respectively */
uint8_t value = 0; /* return value */ uint8_t value = 0; /* return value */
while (ADCSRA & (1 << ADSC)); while (ADCSRA & (1 << ADSC))
;
ADMUX = channel | (1 << ADLAR) | (0 << REFS1) | (1 << REFS0); ADMUX = channel | (1 << ADLAR) | (0 << REFS1) | (1 << REFS0);
/* Delay needed for the stabilization of the ADC input voltage */ /* Delay needed for the stabilization of the ADC input voltage */
_delay_us(10); _delay_us(10);
/* Start the analog to digital conversion */ /* Start the analog to digital conversion */
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | ADPS_8BIT; ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | ADPS_8BIT;
/* Wait for the analog to digital conversion to complete */ /* Wait for the analog to digital conversion to complete */
while ((ADCSRA & (1 << ADIF)) == 0); while ((ADCSRA & (1 << ADIF)) == 0)
;
value = ADCH; value = ADCH;
return value; return value;
@@ -94,19 +94,20 @@ uint8_t adc_result_8bit(
* Returns: none * Returns: none
* Notes: none * Notes: none
**************************************************/ **************************************************/
uint16_t adc_result_10bit( uint16_t adc_result_10bit(uint8_t channel)
uint8_t channel)
{ /* 0..7 = ADC0..ADC7, respectively */ { /* 0..7 = ADC0..ADC7, respectively */
uint16_t value = 0; /* return value */ uint16_t value = 0; /* return value */
while (ADCSRA & (1 << ADSC)); while (ADCSRA & (1 << ADSC))
;
ADMUX = channel | (0 << ADLAR) | (0 << REFS1) | (1 << REFS0); ADMUX = channel | (0 << ADLAR) | (0 << REFS1) | (1 << REFS0);
/* Delay needed for the stabilization of the ADC input voltage */ /* Delay needed for the stabilization of the ADC input voltage */
_delay_us(10); _delay_us(10);
/* Start the analog to digital conversion */ /* Start the analog to digital conversion */
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | ADPS_10BIT; ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADIF) | ADPS_10BIT;
/* Wait for the analog to digital conversion to complete */ /* Wait for the analog to digital conversion to complete */
while ((ADCSRA & (1 << ADIF)) == 0); while ((ADCSRA & (1 << ADIF)) == 0)
;
value = ADCL; value = ADCL;
value |= (ADCH << 8); value |= (ADCH << 8);
@@ -118,8 +119,7 @@ uint16_t adc_result_10bit(
* Returns: none * Returns: none
* Notes: none * Notes: none
**************************************************/ **************************************************/
void adc_init( void adc_init(void)
void)
{ {
/* configure ADC for Free Running Mode - ADTS = 000 */ /* configure ADC for Free Running Mode - ADTS = 000 */
/* AIN1 is applied to the negative input of the Analog Comparator - ACME */ /* AIN1 is applied to the negative input of the Analog Comparator - ACME */
+4 -8
View File
@@ -86,8 +86,7 @@ ISR(ADC_vect)
BIT_SET(ADCSRA, ADSC); BIT_SET(ADCSRA, ADSC);
} }
void adc_enable( void adc_enable(uint8_t index)
uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */ { /* 0..7 = ADC0..ADC7, respectively */
if (Enabled_Channels) { if (Enabled_Channels) {
/* ADC interupt is already started */ /* ADC interupt is already started */
@@ -106,8 +105,7 @@ void adc_enable(
} }
} }
uint8_t adc_result_8bit( uint8_t adc_result_8bit(uint8_t index)
uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */ { /* 0..7 = ADC0..ADC7, respectively */
uint8_t result = 0; uint8_t result = 0;
uint8_t sreg; uint8_t sreg;
@@ -123,8 +121,7 @@ uint8_t adc_result_8bit(
return result; return result;
} }
uint16_t adc_result_10bit( uint16_t adc_result_10bit(uint8_t index)
uint8_t index)
{ /* 0..7 = ADC0..ADC7, respectively */ { /* 0..7 = ADC0..ADC7, respectively */
uint16_t result = 0; uint16_t result = 0;
uint8_t sreg; uint8_t sreg;
@@ -140,8 +137,7 @@ uint16_t adc_result_10bit(
return result; return result;
} }
void adc_init( void adc_init(void)
void)
{ {
/* Initial channel selection */ /* Initial channel selection */
/* ADLAR = Left Adjust Result /* ADLAR = Left Adjust Result
+18 -43
View File
@@ -42,30 +42,16 @@
static float Present_Value[MAX_ANALOG_INPUTS]; static float Present_Value[MAX_ANALOG_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Input_Properties_Required[] = { static const int Analog_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Input_Properties_Optional[] = { static const int Analog_Input_Properties_Optional[] = { -1 };
-1
};
static const int Analog_Input_Properties_Proprietary[] = { static const int Analog_Input_Properties_Proprietary[] = { -1 };
-1
};
void Analog_Input_Property_Lists( void Analog_Input_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Analog_Input_Properties_Required; *pRequired = Analog_Input_Properties_Required;
@@ -77,8 +63,7 @@ void Analog_Input_Property_Lists(
return; return;
} }
void Analog_Input_Init( void Analog_Input_Init(void)
void)
{ {
return; return;
} }
@@ -86,8 +71,7 @@ void Analog_Input_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
@@ -96,22 +80,19 @@ bool Analog_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
bool Analog_Input_Object_Name( bool Analog_Input_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[32]; /* okay for single thread */ static char text_string[32]; /* okay for single thread */
bool status = false; bool status = false;
@@ -124,8 +105,7 @@ bool Analog_Input_Object_Name(
return status; return status;
} }
float Analog_Input_Present_Value( float Analog_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
@@ -136,9 +116,7 @@ float Analog_Input_Present_Value(
return value; return value;
} }
void Analog_Input_Present_Value_Set( void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
if (object_instance < MAX_ANALOG_INPUTS) { if (object_instance < MAX_ANALOG_INPUTS) {
Present_Value[object_instance] = value; Present_Value[object_instance] = value;
@@ -147,8 +125,7 @@ void Analog_Input_Present_Value_Set(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object already exists */ /* assumption - object already exists */
int Analog_Input_Read_Property( int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_CHARACTER_STRING char_string = { 0 }; BACNET_CHARACTER_STRING char_string = { 0 };
@@ -162,9 +139,8 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], rpdata->object_type, &apdu[0], rpdata->object_type, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Analog_Input_Object_Name(rpdata->object_instance, &char_string); Analog_Input_Object_Name(rpdata->object_instance, &char_string);
@@ -176,9 +152,8 @@ int Analog_Input_Read_Property(
encode_application_enumerated(&apdu[0], rpdata->object_type); encode_application_enumerated(&apdu[0], rpdata->object_type);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
+25 -51
View File
@@ -46,17 +46,9 @@
static float Present_Value[MAX_ANALOG_VALUES]; static float Present_Value[MAX_ANALOG_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Value_Properties_Required[] = { static const int Analog_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Value_Properties_Optional[] = { static const int Analog_Value_Properties_Optional[] = {
#if 0 #if 0
@@ -66,14 +58,10 @@ static const int Analog_Value_Properties_Optional[] = {
-1 -1
}; };
static const int Analog_Value_Properties_Proprietary[] = { static const int Analog_Value_Properties_Proprietary[] = { -1 };
-1
};
void Analog_Value_Property_Lists( void Analog_Value_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Analog_Value_Properties_Required; *pRequired = Analog_Value_Properties_Required;
@@ -85,8 +73,7 @@ void Analog_Value_Property_Lists(
return; return;
} }
void Analog_Value_Init( void Analog_Value_Init(void)
void)
{ {
return; return;
} }
@@ -94,8 +81,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
return true; return true;
@@ -105,8 +91,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(void)
void)
{ {
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
} }
@@ -114,8 +99,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -123,8 +107,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_VALUES; unsigned index = MAX_ANALOG_VALUES;
@@ -134,8 +117,7 @@ unsigned Analog_Value_Instance_To_Index(
return index; return index;
} }
float Analog_Value_Present_Value( float Analog_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0; float value = 0;
unsigned index = 0; unsigned index = 0;
@@ -149,9 +131,7 @@ float Analog_Value_Present_Value(
} }
bool Analog_Value_Present_Value_Set( bool Analog_Value_Present_Value_Set(
uint32_t object_instance, uint32_t object_instance, float value, uint8_t priority)
float value,
uint8_t priority)
{ {
unsigned index = 0; unsigned index = 0;
bool status = false; bool status = false;
@@ -160,8 +140,8 @@ bool Analog_Value_Present_Value_Set(
index = Analog_Value_Instance_To_Index(object_instance); index = Analog_Value_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_VALUES) { if (index < MAX_ANALOG_VALUES) {
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) && (priority != 6 /* reserved */) && (value >= 0.0) &&
(value >= 0.0) && (value <= 100.0)) { (value <= 100.0)) {
Present_Value[index] = value; Present_Value[index] = value;
/* 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.
@@ -176,8 +156,7 @@ bool Analog_Value_Present_Value_Set(
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Analog_Value_Object_Name( bool Analog_Value_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
unsigned index = 0; unsigned index = 0;
@@ -193,8 +172,7 @@ bool Analog_Value_Object_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Read_Property( int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -214,9 +192,8 @@ int Analog_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], rpdata->object_type, &apdu[0], rpdata->object_type, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Analog_Value_Object_Name(rpdata->object_instance, &char_string); Analog_Value_Object_Name(rpdata->object_instance, &char_string);
@@ -332,8 +309,7 @@ int Analog_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
#if 0 #if 0
@@ -344,9 +320,8 @@ bool Analog_Value_Write_Property(
int len = 0; int len = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -363,8 +338,7 @@ bool Analog_Value_Write_Property(
} }
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
status = status =
@@ -372,9 +346,9 @@ bool Analog_Value_Write_Property(
value.type.Real, wp_data->priority); value.type.Real, wp_data->priority);
if (!status) { if (!status) {
if (wp_data->priority == 6) { if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum
algorithm and may not be used for other purposes in any On/Off algorithm and may not be used for other
object. */ purposes in any object. */
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else { } else {
+15 -20
View File
@@ -55,8 +55,7 @@ static uint8_t MSTP_MAC_Address;
static struct mstimer DCC_Timer; static struct mstimer DCC_Timer;
#define DCC_CYCLE_SECONDS 1 #define DCC_CYCLE_SECONDS 1
static bool seeprom_version_test( static bool seeprom_version_test(void)
void)
{ {
uint16_t version = 0; uint16_t version = 0;
uint16_t id = 0; uint16_t id = 0;
@@ -65,8 +64,7 @@ static bool seeprom_version_test(
rv = seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2); rv = seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
if (rv > 0) { if (rv > 0) {
rv = seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *) & version, rv = seeprom_bytes_read(NV_SEEPROM_VERSION_0, (uint8_t *)&version, 2);
2);
} }
if ((rv > 0) && (id == SEEPROM_ID) && (version == SEEPROM_VERSION)) { if ((rv > 0) && (id == SEEPROM_ID) && (version == SEEPROM_VERSION)) {
@@ -90,8 +88,8 @@ static void device_id_init(uint8_t mac)
uint32_t device_id = 0; uint32_t device_id = 0;
/* Get the device ID from the eeprom */ /* Get the device ID from the eeprom */
eeprom_bytes_read(NV_EEPROM_DEVICE_0, (uint8_t *) & device_id, eeprom_bytes_read(
sizeof(device_id)); NV_EEPROM_DEVICE_0, (uint8_t *)&device_id, sizeof(device_id));
if (device_id < BACNET_MAX_INSTANCE) { if (device_id < BACNET_MAX_INSTANCE) {
Device_Set_Object_Instance_Number(device_id); Device_Set_Object_Instance_Number(device_id);
} else { } else {
@@ -100,8 +98,7 @@ static void device_id_init(uint8_t mac)
} }
} }
void bacnet_init( void bacnet_init(void)
void)
{ {
uint8_t max_master = 0; uint8_t max_master = 0;
@@ -121,21 +118,20 @@ void bacnet_init(
Device_Init(NULL); Device_Init(NULL);
device_id_init(MSTP_MAC_Address); device_id_init(MSTP_MAC_Address);
/* set up our confirmed service unrecognized service handler - required! */ /* set up our confirmed service unrecognized service handler - required! */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we need to handle who-is to support dynamic device binding */ /* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(
handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, apdu_set_confirmed_handler(
handler_read_property_multiple); SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, apdu_set_confirmed_handler(
handler_reinitialize_device); SERVICE_CONFIRMED_REINITIALIZE_DEVICE, handler_reinitialize_device);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, apdu_set_confirmed_handler(
handler_write_property); SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
@@ -146,8 +142,7 @@ void bacnet_init(
} }
static uint8_t PDUBuffer[MAX_MPDU]; static uint8_t PDUBuffer[MAX_MPDU];
void bacnet_task( void bacnet_task(void)
void)
{ {
uint8_t mstp_mac_address; uint8_t mstp_mac_address;
uint16_t pdu_len; uint16_t pdu_len;
+17 -41
View File
@@ -42,30 +42,16 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Input_Properties_Required[] = { static const int Binary_Input_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_POLARITY,
-1
};
static const int Binary_Input_Properties_Optional[] = { static const int Binary_Input_Properties_Optional[] = { -1 };
-1
};
static const int Binary_Input_Properties_Proprietary[] = { static const int Binary_Input_Properties_Proprietary[] = { -1 };
-1
};
void Binary_Input_Property_Lists( void Binary_Input_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) { if (pRequired) {
*pRequired = Binary_Input_Properties_Required; *pRequired = Binary_Input_Properties_Required;
@@ -80,8 +66,7 @@ void Binary_Input_Property_Lists(
return; return;
} }
void Binary_Input_Init( void Binary_Input_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -91,8 +76,7 @@ void Binary_Input_Init(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance( bool Binary_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_INPUTS) if (object_instance < MAX_BINARY_INPUTS)
return true; return true;
@@ -101,15 +85,13 @@ bool Binary_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Input_Count( unsigned Binary_Input_Count(void)
void)
{ {
return MAX_BINARY_INPUTS; return MAX_BINARY_INPUTS;
} }
/* we simply have 0-n object instances.*/ /* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance( uint32_t Binary_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -117,8 +99,7 @@ uint32_t Binary_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index( unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_INPUTS; unsigned index = MAX_BINARY_INPUTS;
@@ -128,8 +109,7 @@ unsigned Binary_Input_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Input_Present_Value( BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0; unsigned index = 0;
@@ -143,8 +123,7 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
} }
bool Binary_Input_Present_Value_Set( bool Binary_Input_Present_Value_Set(
uint32_t object_instance, uint32_t object_instance, BACNET_BINARY_PV value)
BACNET_BINARY_PV value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -158,8 +137,7 @@ bool Binary_Input_Present_Value_Set(
} }
bool Binary_Input_Object_Name( bool Binary_Input_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[32]; /* okay for single thread */ static char text_string[32]; /* okay for single thread */
bool status = false; bool status = false;
@@ -174,8 +152,7 @@ bool Binary_Input_Object_Name(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */ /* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property( int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string = { 0 }; BACNET_BIT_STRING bit_string = { 0 };
@@ -191,9 +168,8 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], rpdata->object_type, &apdu[0], rpdata->object_type, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Binary_Input_Object_Name(rpdata->object_instance, &char_string); Binary_Input_Object_Name(rpdata->object_instance, &char_string);
+17 -31
View File
@@ -35,10 +35,7 @@
#include "bacnet/basic/object/device.h" #include "bacnet/basic/object/device.h"
#include "bname.h" #include "bname.h"
static bool bacnet_name_isvalid( static bool bacnet_name_isvalid(uint8_t encoding, uint8_t length, char *str)
uint8_t encoding,
uint8_t length,
char *str)
{ {
bool valid = false; bool valid = false;
@@ -55,32 +52,27 @@ static bool bacnet_name_isvalid(
} }
bool bacnet_name_save( bool bacnet_name_save(
uint16_t offset, uint16_t offset, uint8_t encoding, char *str, uint8_t length)
uint8_t encoding,
char *str,
uint8_t length)
{ {
uint8_t buffer[NV_EEPROM_NAME_SIZE] = { 0 }; uint8_t buffer[NV_EEPROM_NAME_SIZE] = { 0 };
uint8_t i = 0; uint8_t i = 0;
if (bacnet_name_isvalid(encoding, length, str)) { if (bacnet_name_isvalid(encoding, length, str)) {
eeprom_bytes_write(NV_EEPROM_NAME_LENGTH(offset), &length, 1); eeprom_bytes_write(NV_EEPROM_NAME_LENGTH(offset), &length, 1);
eeprom_bytes_write(NV_EEPROM_NAME_ENCODING(offset), eeprom_bytes_write(
(uint8_t *) & encoding, 1); NV_EEPROM_NAME_ENCODING(offset), (uint8_t *)&encoding, 1);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
buffer[i] = str[i]; buffer[i] = str[i];
} }
eeprom_bytes_write(NV_EEPROM_NAME_STRING(offset), &buffer[0], eeprom_bytes_write(
NV_EEPROM_NAME_SIZE); NV_EEPROM_NAME_STRING(offset), &buffer[0], NV_EEPROM_NAME_SIZE);
return true; return true;
} }
return false; return false;
} }
bool bacnet_name_set( bool bacnet_name_set(uint16_t offset, BACNET_CHARACTER_STRING *char_string)
uint16_t offset,
BACNET_CHARACTER_STRING * char_string)
{ {
uint8_t encoding = 0; uint8_t encoding = 0;
uint8_t length = 0; uint8_t length = 0;
@@ -92,8 +84,7 @@ bool bacnet_name_set(
return bacnet_name_save(offset, encoding, str, length); return bacnet_name_save(offset, encoding, str, length);
} }
bool bacnet_name_write_unique( bool bacnet_name_write_unique(uint16_t offset,
uint16_t offset,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
@@ -113,8 +104,8 @@ bool bacnet_name_write_unique(
} else if (length <= NV_EEPROM_NAME_SIZE) { } else if (length <= NV_EEPROM_NAME_SIZE) {
encoding = characterstring_encoding(char_string); encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) { if (encoding < MAX_CHARACTER_STRING_ENCODING) {
if (Device_Valid_Object_Name(char_string, &duplicate_type, if (Device_Valid_Object_Name(
&duplicate_instance)) { char_string, &duplicate_type, &duplicate_instance)) {
if ((duplicate_type == object_type) && if ((duplicate_type == object_type) &&
(duplicate_instance == object_instance)) { (duplicate_instance == object_instance)) {
/* writing same name to same object */ /* writing same name to same object */
@@ -145,8 +136,7 @@ bool bacnet_name_write_unique(
} }
/* no required minumum length or duplicate checking */ /* no required minumum length or duplicate checking */
bool bacnet_name_write( bool bacnet_name_write(uint16_t offset,
uint16_t offset,
BACNET_CHARACTER_STRING *char_string, BACNET_CHARACTER_STRING *char_string,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
@@ -176,18 +166,14 @@ bool bacnet_name_write(
return status; return status;
} }
void bacnet_name_init( void bacnet_name_init(uint16_t offset, char *default_string)
uint16_t offset,
char *default_string)
{ {
(void) bacnet_name_save(offset, CHARACTER_UTF8, default_string, (void)bacnet_name_save(
strlen(default_string)); offset, CHARACTER_UTF8, default_string, strlen(default_string));
} }
void bacnet_name( void bacnet_name(
uint16_t offset, uint16_t offset, BACNET_CHARACTER_STRING *char_string, char *default_string)
BACNET_CHARACTER_STRING * char_string,
char *default_string)
{ {
uint8_t encoding = 0; uint8_t encoding = 0;
uint8_t length = 0; uint8_t length = 0;
@@ -195,8 +181,8 @@ void bacnet_name(
eeprom_bytes_read(NV_EEPROM_NAME_ENCODING(offset), &encoding, 1); eeprom_bytes_read(NV_EEPROM_NAME_ENCODING(offset), &encoding, 1);
eeprom_bytes_read(NV_EEPROM_NAME_LENGTH(offset), &length, 1); eeprom_bytes_read(NV_EEPROM_NAME_LENGTH(offset), &length, 1);
eeprom_bytes_read(NV_EEPROM_NAME_STRING(offset), (uint8_t *) & name, eeprom_bytes_read(
NV_EEPROM_NAME_SIZE); NV_EEPROM_NAME_STRING(offset), (uint8_t *)&name, NV_EEPROM_NAME_SIZE);
if (bacnet_name_isvalid(encoding, length, name)) { if (bacnet_name_isvalid(encoding, length, name)) {
characterstring_init(char_string, encoding, &name[0], length); characterstring_init(char_string, encoding, &name[0], length);
} else if (default_string) { } else if (default_string) {
+58 -96
View File
@@ -55,34 +55,18 @@ static uint8_t Out_Of_Service[MAX_BINARY_OUTPUTS];
static uint8_t Polarity[MAX_BINARY_OUTPUTS]; static uint8_t Polarity[MAX_BINARY_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Output_Properties_Required[] = { static const int Binary_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, PROP_PRIORITY_ARRAY,
PROP_OBJECT_TYPE, PROP_RELINQUISH_DEFAULT, -1 };
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_POLARITY,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
static const int Binary_Output_Properties_Optional[] = { static const int Binary_Output_Properties_Optional[] = { PROP_ACTIVE_TEXT,
PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1 };
PROP_INACTIVE_TEXT,
-1
};
static const int Binary_Output_Properties_Proprietary[] = { static const int Binary_Output_Properties_Proprietary[] = { -1 };
-1
};
void Binary_Output_Property_Lists( void Binary_Output_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Binary_Output_Properties_Required; *pRequired = Binary_Output_Properties_Required;
@@ -95,8 +79,7 @@ void Binary_Output_Property_Lists(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Output_Valid_Instance( bool Binary_Output_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_OUTPUTS) if (object_instance < MAX_BINARY_OUTPUTS)
return true; return true;
@@ -105,22 +88,19 @@ bool Binary_Output_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Output_Count( unsigned Binary_Output_Count(void)
void)
{ {
return MAX_BINARY_OUTPUTS; return MAX_BINARY_OUTPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Binary_Output_Index_To_Instance( uint32_t Binary_Output_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Output_Instance_To_Index( unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_OUTPUTS; unsigned index = MAX_BINARY_OUTPUTS;
@@ -130,8 +110,7 @@ unsigned Binary_Output_Instance_To_Index(
return index; return index;
} }
static BACNET_BINARY_PV Present_Value( static BACNET_BINARY_PV Present_Value(unsigned int index)
unsigned int index)
{ {
BACNET_BINARY_PV value = RELINQUISH_DEFAULT; BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
BACNET_BINARY_PV current_value = RELINQUISH_DEFAULT; BACNET_BINARY_PV current_value = RELINQUISH_DEFAULT;
@@ -150,8 +129,7 @@ static BACNET_BINARY_PV Present_Value(
return value; return value;
} }
BACNET_BINARY_PV Binary_Output_Present_Value( BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
@@ -161,9 +139,7 @@ BACNET_BINARY_PV Binary_Output_Present_Value(
} }
bool Binary_Output_Present_Value_Set( bool Binary_Output_Present_Value_Set(
uint32_t instance, uint32_t instance, BACNET_BINARY_PV binary_value, unsigned priority)
BACNET_BINARY_PV binary_value,
unsigned priority)
{ /* 0..15 */ { /* 0..15 */
bool status = false; bool status = false;
@@ -180,17 +156,16 @@ bool Binary_Output_Present_Value_Set(
return status; return status;
} }
bool Binary_Output_Polarity_Set( bool Binary_Output_Polarity_Set(uint32_t instance, BACNET_POLARITY polarity)
uint32_t instance,
BACNET_POLARITY polarity)
{ {
bool status = false; bool status = false;
if (instance < MAX_BINARY_OUTPUTS) { if (instance < MAX_BINARY_OUTPUTS) {
if (polarity < MAX_POLARITY) { if (polarity < MAX_POLARITY) {
Polarity[instance] = polarity; Polarity[instance] = polarity;
seeprom_bytes_write(NV_SEEPROM_BINARY_OUTPUT(instance, seeprom_bytes_write(
NV_SEEPROM_BO_POLARITY), &Polarity[instance], 1); NV_SEEPROM_BINARY_OUTPUT(instance, NV_SEEPROM_BO_POLARITY),
&Polarity[instance], 1);
status = true; status = true;
} }
} }
@@ -198,8 +173,7 @@ bool Binary_Output_Polarity_Set(
return status; return status;
} }
BACNET_POLARITY Binary_Output_Polarity( BACNET_POLARITY Binary_Output_Polarity(uint32_t instance)
uint32_t instance)
{ {
BACNET_POLARITY polarity = POLARITY_NORMAL; BACNET_POLARITY polarity = POLARITY_NORMAL;
@@ -210,19 +184,17 @@ BACNET_POLARITY Binary_Output_Polarity(
return polarity; return polarity;
} }
void Binary_Output_Out_Of_Service_Set( void Binary_Output_Out_Of_Service_Set(uint32_t instance, bool flag)
uint32_t instance,
bool flag)
{ {
if (instance < MAX_BINARY_OUTPUTS) { if (instance < MAX_BINARY_OUTPUTS) {
Out_Of_Service[instance] = flag; Out_Of_Service[instance] = flag;
seeprom_bytes_write(NV_SEEPROM_BINARY_OUTPUT(instance, seeprom_bytes_write(
NV_SEEPROM_BO_OUT_OF_SERVICE), &Out_Of_Service[instance], 1); NV_SEEPROM_BINARY_OUTPUT(instance, NV_SEEPROM_BO_OUT_OF_SERVICE),
&Out_Of_Service[instance], 1);
} }
} }
bool Binary_Output_Out_Of_Service( bool Binary_Output_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
bool flag = false; bool flag = false;
@@ -235,8 +207,7 @@ bool Binary_Output_Out_Of_Service(
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Binary_Output_Object_Name( bool Binary_Output_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[32]; /* okay for single thread */ static char text_string[32]; /* okay for single thread */
bool status = false; bool status = false;
@@ -250,8 +221,7 @@ bool Binary_Output_Object_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Binary_Output_Read_Property( int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -270,9 +240,8 @@ int Binary_Output_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], rpdata->object_type, &apdu[0], rpdata->object_type, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Binary_Output_Object_Name(rpdata->object_instance, &char_string); Binary_Output_Object_Name(rpdata->object_instance, &char_string);
@@ -312,8 +281,7 @@ int Binary_Output_Read_Property(
object_index = object_index =
Binary_Output_Instance_To_Index(rpdata->object_instance); Binary_Output_Instance_To_Index(rpdata->object_instance);
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], Polarity[object_index]);
Polarity[object_index]);
break; break;
case PROP_PRIORITY_ARRAY: case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
@@ -327,14 +295,13 @@ int Binary_Output_Read_Property(
Binary_Output_Instance_To_Index(rpdata->object_instance); Binary_Output_Instance_To_Index(rpdata->object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) { for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */ /* FIXME: check if we have room before adding it to APDU */
present_value = (BACNET_BINARY_PV) present_value =
Binary_Output_Level[object_index][i]; (BACNET_BINARY_PV)Binary_Output_Level[object_index][i];
if (present_value == BINARY_NULL) { if (present_value == BINARY_NULL) {
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
} else { } else {
len = len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len], present_value);
present_value);
} }
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
@@ -351,14 +318,13 @@ int Binary_Output_Read_Property(
Binary_Output_Instance_To_Index(rpdata->object_instance); Binary_Output_Instance_To_Index(rpdata->object_instance);
if (rpdata->array_index <= BACNET_MAX_PRIORITY) { if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
present_value = (BACNET_BINARY_PV) present_value = (BACNET_BINARY_PV)
Binary_Output_Level[object_index][rpdata->array_index - Binary_Output_Level[object_index]
1]; [rpdata->array_index - 1];
if (present_value == BINARY_NULL) { if (present_value == BINARY_NULL) {
apdu_len = encode_application_null(&apdu[apdu_len]); apdu_len = encode_application_null(&apdu[apdu_len]);
} else { } else {
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len], present_value);
present_value);
} }
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -399,8 +365,7 @@ int Binary_Output_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Output_Write_Property( bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int priority = 0; unsigned int priority = 0;
@@ -409,9 +374,8 @@ bool Binary_Output_Write_Property(
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -441,8 +405,8 @@ bool Binary_Output_Write_Property(
(value.type.Enumerated <= MAX_BINARY_PV)) { (value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV)value.type.Enumerated; level = (BACNET_BINARY_PV)value.type.Enumerated;
priority--; priority--;
Binary_Output_Present_Value_Set(wp_data->object_instance, Binary_Output_Present_Value_Set(
level, priority); wp_data->object_instance, level, priority);
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
@@ -456,21 +420,20 @@ bool Binary_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
level = BINARY_NULL; level = BINARY_NULL;
priority = wp_data->priority; priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) { if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--; priority--;
Binary_Output_Present_Value_Set Binary_Output_Present_Value_Set(
(wp_data->object_instance, level, priority); wp_data->object_instance, level, priority);
} else if (priority == 6) { } else if (priority == 6) {
status = false; status = false;
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum
algorithm and may not be used for other purposes in any On/Off algorithm and may not be used for other
object. */ purposes in any object. */
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else { } else {
@@ -482,12 +445,11 @@ bool Binary_Output_Write_Property(
} }
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
Binary_Output_Out_Of_Service_Set(wp_data->object_instance, Binary_Output_Out_Of_Service_Set(
value.type.Boolean); wp_data->object_instance, value.type.Boolean);
} }
break; break;
case PROP_POLARITY: case PROP_POLARITY:
@@ -528,8 +490,7 @@ bool Binary_Output_Write_Property(
return status; return status;
} }
void Binary_Output_Init( void Binary_Output_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
@@ -541,14 +502,15 @@ void Binary_Output_Init(
if (Polarity[i] >= MAX_POLARITY) { if (Polarity[i] >= MAX_POLARITY) {
Binary_Output_Polarity_Set(i, POLARITY_NORMAL); Binary_Output_Polarity_Set(i, POLARITY_NORMAL);
} }
seeprom_bytes_read(NV_SEEPROM_BINARY_OUTPUT(i, seeprom_bytes_read(
NV_SEEPROM_BO_OUT_OF_SERVICE), &Out_Of_Service[i], 1); NV_SEEPROM_BINARY_OUTPUT(i, NV_SEEPROM_BO_OUT_OF_SERVICE),
&Out_Of_Service[i], 1);
if (Out_Of_Service[i] > 1) { if (Out_Of_Service[i] > 1) {
Binary_Output_Out_Of_Service_Set(i, false); Binary_Output_Out_Of_Service_Set(i, false);
} }
for (j = 0; j < BACNET_MAX_PRIORITY; j++) { for (j = 0; j < BACNET_MAX_PRIORITY; j++) {
seeprom_bytes_read(NV_SEEPROM_BINARY_OUTPUT(i, seeprom_bytes_read(
NV_SEEPROM_BO_PRIORITY_ARRAY_1 + j), NV_SEEPROM_BINARY_OUTPUT(i, NV_SEEPROM_BO_PRIORITY_ARRAY_1 + j),
&Binary_Output_Level[i][j], 1); &Binary_Output_Level[i][j], 1);
} }
} }
+55 -71
View File
@@ -16,8 +16,8 @@
* *
* Description : This Program allows an AVR with bootloader capabilities to * Description : This Program allows an AVR with bootloader capabilities to
* Read/write its own Flash/EEprom. To enter Programming mode * Read/write its own Flash/EEprom. To enter Programming mode
* an input pin is checked. If this pin is pulled low, programming mode * an input pin is checked. If this pin is pulled low,
* is entered. If not, normal execution is done from $0000 *programming mode is entered. If not, normal execution is done from $0000
* "reset" vector in Application area. * "reset" vector in Application area.
* *
* Preparations : Use the preprocessor.xls file for obtaining a customized * Preparations : Use the preprocessor.xls file for obtaining a customized
@@ -28,8 +28,6 @@
#include "serial.h" #include "serial.h"
#include "flash.h" #include "flash.h"
/* Uncomment the following to save code space */ /* Uncomment the following to save code space */
/*#define REMOVE_AVRPROG_SUPPORT */ /*#define REMOVE_AVRPROG_SUPPORT */
/*#define REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */ /*#define REMOVE_FUSE_AND_LOCK_BIT_SUPPORT */
@@ -52,43 +50,35 @@
#endif /* LARGE_MEMORY */ #endif /* LARGE_MEMORY */
#ifndef REMOVE_BLOCK_SUPPORT #ifndef REMOVE_BLOCK_SUPPORT
unsigned char BlockLoad( unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address);
unsigned int size, void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address);
unsigned char mem,
ADDR_T * address);
void BlockRead(
unsigned int size,
unsigned char mem,
ADDR_T * address);
/* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n = PAGESIZE, where n=1,2,3... */ /* BLOCKSIZE should be chosen so that the following holds: BLOCKSIZE*n =
* PAGESIZE, where n=1,2,3... */
#define BLOCKSIZE PAGESIZE #define BLOCKSIZE PAGESIZE
#endif /* REMOVE_BLOCK_SUPPORT */ #endif /* REMOVE_BLOCK_SUPPORT */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
__C_task void main( __C_task void main(void)
void)
#else /* ! __ICCAVR__ */ #else /* ! __ICCAVR__ */
int main( int main(void)
void)
#endif /* __ICCAVR__ */ #endif /* __ICCAVR__ */
{ {
ADDR_T address; ADDR_T address;
unsigned int temp_int; unsigned int temp_int;
unsigned char val; unsigned char val;
/* Initialization */ /* Initialization */
void ( void (*funcptr)(void) =
*funcptr) ( 0x0000; /* Set up function pointer to RESET vector. */
void) = 0x0000; /* Set up function pointer to RESET vector. */ PROGPORT |=
PROGPORT |= (1 << PROG_NO); /* Enable pull-up on PROG_NO line on PROGPORT. */ (1 << PROG_NO); /* Enable pull-up on PROG_NO line on PROGPORT. */
initbootuart(); /* Initialize UART. */ initbootuart(); /* Initialize UART. */
/* Branch to bootloader or application code? */ /* Branch to bootloader or application code? */
if (!(PROGPIN & (1 << PROG_NO))) { /* If PROGPIN is pulled low, enter programmingmode. */ if (!(PROGPIN & (1 << PROG_NO))) { /* If PROGPIN is pulled low, enter
programmingmode. */
/* Main loop */ /* Main loop */
for (;;) { for (;;) {
val = recchar(); /* Wait for command character. */ val = recchar(); /* Wait for command character. */
@@ -98,20 +88,24 @@ int main(
sendchar('Y'); /* Yes, we do autoincrement. */ sendchar('Y'); /* Yes, we do autoincrement. */
} }
/* Set address. */ /* Set address. */
else if (val == 'A') { /* Set address... *//* NOTE: Flash addresses are given in words, not bytes. */ else if (val == 'A') {
address = (recchar() << 8) | recchar(); /* Read address high and low byte. */ /* Set address... */ /* NOTE: Flash addresses are given in
words, not bytes. */
address = (recchar() << 8) |
recchar(); /* Read address high and low byte. */
sendchar('\r'); /* Send OK back. */ sendchar('\r'); /* Send OK back. */
} }
/* Chip erase. */ /* Chip erase. */
else if (val == 'e') { else if (val == 'e') {
for (address = 0; address < APP_END; address += PAGESIZE) { /* NOTE: Here we use address as a byte-address, not word-address, for convenience. */ for (address = 0; address < APP_END; address +=
PAGESIZE) { /* NOTE: Here we use address as a byte-address,
not word-address, for convenience. */
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
_PAGE_ERASE(address); _PAGE_ERASE(address);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
@@ -129,7 +123,6 @@ int main(
sendchar(BLOCKSIZE & 0xFF); /* Report BLOCKSIZE (bytes). */ sendchar(BLOCKSIZE & 0xFF); /* Report BLOCKSIZE (bytes). */
} }
/* Start block load. */ /* Start block load. */
else if (val == 'B') { else if (val == 'B') {
temp_int = (recchar() << 8) | recchar(); /* Get block size. */ temp_int = (recchar() << 8) | recchar(); /* Get block size. */
@@ -137,7 +130,6 @@ int main(
sendchar(BlockLoad(temp_int, val, &address)); /* Block load. */ sendchar(BlockLoad(temp_int, val, &address)); /* Block load. */
} }
/* Start block read. */ /* Start block read. */
else if (val == 'g') { else if (val == 'g') {
temp_int = (recchar() << 8) | recchar(); /* Get block size. */ temp_int = (recchar() << 8) | recchar(); /* Get block size. */
@@ -153,7 +145,8 @@ int main(
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
_ENABLE_RWW_SECTION(); _ENABLE_RWW_SECTION();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 1)); sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 1));
sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 0)); sendchar(_LOAD_PROGRAM_MEMORY((address << 1) + 0));
@@ -164,22 +157,25 @@ int main(
address++; /* Auto-advance to next Flash word. */ address++; /* Auto-advance to next Flash word. */
} }
/* Write program memory, low byte. */ /* Write program memory, low byte. */
else if (val == 'c') { /* NOTE: Always use this command before sending high byte. */ else if (val == 'c') { /* NOTE: Always use this command before
temp_int = recchar(); /* Get low byte for later _FILL_TEMP_WORD. */ sending high byte. */
temp_int =
recchar(); /* Get low byte for later _FILL_TEMP_WORD. */
sendchar('\r'); /* Send OK back. */ sendchar('\r'); /* Send OK back. */
} }
/* Write program memory, high byte. */ /* Write program memory, high byte. */
else if (val == 'C') { else if (val == 'C') {
temp_int |= (recchar() << 8); /* Get and insert high byte. */ temp_int |= (recchar() << 8); /* Get and insert high byte. */
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
_FILL_TEMP_WORD((address << 1), temp_int); /* Convert word-address to byte-address and fill. */ _FILL_TEMP_WORD(
(address << 1), temp_int); /* Convert word-address to
byte-address and fill. */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default = Pe1053 /* Back to default. */ #pragma diag_default = Pe1053 /* Back to default. */
#endif #endif
@@ -187,7 +183,6 @@ int main(
sendchar('\r'); /* Send OK back. */ sendchar('\r'); /* Send OK back. */
} }
/* Write page. */ /* Write page. */
else if (val == 'm') { else if (val == 'm') {
if (address >= (APP_END >> 1)) { /* Protect bootloader area. */ if (address >= (APP_END >> 1)) { /* Protect bootloader area. */
@@ -195,9 +190,11 @@ int main(
} else { } else {
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
_PAGE_WRITE(address << 1); /* Convert word-address to byte-address and write. */ _PAGE_WRITE(address << 1); /* Convert word-address to
byte-address and write. */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_default = Pe1053 /* Back to default. */ #pragma diag_default = Pe1053 /* Back to default. */
#endif #endif
@@ -216,14 +213,14 @@ int main(
EEDR = recchar(); /* Get byte. */ EEDR = recchar(); /* Get byte. */
EECR |= (1 << EEMWE); /* Write byte. */ EECR |= (1 << EEMWE); /* Write byte. */
EECR |= (1 << EEWE); EECR |= (1 << EEWE);
while (EECR & (1 << EEWE)) /* Wait for write operation to finish. */ while (EECR &
(1 << EEWE)) /* Wait for write operation to finish. */
; ;
address++; /* Auto-advance to next EEPROM byte. */ address++; /* Auto-advance to next EEPROM byte. */
sendchar('\r'); /* Send OK back. */ sendchar('\r'); /* Send OK back. */
} }
/* Read EEPROM memory. */ /* Read EEPROM memory. */
else if (val == 'd') { else if (val == 'd') {
EEARL = address; /* Setup EEPROM address. */ EEARL = address; /* Setup EEPROM address. */
@@ -248,21 +245,18 @@ int main(
sendchar(_GET_LOCK_BITS()); sendchar(_GET_LOCK_BITS());
} }
/* Read fuse bits. */ /* Read fuse bits. */
else if (val == 'F') { else if (val == 'F') {
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
sendchar(_GET_LOW_FUSES()); sendchar(_GET_LOW_FUSES());
} }
/* Read high fuse bits. */ /* Read high fuse bits. */
else if (val == 'N') { else if (val == 'N') {
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
sendchar(_GET_HIGH_FUSES()); sendchar(_GET_HIGH_FUSES());
} }
/* Read extended fuse bits. */ /* Read extended fuse bits. */
else if (val == 'Q') { else if (val == 'Q') {
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
@@ -277,22 +271,20 @@ int main(
sendchar('\r'); /* Nothing special to do, just answer OK. */ sendchar('\r'); /* Nothing special to do, just answer OK. */
} }
/* Exit bootloader. */ /* Exit bootloader. */
else if (val == 'E') { else if (val == 'E') {
_WAIT_FOR_SPM(); _WAIT_FOR_SPM();
_ENABLE_RWW_SECTION(); _ENABLE_RWW_SECTION();
sendchar('\r'); sendchar('\r');
funcptr(); /* Jump to Reset vector 0x0000 in Application Section. */ funcptr(); /* Jump to Reset vector 0x0000 in Application
Section. */
} }
/* Get programmer type. */ /* Get programmer type. */
else if (val == 'p') { else if (val == 'p') {
sendchar('S'); /* Answer 'SERIAL'. */ sendchar('S'); /* Answer 'SERIAL'. */
} }
/* Return supported device codes. */ /* Return supported device codes. */
else if (val == 't') { else if (val == 't') {
#if PARTCODE + 0 > 0 #if PARTCODE + 0 > 0
@@ -301,7 +293,6 @@ int main(
sendchar(0); /* Send list terminator. */ sendchar(0); /* Send list terminator. */
} }
/* Set LED, clear LED and set device type. */ /* Set LED, clear LED and set device type. */
else if ((val == 'x') || (val == 'y') || (val == 'T')) { else if ((val == 'x') || (val == 'y') || (val == 'T')) {
recchar(); /* Ignore the command and it's parameter. */ recchar(); /* Ignore the command and it's parameter. */
@@ -312,7 +303,8 @@ int main(
/* Return programmer identifier. */ /* Return programmer identifier. */
else if (val == 'S') { else if (val == 'S') {
sendchar('A'); /* Return 'AVRBOOT'. */ sendchar('A'); /* Return 'AVRBOOT'. */
sendchar('V'); /* Software identifier (aka programmer signature) is always 7 characters. */ sendchar('V'); /* Software identifier (aka programmer signature)
is always 7 characters. */
sendchar('R'); sendchar('R');
sendchar('B'); sendchar('B');
sendchar('O'); sendchar('O');
@@ -320,14 +312,12 @@ int main(
sendchar('T'); sendchar('T');
} }
/* Return software version. */ /* Return software version. */
else if (val == 'V') { else if (val == 'V') {
sendchar('1'); sendchar('1');
sendchar('5'); sendchar('5');
} }
/* Return signature bytes. */ /* Return signature bytes. */
else if (val == 's') { else if (val == 's') {
sendchar(SIGNATURE_BYTE_3); sendchar(SIGNATURE_BYTE_3);
@@ -335,7 +325,6 @@ int main(
sendchar(SIGNATURE_BYTE_1); sendchar(SIGNATURE_BYTE_1);
} }
/* The last command to accept is ESC (synchronization). */ /* The last command to accept is ESC (synchronization). */
else if (val != 0x1b) { /* If not ESC, then it is unrecognized... */ else if (val != 0x1b) { /* If not ESC, then it is unrecognized... */
sendchar('?'); sendchar('?');
@@ -348,12 +337,8 @@ int main(
} }
} /* end: main */ } /* end: main */
#ifndef REMOVE_BLOCK_SUPPORT #ifndef REMOVE_BLOCK_SUPPORT
unsigned char BlockLoad( unsigned char BlockLoad(unsigned int size, unsigned char mem, ADDR_T *address)
unsigned int size,
unsigned char mem,
ADDR_T * address)
{ {
unsigned char buffer[BLOCKSIZE]; unsigned char buffer[BLOCKSIZE];
unsigned int data; unsigned int data;
@@ -383,7 +368,8 @@ unsigned char BlockLoad(
} }
/* Flash memory type. */ /* Flash memory type. */
else if (mem == 'F') { /* NOTE: For flash programming, 'address' is given in words. */ else if (mem ==
'F') { /* NOTE: For flash programming, 'address' is given in words. */
(*address) <<= 1; /* Convert address to bytes temporarily. */ (*address) <<= 1; /* Convert address to bytes temporarily. */
tempaddress = (*address); /* Store address in page. */ tempaddress = (*address); /* Store address in page. */
@@ -391,7 +377,8 @@ unsigned char BlockLoad(
data = recchar(); data = recchar();
data |= (recchar() << 8); data |= (recchar() << 8);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
_FILL_TEMP_WORD(*address, data); _FILL_TEMP_WORD(*address, data);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
@@ -402,7 +389,8 @@ unsigned char BlockLoad(
} while (size); /* Loop until all bytes written. */ } while (size); /* Loop until all bytes written. */
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
_PAGE_WRITE(tempaddress); _PAGE_WRITE(tempaddress);
#ifdef __ICCAVR__ #ifdef __ICCAVR__
@@ -421,11 +409,7 @@ unsigned char BlockLoad(
} }
} }
void BlockRead(unsigned int size, unsigned char mem, ADDR_T *address)
void BlockRead(
unsigned int size,
unsigned char mem,
ADDR_T * address)
{ {
/* EEPROM memory type. */ /* EEPROM memory type. */
if (mem == 'E') { /* Read EEPROM */ if (mem == 'E') { /* Read EEPROM */
@@ -446,7 +430,8 @@ void BlockRead(
do { do {
#ifdef __ICCAVR__ #ifdef __ICCAVR__
#pragma diag_suppress=Pe1053 /* Suppress warning for conversion from long-type address to flash ptr. */ #pragma diag_suppress = Pe1053 /* Suppress warning for conversion from \
long-type address to flash ptr. */
#endif #endif
sendchar(_LOAD_PROGRAM_MEMORY(*address)); sendchar(_LOAD_PROGRAM_MEMORY(*address));
sendchar(_LOAD_PROGRAM_MEMORY((*address) + 1)); sendchar(_LOAD_PROGRAM_MEMORY((*address) + 1));
@@ -462,5 +447,4 @@ void BlockRead(
} }
#endif /* REMOVE_BLOCK_SUPPORT */ #endif /* REMOVE_BLOCK_SUPPORT */
/* end of file */ /* end of file */
+9 -12
View File
@@ -18,27 +18,24 @@
****************************************************************************/ ****************************************************************************/
#include "defines.h" #include "defines.h"
void initbootuart(void)
void initbootuart(
void)
{ {
BAUD_RATE_LOW_REG = BRREG_VALUE; BAUD_RATE_LOW_REG = BRREG_VALUE;
UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) | (1 << ENABLE_TRANSMITTER_BIT); /* enable receive and transmit */ UART_CONTROL_REG = (1 << ENABLE_RECEIVER_BIT) |
(1 << ENABLE_TRANSMITTER_BIT); /* enable receive and transmit */
} }
void sendchar(unsigned char c)
void sendchar(
unsigned char c)
{ {
UART_DATA_REG = c; /* prepare transmission */ UART_DATA_REG = c; /* prepare transmission */
while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT))); /* wait until byte sendt */ while (!(UART_STATUS_REG & (1 << TRANSMIT_COMPLETE_BIT)))
; /* wait until byte sendt */
UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); /* delete TXCflag */ UART_STATUS_REG |= (1 << TRANSMIT_COMPLETE_BIT); /* delete TXCflag */
} }
unsigned char recchar(void)
unsigned char recchar(
void)
{ {
while (!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT))); /* wait for data */ while (!(UART_STATUS_REG & (1 << RECEIVE_COMPLETE_BIT)))
; /* wait for data */
return UART_DATA_REG; return UART_DATA_REG;
} }
+91 -164
View File
@@ -50,10 +50,8 @@
static const char *BACnet_Version = BACNET_VERSION_TEXT; static const char *BACnet_Version = BACNET_VERSION_TEXT;
/* forward prototype */ /* forward prototype */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
BACNET_READ_PROPERTY_DATA * rpdata); bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
bool Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA * wp_data);
static struct my_object_functions { static struct my_object_functions {
BACNET_OBJECT_TYPE Object_Type; BACNET_OBJECT_TYPE Object_Type;
@@ -65,31 +63,28 @@ static struct my_object_functions {
read_property_function Object_Read_Property; read_property_function Object_Read_Property;
write_property_function Object_Write_Property; write_property_function Object_Write_Property;
rpm_property_lists_function Object_RPM_List; rpm_property_lists_function Object_RPM_List;
} Object_Table[] = { } Object_Table[] = { { OBJECT_DEVICE, NULL, /* don't init - recursive! */
{
OBJECT_DEVICE, NULL, /* don't init - recursive! */
Device_Count, Device_Index_To_Instance, Device_Count, Device_Index_To_Instance,
Device_Valid_Object_Instance_Number, Device_Object_Name, Device_Valid_Object_Instance_Number,
Device_Read_Property_Local, Device_Write_Property_Local, Device_Object_Name, Device_Read_Property_Local,
Device_Property_Lists}, { Device_Write_Property_Local, Device_Property_Lists },
OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, { OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
Analog_Input_Object_Name, Analog_Input_Read_Property, NULL, Analog_Input_Object_Name, Analog_Input_Read_Property, NULL,
Analog_Input_Property_Lists}, { Analog_Input_Property_Lists },
OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count, { OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
Analog_Value_Object_Name, Analog_Value_Read_Property, Analog_Value_Object_Name, Analog_Value_Read_Property,
Analog_Value_Write_Property, Analog_Value_Property_Lists}, { Analog_Value_Write_Property, Analog_Value_Property_Lists },
OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, { OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
Binary_Input_Object_Name, Binary_Input_Read_Property, NULL, Binary_Input_Object_Name, Binary_Input_Read_Property, NULL,
Binary_Input_Property_Lists}, { Binary_Input_Property_Lists },
OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, { OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count,
Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance,
Binary_Output_Object_Name, Binary_Output_Read_Property, Binary_Output_Object_Name, Binary_Output_Read_Property,
Binary_Output_Write_Property, Binary_Output_Property_Lists}, { Binary_Output_Write_Property, Binary_Output_Property_Lists },
MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL} { MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL } };
};
/* note: you really only need to define variables for /* note: you really only need to define variables for
properties that are writable or that may change. properties that are writable or that may change.
@@ -102,44 +97,20 @@ static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
static const char *Reinit_Password = "rehmite"; static const char *Reinit_Password = "rehmite";
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Device_Properties_Required[] = { static const int Device_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
PROP_OBJECT_NAME, PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
PROP_OBJECT_TYPE, PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
PROP_SYSTEM_STATUS, PROP_PROTOCOL_REVISION, PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_VENDOR_NAME, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, PROP_OBJECT_LIST,
PROP_VENDOR_IDENTIFIER, PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
PROP_MODEL_NAME, PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES, PROP_DEVICE_ADDRESS_BINDING,
PROP_FIRMWARE_REVISION, PROP_DATABASE_REVISION, -1 };
PROP_APPLICATION_SOFTWARE_VERSION,
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_REVISION,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_OBJECT_LIST,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_DEVICE_ADDRESS_BINDING,
PROP_DATABASE_REVISION,
-1
};
static const int Device_Properties_Optional[] = { static const int Device_Properties_Optional[] = { PROP_MAX_MASTER,
PROP_MAX_MASTER, PROP_MAX_INFO_FRAMES, PROP_DESCRIPTION, PROP_LOCATION, -1 };
PROP_MAX_INFO_FRAMES,
PROP_DESCRIPTION,
PROP_LOCATION,
-1
};
static const int Device_Properties_Proprietary[] = { static const int Device_Properties_Proprietary[] = { 512, 513, 9600, -1 };
512,
513,
9600,
-1
};
static struct my_object_functions *Device_Objects_Find_Functions( static struct my_object_functions *Device_Objects_Find_Functions(
BACNET_OBJECT_TYPE Object_Type) BACNET_OBJECT_TYPE Object_Type)
@@ -161,8 +132,7 @@ static struct my_object_functions *Device_Objects_Find_Functions(
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns BACNET_STATUS_ERROR */ or sets the error, and returns BACNET_STATUS_ERROR */
int Device_Read_Property( int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = BACNET_STATUS_ERROR; int apdu_len = BACNET_STATUS_ERROR;
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -183,8 +153,7 @@ int Device_Read_Property(
return apdu_len; return apdu_len;
} }
bool Device_Write_Property( bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; bool status = false;
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -212,8 +181,7 @@ bool Device_Write_Property(
return status; return status;
} }
static unsigned my_property_list_count( static unsigned my_property_list_count(const int *pList)
const int *pList)
{ {
unsigned property_count = 0; unsigned property_count = 0;
@@ -228,8 +196,7 @@ static unsigned my_property_list_count(
} }
/* for a given object type, returns the special property list */ /* for a given object type, returns the special property list */
void Device_Objects_Property_List( void Device_Objects_Property_List(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
struct special_property_list_t *pPropertyList) struct special_property_list_t *pPropertyList)
{ {
@@ -252,25 +219,23 @@ void Device_Objects_Property_List(
} }
/* Fetch the counts if available otherwise zero them */ /* Fetch the counts if available otherwise zero them */
pPropertyList->Required.count = pPropertyList->Required.count = pPropertyList->Required.pList == NULL
pPropertyList->Required.pList == ? 0
NULL ? 0 : my_property_list_count(pPropertyList->Required.pList); : my_property_list_count(pPropertyList->Required.pList);
pPropertyList->Optional.count = pPropertyList->Optional.count = pPropertyList->Optional.pList == NULL
pPropertyList->Optional.pList == ? 0
NULL ? 0 : my_property_list_count(pPropertyList->Optional.pList); : my_property_list_count(pPropertyList->Optional.pList);
pPropertyList->Proprietary.count = pPropertyList->Proprietary.count = pPropertyList->Proprietary.pList == NULL
pPropertyList->Proprietary.pList == ? 0
NULL ? 0 : my_property_list_count(pPropertyList->Proprietary.pList); : my_property_list_count(pPropertyList->Proprietary.pList);
return; return;
} }
void Device_Property_Lists( void Device_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Device_Properties_Required; *pRequired = Device_Properties_Required;
@@ -282,21 +247,18 @@ void Device_Property_Lists(
return; return;
} }
unsigned Device_Count( unsigned Device_Count(void)
void)
{ {
return 1; return 1;
} }
uint32_t Device_Index_To_Instance( uint32_t Device_Index_To_Instance(unsigned index)
unsigned index)
{ {
index = index; index = index;
return Object_Instance_Number; return Object_Instance_Number;
} }
static char *Device_Name_Default( static char *Device_Name_Default(void)
void)
{ {
static char text_string[32]; /* okay for single thread */ static char text_string[32]; /* okay for single thread */
@@ -306,8 +268,7 @@ static char *Device_Name_Default(
} }
bool Device_Object_Name( bool Device_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
bool status = false; bool status = false;
@@ -319,8 +280,7 @@ bool Device_Object_Name(
return status; return status;
} }
bool Device_Reinitialize( bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
BACNET_REINITIALIZE_DEVICE_DATA * rd_data)
{ {
bool status = false; bool status = false;
@@ -363,14 +323,12 @@ bool Device_Reinitialize(
return status; return status;
} }
BACNET_REINITIALIZED_STATE Device_Reinitialized_State( BACNET_REINITIALIZED_STATE Device_Reinitialized_State(void)
void)
{ {
return Reinitialize_State; return Reinitialize_State;
} }
void Device_Init( void Device_Init(object_functions_t *object_table)
object_functions_t * object_table)
{ {
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -389,14 +347,12 @@ void Device_Init(
} }
/* methods to manipulate the data */ /* methods to manipulate the data */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(void)
void)
{ {
return Object_Instance_Number; return Object_Instance_Number;
} }
bool Device_Set_Object_Instance_Number( bool Device_Set_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
@@ -411,21 +367,17 @@ bool Device_Set_Object_Instance_Number(
return status; return status;
} }
bool Device_Valid_Object_Instance_Number( bool Device_Valid_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
return (Object_Instance_Number == object_id); return (Object_Instance_Number == object_id);
} }
BACNET_DEVICE_STATUS Device_System_Status( BACNET_DEVICE_STATUS Device_System_Status(void)
void)
{ {
return System_Status; return System_Status;
} }
int Device_Set_System_Status( int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
BACNET_DEVICE_STATUS status,
bool local)
{ {
/*return value - 0 = ok, -1 = bad value, -2 = not allowed */ /*return value - 0 = ok, -1 = bad value, -2 = not allowed */
int result = -1; int result = -1;
@@ -438,34 +390,29 @@ int Device_Set_System_Status(
return result; return result;
} }
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(void)
void)
{ {
return BACNET_VENDOR_ID; return BACNET_VENDOR_ID;
} }
BACNET_SEGMENTATION Device_Segmentation_Supported( BACNET_SEGMENTATION Device_Segmentation_Supported(void)
void)
{ {
return SEGMENTATION_NONE; return SEGMENTATION_NONE;
} }
uint32_t Device_Database_Revision( uint32_t Device_Database_Revision(void)
void)
{ {
return Database_Revision; return Database_Revision;
} }
void Device_Inc_Database_Revision( void Device_Inc_Database_Revision(void)
void)
{ {
Database_Revision++; Database_Revision++;
} }
/* Since many network clients depend on the object list */ /* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */ /* for discovery, it must be consistent! */
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(void)
void)
{ {
unsigned count = 0; /* number of objects */ unsigned count = 0; /* number of objects */
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -483,9 +430,7 @@ unsigned Device_Object_List_Count(
} }
bool Device_Object_List_Identifier( bool Device_Object_List_Identifier(
uint32_t array_index, uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
BACNET_OBJECT_TYPE *object_type,
uint32_t * instance)
{ {
bool status = false; bool status = false;
uint32_t count = 0; uint32_t count = 0;
@@ -516,8 +461,7 @@ bool Device_Object_List_Identifier(
return status; return status;
} }
bool Device_Valid_Object_Name( bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
BACNET_CHARACTER_STRING * object_name1,
BACNET_OBJECT_TYPE *object_type, BACNET_OBJECT_TYPE *object_type,
uint32_t *object_instance) uint32_t *object_instance)
{ {
@@ -553,8 +497,7 @@ bool Device_Valid_Object_Name(
} }
bool Device_Valid_Object_Id( bool Device_Valid_Object_Id(
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
uint32_t object_instance)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
struct my_object_functions *pObject = NULL; struct my_object_functions *pObject = NULL;
@@ -567,8 +510,7 @@ bool Device_Valid_Object_Id(
return status; return status;
} }
bool Device_Object_Name_Copy( bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
@@ -584,8 +526,7 @@ bool Device_Object_Name_Copy(
} }
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */ /* return the length of the apdu encoded or BACNET_STATUS_ERROR for error */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */ int len = 0; /* apdu len intermediate value */
@@ -605,9 +546,8 @@ int Device_Read_Property_Local(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch ((int)rpdata->object_property) { switch ((int)rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], rpdata->object_type, &apdu[0], rpdata->object_type, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Device_Object_Name(rpdata->object_instance, &char_string); Device_Object_Name(rpdata->object_instance, &char_string);
@@ -625,15 +565,14 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_LOCATION: case PROP_LOCATION:
bacnet_name(NV_EEPROM_DEVICE_LOCATION, &char_string, bacnet_name(
"default location"); NV_EEPROM_DEVICE_LOCATION, &char_string, "default location");
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_SYSTEM_STATUS: case PROP_SYSTEM_STATUS:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], Device_System_Status());
Device_System_Status());
break; break;
case PROP_VENDOR_NAME: case PROP_VENDOR_NAME:
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME); characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
@@ -664,8 +603,7 @@ int Device_Read_Property_Local(
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], BACNET_PROTOCOL_REVISION);
BACNET_PROTOCOL_REVISION);
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */ /* Note: list of services that are executed, not initiated. */
@@ -707,11 +645,10 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */ /* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
if (Device_Object_List_Identifier(i, &object_type, if (Device_Object_List_Identifier(
&instance)) { i, &object_type, &instance)) {
len = len = encode_application_object_id(
encode_application_object_id(&apdu[apdu_len], &apdu[apdu_len], object_type, instance);
object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
@@ -731,11 +668,10 @@ int Device_Read_Property_Local(
} }
} }
} else { } else {
if (Device_Object_List_Identifier(rpdata->array_index, if (Device_Object_List_Identifier(
&object_type, &instance)) rpdata->array_index, &object_type, &instance))
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], object_type, &apdu[0], object_type, instance);
instance);
else { else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -747,9 +683,8 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break; break;
case PROP_SEGMENTATION_SUPPORTED: case PROP_SEGMENTATION_SUPPORTED:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Device_Segmentation_Supported());
Device_Segmentation_Supported());
break; break;
case PROP_APDU_TIMEOUT: case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout()); apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
@@ -761,14 +696,12 @@ int Device_Read_Property_Local(
/* 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 = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Database_Revision());
Device_Database_Revision());
break; break;
case PROP_MAX_INFO_FRAMES: case PROP_MAX_INFO_FRAMES:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
dlmstp_max_info_frames());
break; break;
case PROP_MAX_MASTER: case PROP_MAX_MASTER:
apdu_len = apdu_len =
@@ -781,8 +714,7 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], stack_unused()); apdu_len = encode_application_unsigned(&apdu[0], stack_unused());
break; break;
case 9600: case 9600:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0], rs485_baud_rate());
encode_application_unsigned(&apdu[0], rs485_baud_rate());
break; break;
default: default:
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -801,8 +733,7 @@ int Device_Read_Property_Local(
return apdu_len; return apdu_len;
} }
bool Device_Write_Property_Local( bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value - false=error */ bool status = false; /* return value - false=error */
int len = 0; int len = 0;
@@ -810,9 +741,8 @@ bool Device_Write_Property_Local(
uint8_t max_master = 0; uint8_t max_master = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -831,8 +761,8 @@ bool Device_Write_Property_Local(
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(value.type. (Device_Set_Object_Instance_Number(
Object_Id.instance))) { value.type.Object_Id.instance))) {
eeprom_bytes_write(NV_EEPROM_DEVICE_0, eeprom_bytes_write(NV_EEPROM_DEVICE_0,
(uint8_t *)&value.type.Object_Id.instance, 4); (uint8_t *)&value.type.Object_Id.instance, 4);
/* we could send an I-Am broadcast to let the world know */ /* we could send an I-Am broadcast to let the world know */
@@ -879,8 +809,7 @@ bool Device_Write_Property_Local(
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status = status = bacnet_name_write_unique(NV_EEPROM_DEVICE_NAME,
bacnet_name_write_unique(NV_EEPROM_DEVICE_NAME,
wp_data->object_type, wp_data->object_instance, wp_data->object_type, wp_data->object_instance,
&value.type.Character_String, &wp_data->error_class, &value.type.Character_String, &wp_data->error_class,
&wp_data->error_code); &wp_data->error_code);
@@ -891,8 +820,7 @@ bool Device_Write_Property_Local(
break; break;
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status = status = bacnet_name_write(NV_EEPROM_DEVICE_DESCRIPTION,
bacnet_name_write(NV_EEPROM_DEVICE_DESCRIPTION,
&value.type.Character_String, &wp_data->error_class, &value.type.Character_String, &wp_data->error_class,
&wp_data->error_code); &wp_data->error_code);
} else { } else {
@@ -902,8 +830,7 @@ bool Device_Write_Property_Local(
break; break;
case PROP_LOCATION: case PROP_LOCATION:
if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) { if (value.tag == BACNET_APPLICATION_TAG_CHARACTER_STRING) {
status = status = bacnet_name_write(NV_EEPROM_DEVICE_LOCATION,
bacnet_name_write(NV_EEPROM_DEVICE_LOCATION,
&value.type.Character_String, &wp_data->error_class, &value.type.Character_String, &wp_data->error_class,
&wp_data->error_code); &wp_data->error_code);
} else { } else {
+47 -68
View File
@@ -182,7 +182,11 @@ static uint8_t Nmax_master = 127;
#define Tusage_delay 15 #define Tusage_delay 15
/* we need to be able to increment without rolling over */ /* we need to be able to increment without rolling over */
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} #define INCREMENT_AND_LIMIT_UINT8(x) \
{ \
if (x < 0xFF) \
x++; \
}
/* data structure for MS/TP PDU Queue */ /* data structure for MS/TP PDU Queue */
struct mstp_pdu_packet { struct mstp_pdu_packet {
@@ -194,8 +198,7 @@ struct mstp_pdu_packet {
static struct mstp_pdu_packet PDU_Buffer[MSTP_PDU_PACKET_COUNT]; static struct mstp_pdu_packet PDU_Buffer[MSTP_PDU_PACKET_COUNT];
static RING_BUFFER PDU_Queue; static RING_BUFFER PDU_Queue;
bool dlmstp_init( bool dlmstp_init(char *ifname)
char *ifname)
{ {
ifname = ifname; ifname = ifname;
@@ -205,15 +208,12 @@ bool dlmstp_init(
return true; return true;
} }
void dlmstp_cleanup( void dlmstp_cleanup(void)
void)
{ {
/* nothing to do for static buffers */ /* nothing to do for static buffers */
} }
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
BACNET_ADDRESS * src,
uint8_t mstp_address)
{ {
int i = 0; int i = 0;
@@ -236,8 +236,7 @@ void dlmstp_fill_bacnet_address(
} }
} }
static bool dlmstp_compare_data_expecting_reply( static bool dlmstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint8_t * request_pdu,
uint16_t request_pdu_len, uint16_t request_pdu_len,
uint8_t src_address, uint8_t src_address,
uint8_t *reply_pdu, uint8_t *reply_pdu,
@@ -261,9 +260,8 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the request data */ /* decode the request data */
request.address.mac[0] = src_address; request.address.mac[0] = src_address;
request.address.mac_len = 1; request.address.mac_len = 1;
offset = offset = npdu_decode(
npdu_decode(&request_pdu[0], NULL, &request.address, &request_pdu[0], NULL, &request.address, &request.npdu_data);
&request.npdu_data);
if (request.npdu_data.network_layer_message) { if (request.npdu_data.network_layer_message) {
return false; return false;
} }
@@ -280,8 +278,7 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */ /* decode the reply data */
reply.address.mac[0] = dest_address; reply.address.mac[0] = dest_address;
reply.address.mac_len = 1; reply.address.mac_len = 1;
offset = offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
return false; return false;
} }
@@ -322,7 +319,8 @@ static bool dlmstp_compare_data_expecting_reply(
return false; return false;
} }
} }
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) { if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false; return false;
} }
#if 0 #if 0
@@ -401,8 +399,7 @@ static void MSTP_Send_Frame(
rs485_rts_enable(false); rs485_rts_enable(false);
} }
static void MSTP_Receive_Frame_FSM( static void MSTP_Receive_Frame_FSM(void)
void)
{ {
/* stores the latest received data octet */ /* stores the latest received data octet */
uint8_t DataRegister = 0; uint8_t DataRegister = 0;
@@ -638,8 +635,7 @@ static void MSTP_Receive_Frame_FSM(
#ifdef MSTP_DEBUG_STATES #ifdef MSTP_DEBUG_STATES
static MSTP_MASTER_STATE Master_State_Log[128]; static MSTP_MASTER_STATE Master_State_Log[128];
static unsigned master_state_log_index = 0; static unsigned master_state_log_index = 0;
void log_master_state( void log_master_state(MSTP_MASTER_STATE state)
MSTP_MASTER_STATE state)
{ {
Master_State_Log[master_state_log_index] = state; Master_State_Log[master_state_log_index] = state;
master_state_log_index++; master_state_log_index++;
@@ -652,8 +648,7 @@ void log_master_state(
#endif #endif
/* returns true if we need to transition immediately */ /* returns true if we need to transition immediately */
static bool MSTP_Master_Node_FSM( static bool MSTP_Master_Node_FSM(void)
void)
{ {
/* The number of frames sent by this node during a single token hold. */ /* The number of frames sent by this node during a single token hold. */
/* When this counter reaches the value Nmax_info_frames, the node must */ /* When this counter reaches the value Nmax_info_frames, the node must */
@@ -758,9 +753,8 @@ static bool MSTP_Master_Node_FSM(
} }
break; break;
case FRAME_TYPE_TEST_REQUEST: case FRAME_TYPE_TEST_REQUEST:
MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress,
SourceAddress, This_Station, &InputBuffer[0], This_Station, &InputBuffer[0], DataLength);
DataLength);
break; break;
case FRAME_TYPE_TEST_RESPONSE: case FRAME_TYPE_TEST_RESPONSE:
default: default:
@@ -924,8 +918,8 @@ static bool MSTP_Master_Node_FSM(
may be found in that case. */ may be found in that case. */
TokenCount++; TokenCount++;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
RetryCount = 0; RetryCount = 0;
EventCount = 0; EventCount = 0;
Master_State = MSTP_MASTER_STATE_PASS_TOKEN; Master_State = MSTP_MASTER_STATE_PASS_TOKEN;
@@ -947,8 +941,8 @@ static bool MSTP_Master_Node_FSM(
/* ResetMaintenancePFM */ /* ResetMaintenancePFM */
Poll_Station = This_Station; Poll_Station = This_Station;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
RetryCount = 0; RetryCount = 0;
TokenCount = 1; /* changed in Errata SSPC-135-2004 */ TokenCount = 1; /* changed in Errata SSPC-135-2004 */
EventCount = 0; EventCount = 0;
@@ -971,8 +965,8 @@ static bool MSTP_Master_Node_FSM(
/* RetrySendToken */ /* RetrySendToken */
RetryCount++; RetryCount++;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
EventCount = 0; EventCount = 0;
/* re-enter the current state to listen for NS */ /* re-enter the current state to listen for NS */
/* to begin using the token. */ /* to begin using the token. */
@@ -1049,15 +1043,15 @@ static bool MSTP_Master_Node_FSM(
/* a successor node. */ /* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (MSTP_Flag.ReceivedValidFrame == true) { if (MSTP_Flag.ReceivedValidFrame == true) {
if ((DestinationAddress == This_Station) if ((DestinationAddress == This_Station) &&
&& (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { (FrameType == FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */ /* ReceivedReplyToPFM */
MSTP_Flag.SoleMaster = false; MSTP_Flag.SoleMaster = false;
Next_Station = SourceAddress; Next_Station = SourceAddress;
EventCount = 0; EventCount = 0;
/* Transmit a Token frame to NS */ /* Transmit a Token frame to NS */
MSTP_Send_Frame(FRAME_TYPE_TOKEN, Next_Station, MSTP_Send_Frame(
This_Station, NULL, 0); FRAME_TYPE_TOKEN, Next_Station, This_Station, NULL, 0);
Poll_Station = This_Station; Poll_Station = This_Station;
TokenCount = 0; TokenCount = 0;
RetryCount = 0; RetryCount = 0;
@@ -1124,10 +1118,9 @@ static bool MSTP_Master_Node_FSM(
if (!timeout) { if (!timeout) {
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
if (pkt != NULL) { if (pkt != NULL) {
matched = matched = dlmstp_compare_data_expecting_reply(
dlmstp_compare_data_expecting_reply(&InputBuffer[0], &InputBuffer[0], DataLength, SourceAddress,
DataLength, SourceAddress, &pkt->buffer[0], &pkt->buffer[0], pkt->length, pkt->destination_mac);
pkt->length, pkt->destination_mac);
} else { } else {
matched = false; matched = false;
} }
@@ -1144,12 +1137,10 @@ static bool MSTP_Master_Node_FSM(
if (pkt->data_expecting_reply) { if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else { } else {
frame_type = frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
} }
MSTP_Send_Frame(frame_type, pkt->destination_mac, MSTP_Send_Frame(frame_type, pkt->destination_mac, This_Station,
This_Station, (uint8_t *) & pkt->buffer[0], (uint8_t *)&pkt->buffer[0], pkt->length);
pkt->length);
Master_State = MSTP_MASTER_STATE_IDLE; Master_State = MSTP_MASTER_STATE_IDLE;
/* clear our flag we were holding for comparison */ /* clear our flag we were holding for comparison */
MSTP_Flag.ReceivedValidFrame = false; MSTP_Flag.ReceivedValidFrame = false;
@@ -1180,8 +1171,7 @@ static bool MSTP_Master_Node_FSM(
return transition_now; return transition_now;
} }
static void MSTP_Slave_Node_FSM( static void MSTP_Slave_Node_FSM(void)
void)
{ {
/* packet from the PDU Queue */ /* packet from the PDU Queue */
struct mstp_pdu_packet *pkt; struct mstp_pdu_packet *pkt;
@@ -1216,8 +1206,7 @@ static void MSTP_Slave_Node_FSM(
} else if (MSTP_Flag.ReceivePacketPending) { } else if (MSTP_Flag.ReceivePacketPending) {
if (!Ringbuf_Empty(&PDU_Queue)) { if (!Ringbuf_Empty(&PDU_Queue)) {
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
matched = matched = dlmstp_compare_data_expecting_reply(&InputBuffer[0],
dlmstp_compare_data_expecting_reply(&InputBuffer[0],
DataLength, SourceAddress, &pkt->buffer[0], pkt->length, DataLength, SourceAddress, &pkt->buffer[0], pkt->length,
pkt->destination_mac); pkt->destination_mac);
if (matched) { if (matched) {
@@ -1252,8 +1241,7 @@ static void MSTP_Slave_Node_FSM(
} }
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu( int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -1284,8 +1272,7 @@ int dlmstp_send_pdu(
} }
/* Return the length of the packet */ /* Return the length of the packet */
uint16_t dlmstp_receive( uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -1335,8 +1322,7 @@ uint16_t dlmstp_receive(
return pdu_len; return pdu_len;
} }
void dlmstp_set_mac_address( void dlmstp_set_mac_address(uint8_t mac_address)
uint8_t mac_address)
{ {
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
@@ -1348,8 +1334,7 @@ void dlmstp_set_mac_address(
return; return;
} }
uint8_t dlmstp_mac_address( uint8_t dlmstp_mac_address(void)
void)
{ {
return This_Station; return This_Station;
} }
@@ -1361,8 +1346,7 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */ /* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(uint8_t max_info_frames)
uint8_t max_info_frames)
{ {
if (max_info_frames >= MSTP_PDU_PACKET_COUNT) { if (max_info_frames >= MSTP_PDU_PACKET_COUNT) {
Nmax_info_frames = max_info_frames; Nmax_info_frames = max_info_frames;
@@ -1371,8 +1355,7 @@ void dlmstp_set_max_info_frames(
return; return;
} }
uint8_t dlmstp_max_info_frames( uint8_t dlmstp_max_info_frames(void)
void)
{ {
return Nmax_info_frames; return Nmax_info_frames;
} }
@@ -1382,8 +1365,7 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */ /* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
void dlmstp_set_max_master( void dlmstp_set_max_master(uint8_t max_master)
uint8_t max_master)
{ {
if (max_master <= 127) { if (max_master <= 127) {
if (This_Station <= max_master) { if (This_Station <= max_master) {
@@ -1394,14 +1376,12 @@ void dlmstp_set_max_master(
return; return;
} }
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void)
void)
{ {
return Nmax_master; return Nmax_master;
} }
void dlmstp_get_my_address( void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
@@ -1416,8 +1396,7 @@ void dlmstp_get_my_address(
return; return;
} }
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
+1 -3
View File
@@ -29,7 +29,6 @@
/* Internal EEPROM of the AVR - http://supp.iar.com/Support/?note=45745 */ /* Internal EEPROM of the AVR - http://supp.iar.com/Support/?note=45745 */
int eeprom_bytes_read( int eeprom_bytes_read(
uint16_t eeaddr, /* EEPROM starting memory address (offset of zero) */ uint16_t eeaddr, /* EEPROM starting memory address (offset of zero) */
uint8_t *buf, /* data to store */ uint8_t *buf, /* data to store */
@@ -47,8 +46,7 @@ int eeprom_bytes_read(
return count; return count;
} }
int eeprom_bytes_write( int eeprom_bytes_write(uint16_t eeaddr, /* EEPROM starting memory address */
uint16_t eeaddr, /* EEPROM starting memory address */
uint8_t *buf, /* data to send */ uint8_t *buf, /* data to send */
int len) int len)
{ /* number of bytes of data */ { /* number of bytes of data */
+1 -2
View File
@@ -26,8 +26,7 @@
/* me */ /* me */
#include "init.h" #include "init.h"
void init( void init(void)
void)
{ {
/* clear the MCU Status Register */ /* clear the MCU Status Register */
MCUSR = 0; MCUSR = 0;
+6 -13
View File
@@ -43,8 +43,7 @@ static struct mstimer Debounce_Timer;
#if BDK_V1_HACK #if BDK_V1_HACK
/* version 1 BDK workaournd for floating inputs */ /* version 1 BDK workaournd for floating inputs */
static void input_switch_workaround( static void input_switch_workaround(void)
void)
{ {
/* configure the port pins for the switch - as outputs */ /* configure the port pins for the switch - as outputs */
BIT_SET(DDRA, DDA0); BIT_SET(DDRA, DDA0);
@@ -76,8 +75,7 @@ static void input_switch_workaround(
#endif #endif
/* debounce the inputs */ /* debounce the inputs */
void input_task( void input_task(void)
void)
{ {
uint8_t value; uint8_t value;
static uint8_t old_address = 0; static uint8_t old_address = 0;
@@ -119,20 +117,17 @@ void input_task(
#endif #endif
} }
uint8_t input_address( uint8_t input_address(void)
void)
{ {
return Address_Switch; return Address_Switch;
} }
uint8_t input_rotary_value( uint8_t input_rotary_value(uint8_t index)
uint8_t index)
{ {
return Buttons; return Buttons;
} }
bool input_button_value( bool input_button_value(uint8_t index)
uint8_t index)
{ {
bool value = false; bool value = false;
@@ -159,9 +154,7 @@ bool input_button_value(
return value; return value;
} }
void input_init(void)
void input_init(
void)
{ {
/* configure the port pins for the switch */ /* configure the port pins for the switch */
BIT_CLEAR(DDRA, DDA0); BIT_CLEAR(DDRA, DDA0);
+8 -18
View File
@@ -37,8 +37,7 @@ static struct mstimer Off_Delay_Timer[MAX_LEDS];
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_on( void led_on(uint8_t index)
uint8_t index)
{ {
switch (index) { switch (index) {
case 0: case 0:
@@ -74,8 +73,7 @@ void led_on(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_off( void led_off(uint8_t index)
uint8_t index)
{ {
switch (index) { switch (index) {
case 0: case 0:
@@ -111,8 +109,7 @@ void led_off(
* Returns: true if on, false if off. * Returns: true if on, false if off.
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
bool led_state( bool led_state(uint8_t index)
uint8_t index)
{ {
switch (index) { switch (index) {
case 0: case 0:
@@ -143,8 +140,7 @@ bool led_state(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_toggle( void led_toggle(uint8_t index)
uint8_t index)
{ {
if (led_state(index)) { if (led_state(index)) {
led_off(index); led_off(index);
@@ -158,9 +154,7 @@ void led_toggle(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_off_delay( void led_off_delay(uint8_t index, uint32_t delay_ms)
uint8_t index,
uint32_t delay_ms)
{ {
if (index < MAX_LEDS) { if (index < MAX_LEDS) {
mstimer_set(&Off_Delay_Timer[index], delay_ms); mstimer_set(&Off_Delay_Timer[index], delay_ms);
@@ -172,9 +166,7 @@ void led_off_delay(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_on_interval( void led_on_interval(uint8_t index, uint16_t interval_ms)
uint8_t index,
uint16_t interval_ms)
{ {
if (index < MAX_LEDS) { if (index < MAX_LEDS) {
led_on(index); led_on(index);
@@ -187,8 +179,7 @@ void led_on_interval(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_task( void led_task(void)
void)
{ {
uint8_t i; /* loop counter */ uint8_t i; /* loop counter */
@@ -205,8 +196,7 @@ void led_task(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void led_init( void led_init(void)
void)
{ {
uint8_t i; /* loop counter */ uint8_t i; /* loop counter */
+1 -2
View File
@@ -47,8 +47,7 @@ char *BACnet_Version = BACNET_VERSION_TEXT;
/* For porting to IAR, see: /* For porting to IAR, see:
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
int main( int main(void)
void)
{ {
init(); init();
/* Configure the watchdog timer - Disabled for debugging */ /* Configure the watchdog timer - Disabled for debugging */
+4 -8
View File
@@ -32,8 +32,7 @@
/* Timer2 Prescaling: 1, 8, 32, 64, 128, 256, or 1024 */ /* Timer2 Prescaling: 1, 8, 32, 64, 128, 256, or 1024 */
#define TIMER_MICROSECONDS 1000UL #define TIMER_MICROSECONDS 1000UL
#define TIMER_TICKS(p) \ #define TIMER_TICKS(p) \
(((((F_CPU)/(p))/1000UL) \ (((((F_CPU) / (p)) / 1000UL) * (TIMER_MICROSECONDS)) / 1000UL)
*(TIMER_MICROSECONDS))/1000UL)
#define TIMER_TICKS_MAX 255UL #define TIMER_TICKS_MAX 255UL
/* adjust the prescaler for the processor clock */ /* adjust the prescaler for the processor clock */
#if (TIMER_TICKS(1) <= TIMER_TICKS_MAX) #if (TIMER_TICKS(1) <= TIMER_TICKS_MAX)
@@ -65,8 +64,7 @@ static volatile uint32_t Millisecond_Counter;
* Returns: nothing * Returns: nothing
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
static inline void timer_interrupt_handler( static inline void timer_interrupt_handler(void)
void)
{ {
/* Set the counter for the next interrupt */ /* Set the counter for the next interrupt */
TCNT2 = TIMER2_COUNT; TCNT2 = TIMER2_COUNT;
@@ -88,8 +86,7 @@ ISR(TIMER2_OVF_vect)
* Returns: none * Returns: none
* Notes: This method only disables the timer overflow interrupt. * Notes: This method only disables the timer overflow interrupt.
*************************************************************************/ *************************************************************************/
unsigned long mstimer_now( unsigned long mstimer_now(void)
void)
{ {
unsigned long timer_value; /* return value */ unsigned long timer_value; /* return value */
@@ -108,8 +105,7 @@ unsigned long mstimer_now(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
void mstimer_init( void mstimer_init(void)
void)
{ {
/* Normal Operation */ /* Normal Operation */
TCCR2A = 0; TCCR2A = 0;
+15 -30
View File
@@ -58,8 +58,7 @@ static struct mstimer Silence_Timer;
* RETURN: true if the amount of silence time has elapsed * RETURN: true if the amount of silence time has elapsed
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool rs485_silence_time_elapsed( bool rs485_silence_time_elapsed(uint16_t milliseconds)
uint16_t milliseconds)
{ {
return (mstimer_elapsed(&Silence_Timer) > milliseconds); return (mstimer_elapsed(&Silence_Timer) > milliseconds);
} }
@@ -69,8 +68,7 @@ bool rs485_silence_time_elapsed(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void rs485_silence_time_reset( void rs485_silence_time_reset(void)
void)
{ {
mstimer_set(&Silence_Timer, 0); mstimer_set(&Silence_Timer, 0);
} }
@@ -80,8 +78,7 @@ void rs485_silence_time_reset(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void rs485_rts_init( static void rs485_rts_init(void)
void)
{ {
/* configure the port pin as an output */ /* configure the port pin as an output */
BIT_SET(DDRD, DDD4); BIT_SET(DDRD, DDD4);
@@ -92,8 +89,7 @@ static void rs485_rts_init(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void rs485_rts_enable( void rs485_rts_enable(bool enable)
bool enable)
{ {
if (enable) { if (enable) {
BIT_SET(PORTD, PD4); BIT_SET(PORTD, PD4);
@@ -107,8 +103,7 @@ void rs485_rts_enable(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void rs485_receiver_enable( static void rs485_receiver_enable(void)
void)
{ {
UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0); UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);
} }
@@ -118,8 +113,7 @@ static void rs485_receiver_enable(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void rs485_turnaround_delay( void rs485_turnaround_delay(void)
void)
{ {
uint8_t nbytes = 4; uint8_t nbytes = 4;
@@ -167,8 +161,7 @@ ISR(USART0_RX_vect)
* RETURN: none * RETURN: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool rs485_byte_available( bool rs485_byte_available(uint8_t *data_register)
uint8_t * data_register)
{ {
bool data_available = false; /* return value */ bool data_available = false; /* return value */
@@ -188,8 +181,7 @@ bool rs485_byte_available(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool rs485_receive_error( bool rs485_receive_error(void)
void)
{ {
return false; return false;
} }
@@ -199,8 +191,7 @@ bool rs485_receive_error(
* RETURN: none * RETURN: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void rs485_bytes_send( void rs485_bytes_send(uint8_t *buffer, /* data to send */
uint8_t * buffer, /* data to send */
uint16_t nbytes) uint16_t nbytes)
{ /* number of bytes of data */ { /* number of bytes of data */
led_on(LED_5); led_on(LED_5);
@@ -237,8 +228,7 @@ void rs485_bytes_send(
* RETURN: baud rate in bps * RETURN: baud rate in bps
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t rs485_baud_rate( uint32_t rs485_baud_rate(void)
void)
{ {
return Baud_Rate; return Baud_Rate;
} }
@@ -248,8 +238,7 @@ uint32_t rs485_baud_rate(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void rs485_baud_rate_configure( static void rs485_baud_rate_configure(void)
void)
{ {
/* 2x speed mode */ /* 2x speed mode */
BIT_SET(UCSR0A, U2X0); BIT_SET(UCSR0A, U2X0);
@@ -262,8 +251,7 @@ static void rs485_baud_rate_configure(
* RETURN: true if the baud rate is valid * RETURN: true if the baud rate is valid
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool rs485_baud_rate_set( bool rs485_baud_rate_set(uint32_t baud)
uint32_t baud)
{ {
bool valid = true; bool valid = true;
uint8_t baud_k = 0; uint8_t baud_k = 0;
@@ -294,8 +282,7 @@ bool rs485_baud_rate_set(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void rs485_usart_init( static void rs485_usart_init(void)
void)
{ {
/* enable the internal pullup on RXD0 */ /* enable the internal pullup on RXD0 */
BIT_CLEAR(DDRD, DDD0); BIT_CLEAR(DDRD, DDD0);
@@ -318,8 +305,7 @@ static void rs485_usart_init(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
static void rs485_init_nvdata( static void rs485_init_nvdata(void)
void)
{ {
uint8_t baud_k = 9; /* from EEPROM value */ uint8_t baud_k = 9; /* from EEPROM value */
@@ -358,8 +344,7 @@ static void rs485_init_nvdata(
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void rs485_init( void rs485_init(void)
void)
{ {
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
(unsigned)sizeof(Receive_Buffer_Data)); (unsigned)sizeof(Receive_Buffer_Data));
+24 -18
View File
@@ -57,7 +57,8 @@
#endif #endif
/* The lower 3 bits of TWSR are reserved on the ATmega163 */ /* The lower 3 bits of TWSR are reserved on the ATmega163 */
#define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3)) #define TW_STATUS_MASK \
(_BV(TWS7) | _BV(TWS6) | _BV(TWS5) | _BV(TWS4) | _BV(TWS3))
/* start condition transmitted */ /* start condition transmitted */
#define TW_START 0x08 #define TW_START 0x08
/* repeated start condition transmitted */ /* repeated start condition transmitted */
@@ -100,8 +101,7 @@
* RETURN: number of bytes read, or -1 on error * RETURN: number of bytes read, or -1 on error
* NOTES: none * NOTES: none
**************************************************************************/ **************************************************************************/
int seeprom_bytes_read( int seeprom_bytes_read(uint16_t eeaddr, /* SEEPROM starting memory address */
uint16_t eeaddr, /* SEEPROM starting memory address */
uint8_t *buf, /* data to store */ uint8_t *buf, /* data to store */
int len) int len)
{ /* number of bytes of data to read */ { /* number of bytes of data to read */
@@ -159,7 +159,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_SLA_ACK: case TW_MT_SLA_ACK:
@@ -184,7 +185,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
@@ -203,7 +205,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
@@ -229,7 +232,8 @@ int seeprom_bytes_read(
/* send repeated start condition */ /* send repeated start condition */
TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_START: case TW_START:
@@ -247,7 +251,8 @@ int seeprom_bytes_read(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MR_SLA_ACK: case TW_MR_SLA_ACK:
@@ -272,7 +277,8 @@ int seeprom_bytes_read(
/* clear int to start transmission */ /* clear int to start transmission */
TWCR = twcr; TWCR = twcr;
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MR_DATA_NACK: case TW_MR_DATA_NACK:
@@ -373,7 +379,8 @@ static int seeprom_bytes_write_page(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_SLA_ACK: case TW_MT_SLA_ACK:
@@ -394,7 +401,8 @@ static int seeprom_bytes_write_page(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
@@ -413,8 +421,7 @@ static int seeprom_bytes_write_page(
/* clear interrupt to start transmission */ /* clear interrupt to start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0) { while ((TWCR & _BV(TWINT)) == 0) { };
};
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_ACK: case TW_MT_DATA_ACK:
@@ -432,7 +439,8 @@ static int seeprom_bytes_write_page(
/* start transmission */ /* start transmission */
TWCR = _BV(TWINT) | _BV(TWEN); TWCR = _BV(TWINT) | _BV(TWEN);
/* wait for transmission */ /* wait for transmission */
while ((TWCR & _BV(TWINT)) == 0); while ((TWCR & _BV(TWINT)) == 0)
;
twst = TWSR & TW_STATUS_MASK; twst = TWSR & TW_STATUS_MASK;
switch (twst) { switch (twst) {
case TW_MT_DATA_NACK: case TW_MT_DATA_NACK:
@@ -471,8 +479,7 @@ static int seeprom_bytes_write_page(
* is from the last byte of the current page to the * is from the last byte of the current page to the
* first byte of the same page. * first byte of the same page.
**************************************************************************/ **************************************************************************/
int seeprom_bytes_write( int seeprom_bytes_write(uint16_t off, /* SEEPROM starting memory address */
uint16_t off, /* SEEPROM starting memory address */
uint8_t *buf, /* data to send */ uint8_t *buf, /* data to send */
int len) int len)
{ /* number of bytes of data */ { /* number of bytes of data */
@@ -501,8 +508,7 @@ int seeprom_bytes_write(
* Returns: none * Returns: none
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void seeprom_init( void seeprom_init(void)
void)
{ {
/* bit rate prescaler */ /* bit rate prescaler */
TWSR = 0; TWSR = 0;
+10 -20
View File
@@ -35,8 +35,7 @@ static uint32_t Baud_Rate = 9600;
static uint8_t Receive_Buffer_Data[128]; static uint8_t Receive_Buffer_Data[128];
static FIFO_BUFFER Receive_Buffer; static FIFO_BUFFER Receive_Buffer;
static void serial_receiver_enable( static void serial_receiver_enable(void)
void)
{ {
UCSR1B = _BV(TXEN1) | _BV(RXEN1) | _BV(RXCIE1); UCSR1B = _BV(TXEN1) | _BV(RXEN1) | _BV(RXCIE1);
} }
@@ -52,8 +51,7 @@ ISR(USART1_RX_vect)
} }
} }
bool serial_byte_get( bool serial_byte_get(uint8_t *data_register)
uint8_t * data_register)
{ {
bool data_available = false; /* return value */ bool data_available = false; /* return value */
@@ -65,8 +63,7 @@ bool serial_byte_get(
return data_available; return data_available;
} }
bool serial_byte_peek( bool serial_byte_peek(uint8_t *data_register)
uint8_t * data_register)
{ {
bool data_available = false; /* return value */ bool data_available = false; /* return value */
@@ -78,8 +75,7 @@ bool serial_byte_peek(
return data_available; return data_available;
} }
void serial_bytes_send( void serial_bytes_send(uint8_t *buffer, /* data to send */
uint8_t * buffer, /* data to send */
uint16_t nbytes) uint16_t nbytes)
{ /* number of bytes of data */ { /* number of bytes of data */
while (!BIT_CHECK(UCSR1A, UDRE1)) { while (!BIT_CHECK(UCSR1A, UDRE1)) {
@@ -105,8 +101,7 @@ void serial_bytes_send(
return; return;
} }
void serial_byte_send( void serial_byte_send(uint8_t ch)
uint8_t ch)
{ {
while (!BIT_CHECK(UCSR1A, UDRE1)) { while (!BIT_CHECK(UCSR1A, UDRE1)) {
/* do nothing - wait until Tx buffer is empty */ /* do nothing - wait until Tx buffer is empty */
@@ -117,8 +112,7 @@ void serial_byte_send(
return; return;
} }
void serial_byte_transmit_complete( void serial_byte_transmit_complete(void)
void)
{ {
/* was the frame sent? */ /* was the frame sent? */
while (!BIT_CHECK(UCSR1A, TXC1)) { while (!BIT_CHECK(UCSR1A, TXC1)) {
@@ -129,14 +123,12 @@ void serial_byte_transmit_complete(
BIT_SET(UCSR1A, TXC1); BIT_SET(UCSR1A, TXC1);
} }
uint32_t serial_baud_rate( uint32_t serial_baud_rate(void)
void)
{ {
return Baud_Rate; return Baud_Rate;
} }
bool serial_baud_rate_set( bool serial_baud_rate_set(uint32_t baud)
uint32_t baud)
{ {
bool valid = true; bool valid = true;
@@ -162,8 +154,7 @@ bool serial_baud_rate_set(
return valid; return valid;
} }
static void serial_usart_init( static void serial_usart_init(void)
void)
{ {
/* enable the internal pullup on RXD1 */ /* enable the internal pullup on RXD1 */
BIT_CLEAR(DDRD, DDD2); BIT_CLEAR(DDRD, DDD2);
@@ -181,8 +172,7 @@ static void serial_usart_init(
power_usart1_enable(); power_usart1_enable();
} }
void serial_init( void serial_init(void)
void)
{ {
FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0], FIFO_Init(&Receive_Buffer, &Receive_Buffer_Data[0],
(unsigned)sizeof(Receive_Buffer_Data)); (unsigned)sizeof(Receive_Buffer_Data));
+21 -24
View File
@@ -32,11 +32,9 @@ extern uint8_t _end;
extern uint8_t __stack; extern uint8_t __stack;
#define STACK_CANARY (0xC5) #define STACK_CANARY (0xC5)
void stack_init( void stack_init(void) __attribute__((naked)) __attribute__((section(".init1")));
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
void stack_init( void stack_init(void)
void)
{ {
#if 0 #if 0
uint8_t *p = &_end; uint8_t *p = &_end;
@@ -46,28 +44,32 @@ void stack_init(
p++; p++;
} }
#else #else
__asm volatile ( __asm volatile(" ldi r30,lo8(_end)\n"
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */ " ldi r31,hi8(_end)\n"
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n" " ldi r25,hi8(__stack)\n"
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::); " rjmp .cmp\n"
".loop:\n"
" st Z+,r24\n"
".cmp:\n"
" cpi r30,lo8(__stack)\n"
" cpc r31,r25\n"
" brlo .loop\n"
" breq .loop" ::);
#endif #endif
} }
unsigned stack_size( unsigned stack_size(void)
void)
{ {
return (&__stack) - (&_end); return (&__stack) - (&_end);
} }
uint8_t stack_byte( uint8_t stack_byte(unsigned offset)
unsigned offset)
{ {
return *(&_end + offset); return *(&_end + offset);
} }
unsigned stack_unused( unsigned stack_unused(void)
void)
{ {
uint8_t *p = &_end; uint8_t *p = &_end;
unsigned count = 0; unsigned count = 0;
@@ -82,26 +84,21 @@ unsigned stack_unused(
return count; return count;
} }
#else #else
void stack_init( void stack_init(void)
void)
{ {
} }
unsigned stack_size( unsigned stack_size(void)
void)
{ {
return 0; return 0;
} }
uint8_t stack_byte( uint8_t stack_byte(unsigned offset)
unsigned offset)
{ {
return 0; return 0;
} }
unsigned stack_unused( unsigned stack_unused(void)
void)
{ {
return 0; return 0;
} }
+14 -26
View File
@@ -42,17 +42,15 @@
#endif #endif
#define BINARY_STRING_MAX 3 #define BINARY_STRING_MAX 3
const char * const binary_string[BINARY_STRING_MAX] = { const char *const binary_string[BINARY_STRING_MAX] = { "INACTIVE", "ACTIVE",
"INACTIVE", "ACTIVE", "RELINQUISH" "RELINQUISH" };
};
/* timer for test task */ /* timer for test task */
static struct mstimer Test_Timer; static struct mstimer Test_Timer;
/* MAC Address of MS/TP */ /* MAC Address of MS/TP */
static uint8_t MSTP_MAC_Address; static uint8_t MSTP_MAC_Address;
void test_init( void test_init(void)
void)
{ {
#ifdef MSTP_MONITOR #ifdef MSTP_MONITOR
serial_baud_rate_set(115200); serial_baud_rate_set(115200);
@@ -82,14 +80,12 @@ static void test_write_string(const char * text)
} }
} }
/************************************************************************* /*************************************************************************
* Description: Turn on a pin * Description: Turn on a pin
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
static inline void test_pin_on( static inline void test_pin_on(void)
void)
{ {
#if (BDK_VERSION == 4) #if (BDK_VERSION == 4)
BIT_SET(PORTD, PD5); BIT_SET(PORTD, PD5);
@@ -103,8 +99,7 @@ static inline void test_pin_on(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
static inline void test_pin_off( static inline void test_pin_off(void)
void)
{ {
#if (BDK_VERSION == 4) #if (BDK_VERSION == 4)
BIT_CLEAR(PORTD, PD5); BIT_CLEAR(PORTD, PD5);
@@ -118,8 +113,7 @@ static inline void test_pin_off(
* Returns: true if on, false if off. * Returns: true if on, false if off.
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
static inline bool test_pin_state( static inline bool test_pin_state(void)
void)
{ {
#if (BDK_VERSION == 4) #if (BDK_VERSION == 4)
return (BIT_CHECK(PIND, PD5)); return (BIT_CHECK(PIND, PD5));
@@ -133,8 +127,7 @@ static inline bool test_pin_state(
* Returns: none * Returns: none
* Notes: none * Notes: none
*************************************************************************/ *************************************************************************/
static inline void test_pin_toggle( static inline void test_pin_toggle(void)
void)
{ {
if (test_pin_state()) { if (test_pin_state()) {
test_pin_off(); test_pin_off();
@@ -144,8 +137,7 @@ static inline void test_pin_toggle(
} }
#ifdef MSTP_MONITOR #ifdef MSTP_MONITOR
void test_task( void test_task(void)
void)
{ {
if (mstimer_expired(&Test_Timer)) { if (mstimer_expired(&Test_Timer)) {
mstimer_reset(&Test_Timer); mstimer_reset(&Test_Timer);
@@ -155,8 +147,7 @@ void test_task(
#else #else
char Send_Buffer[32]; char Send_Buffer[32];
void test_task( void test_task(void)
void)
{ {
uint8_t data_register = 0; uint8_t data_register = 0;
uint16_t id = 0; uint16_t id = 0;
@@ -208,20 +199,17 @@ void test_task(
case 'e': case 'e':
seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2); seeprom_bytes_read(NV_SEEPROM_TYPE_0, (uint8_t *)&id, 2);
sprintf(Send_Buffer, "\r\n%04X", id); sprintf(Send_Buffer, "\r\n%04X", id);
serial_bytes_send((uint8_t *) Send_Buffer, serial_bytes_send((uint8_t *)Send_Buffer, strlen(Send_Buffer));
strlen(Send_Buffer));
break; break;
case 'b': case 'b':
sprintf(Send_Buffer, "\r\n%lubps", sprintf(Send_Buffer, "\r\n%lubps",
(unsigned long)rs485_baud_rate()); (unsigned long)rs485_baud_rate());
serial_bytes_send((uint8_t *) Send_Buffer, serial_bytes_send((uint8_t *)Send_Buffer, strlen(Send_Buffer));
strlen(Send_Buffer));
break; break;
case 'm': case 'm':
sprintf(Send_Buffer, "\r\nMax:%u", sprintf(
(unsigned) dlmstp_max_master()); Send_Buffer, "\r\nMax:%u", (unsigned)dlmstp_max_master());
serial_bytes_send((uint8_t *) Send_Buffer, serial_bytes_send((uint8_t *)Send_Buffer, strlen(Send_Buffer));
strlen(Send_Buffer));
break; break;
default: default:
break; break;
+5 -10
View File
@@ -25,8 +25,7 @@
#include "watchdog.h" #include "watchdog.h"
#if !defined(__GNUC__) #if !defined(__GNUC__)
static inline void wdt_enable( static inline void wdt_enable(int value)
int value)
{ {
__disable_interrupt(); __disable_interrupt();
__watchdog_reset(); __watchdog_reset();
@@ -38,8 +37,7 @@ static inline void wdt_enable(
__enable_interrupt(); */ __enable_interrupt(); */
} }
static inline void wdt_disable( static inline void wdt_disable(void)
void)
{ {
__disable_interrupt(); __disable_interrupt();
__watchdog_reset(); __watchdog_reset();
@@ -53,8 +51,7 @@ static inline void wdt_disable(
__enable_interrupt(); __enable_interrupt();
} }
static inline void wdt_reset( static inline void wdt_reset(void)
void)
{ {
__watchdog_reset(); __watchdog_reset();
} }
@@ -65,8 +62,7 @@ static inline void wdt_reset(
* Returns: none * Returns: none
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void watchdog_reset( void watchdog_reset(void)
void)
{ {
wdt_reset(); wdt_reset();
} }
@@ -76,8 +72,7 @@ void watchdog_reset(
* Returns: none * Returns: none
* Notes: none * Notes: none
**************************************************************************/ **************************************************************************/
void watchdog_init( void watchdog_init(unsigned milliseconds)
unsigned milliseconds)
{ {
unsigned value = WDTO_15MS; unsigned value = WDTO_15MS;
if (milliseconds) { if (milliseconds) {
+22 -31
View File
@@ -68,8 +68,10 @@ static bool BIP_Debug = false;
* @param str - debug info string * @param str - debug info string
* @param addr - IPv4 address * @param addr - IPv4 address
*/ */
static void debug_print_ipv4(const char *str, const struct in_addr *addr, static void debug_print_ipv4(const char *str,
const unsigned int port, const unsigned int count) const struct in_addr *addr,
const unsigned int port,
const unsigned int count)
{ {
if (BIP_Debug) { if (BIP_Debug) {
fprintf(stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr), fprintf(stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
@@ -267,8 +269,8 @@ int bip_send_mpdu(BACNET_IP_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
memcpy(&bip_dest.sin_addr.s_addr, &dest->address[0], 4); memcpy(&bip_dest.sin_addr.s_addr, &dest->address[0], 4);
bip_dest.sin_port = htons(dest->port); bip_dest.sin_port = htons(dest->port);
/* Send the packet */ /* Send the packet */
debug_print_ipv4("Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, debug_print_ipv4(
mtu_len); "Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
return sendto(BIP_Socket, (char *)mtu, mtu_len, 0, return sendto(BIP_Socket, (char *)mtu, mtu_len, 0,
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr)); (struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
} }
@@ -341,14 +343,14 @@ uint16_t bip_receive(
*/ */
memcpy(&addr.address[0], &sin.sin_addr.s_addr, 4); memcpy(&addr.address[0], &sin.sin_addr.s_addr, 4);
addr.port = ntohs(sin.sin_port); addr.port = ntohs(sin.sin_port);
debug_print_ipv4("Received MPDU->", &sin.sin_addr, sin.sin_port, debug_print_ipv4(
received_bytes); "Received MPDU->", &sin.sin_addr, sin.sin_port, received_bytes);
/* pass the packet into the BBMD handler */ /* pass the packet into the BBMD handler */
offset = bvlc_handler(&addr, src, npdu, received_bytes); offset = bvlc_handler(&addr, src, npdu, received_bytes);
if (offset > 0) { if (offset > 0) {
npdu_len = received_bytes - offset; npdu_len = received_bytes - offset;
debug_print_ipv4("Received NPDU->", &sin.sin_addr, sin.sin_port, debug_print_ipv4(
npdu_len); "Received NPDU->", &sin.sin_addr, sin.sin_port, npdu_len);
if (npdu_len <= max_npdu) { if (npdu_len <= max_npdu) {
/* shift the buffer to return a valid NPDU */ /* shift the buffer to return a valid NPDU */
for (i = 0; i < npdu_len; i++) { for (i = 0; i < npdu_len; i++) {
@@ -414,8 +416,7 @@ bool bip_get_addr_by_name(const char *host_name, BACNET_IP_ADDRESS *addr)
return true; return true;
} }
static void *get_addr_ptr( static void *get_addr_ptr(struct sockaddr *sockaddr_ptr)
struct sockaddr *sockaddr_ptr)
{ {
void *addr_ptr; void *addr_ptr;
if (sockaddr_ptr->sa_family == AF_INET) { if (sockaddr_ptr->sa_family == AF_INET) {
@@ -434,20 +435,16 @@ static void *get_addr_ptr(
* @param addr [out] The netmask addr, broadcast addr, ip addr. * @param addr [out] The netmask addr, broadcast addr, ip addr.
* @param request [in] addr broadaddr netmask * @param request [in] addr broadaddr netmask
*/ */
static int get_local_address( static int get_local_address(char *ifname, struct in_addr *addr, char *request)
char *ifname,
struct in_addr *addr,
char *request)
{ {
char rv; /* return value */ char rv; /* return value */
struct ifaddrs *ifaddrs_ptr; struct ifaddrs *ifaddrs_ptr;
int status; int status;
status = getifaddrs(&ifaddrs_ptr); status = getifaddrs(&ifaddrs_ptr);
if (status == -1) { if (status == -1) {
fprintf(stderr, "Error in 'getifaddrs': %d (%s)\n", errno, fprintf(
strerror(errno)); stderr, "Error in 'getifaddrs': %d (%s)\n", errno, strerror(errno));
} }
while (ifaddrs_ptr) { while (ifaddrs_ptr) {
if ((ifaddrs_ptr->ifa_addr->sa_family == AF_INET) && if ((ifaddrs_ptr->ifa_addr->sa_family == AF_INET) &&
@@ -477,8 +474,7 @@ static int get_local_address(
* @param netmask [out] The netmask, in host order. * @param netmask [out] The netmask, in host order.
* @return 0 on success, else the error from the getifaddrs() call. * @return 0 on success, else the error from the getifaddrs() call.
*/ */
int bip_get_local_netmask( int bip_get_local_netmask(struct in_addr *netmask)
struct in_addr *netmask)
{ {
int rv; int rv;
char *ifname = getenv("BACNET_IFACE"); /* will probably be null */ char *ifname = getenv("BACNET_IFACE"); /* will probably be null */
@@ -497,8 +493,7 @@ int bip_get_local_netmask(
* @param ifname [in] The named interface to use for the network layer. * @param ifname [in] The named interface to use for the network layer.
* Eg, for MAC OS X, ifname is en0, en1, and others. * Eg, for MAC OS X, ifname is en0, en1, and others.
*/ */
void bip_set_interface( void bip_set_interface(char *ifname)
char *ifname)
{ {
struct in_addr local_address; struct in_addr local_address;
struct in_addr broadcast_address; struct in_addr broadcast_address;
@@ -550,8 +545,7 @@ void bip_set_interface(
* @return True if the socket is successfully opened for BACnet/IP, * @return True if the socket is successfully opened for BACnet/IP,
* else False if the socket functions fail. * else False if the socket functions fail.
*/ */
bool bip_init( bool bip_init(char *ifname)
char *ifname)
{ {
int status = 0; /* return from socket lib calls */ int status = 0; /* return from socket lib calls */
struct sockaddr_in sin; struct sockaddr_in sin;
@@ -572,18 +566,16 @@ bool bip_init(
/* Allow us to use the same socket for sending and receiving */ /* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */ /* This makes sure that the src port is correct when sending */
sockopt = 1; sockopt = 1;
status = status = setsockopt(
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sock_fd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
sizeof(sockopt));
if (status < 0) { if (status < 0) {
close(sock_fd); close(sock_fd);
BIP_Socket = -1; BIP_Socket = -1;
return status; return status;
} }
/* allow us to send a broadcast */ /* allow us to send a broadcast */
status = status = setsockopt(
setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, &sockopt, sock_fd, SOL_SOCKET, SO_BROADCAST, &sockopt, sizeof(sockopt));
sizeof(sockopt));
if (status < 0) { if (status < 0) {
close(sock_fd); close(sock_fd);
BIP_Socket = -1; BIP_Socket = -1;
@@ -617,8 +609,7 @@ bool bip_valid(void)
/** Cleanup and close out the BACnet/IP services by closing the socket. /** Cleanup and close out the BACnet/IP services by closing the socket.
* @ingroup DLBIP * @ingroup DLBIP
*/ */
void bip_cleanup( void bip_cleanup(void)
void)
{ {
int sock_fd = 0; int sock_fd = 0;
+2 -4
View File
@@ -27,8 +27,7 @@
* @param true if DST is enabled and active * @param true if DST is enabled and active
* @return true if local time was retrieved * @return true if local time was retrieved
*/ */
bool datetime_local( bool datetime_local(BACNET_DATE *bdate,
BACNET_DATE * bdate,
BACNET_TIME *btime, BACNET_TIME *btime,
int16_t *utc_offset_minutes, int16_t *utc_offset_minutes,
bool *dst_active) bool *dst_active)
@@ -54,8 +53,7 @@ bool datetime_local(
* int tm_isdst Daylight Savings flag. * int tm_isdst Daylight Savings flag.
*/ */
datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900, datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900,
(uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday);
(uint8_t)tblock->tm_mday);
datetime_set_time(btime, (uint8_t)tblock->tm_hour, datetime_set_time(btime, (uint8_t)tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
(uint8_t)(tv.tv_usec / 10000)); (uint8_t)(tv.tv_usec / 10000));
+34 -58
View File
@@ -46,7 +46,8 @@
#include "bacnet/basic/tsm/tsm.h" #include "bacnet/basic/tsm/tsm.h"
#include "bacnet/datalink/dlenv.h" #include "bacnet/datalink/dlenv.h"
/** @file bsd/main.c Example application using the BACnet Stack on BSD/MAC OS X. */ /** @file bsd/main.c Example application using the BACnet Stack on BSD/MAC OS
* X. */
bool Who_Is_Request = true; bool Who_Is_Request = true;
@@ -54,9 +55,7 @@ bool Who_Is_Request = true;
static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static void LocalIAmHandler( static void LocalIAmHandler(
uint8_t * service_request, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
uint16_t service_len,
BACNET_ADDRESS * src)
{ {
int len = 0; int len = 0;
uint32_t device_id = 0; uint32_t device_id = 0;
@@ -66,9 +65,8 @@ static void LocalIAmHandler(
(void)src; (void)src;
(void)service_len; (void)service_len;
len = len = iam_decode_service_request(
iam_decode_service_request(service_request, &device_id, &max_apdu, service_request, &device_id, &max_apdu, &segmentation, &vendor_id);
&segmentation, &vendor_id);
fprintf(stderr, "Received I-Am Request"); fprintf(stderr, "Received I-Am Request");
if (len != -1) { if (len != -1) {
fprintf(stderr, " from %u!\n", device_id); fprintf(stderr, " from %u!\n", device_id);
@@ -79,8 +77,7 @@ static void LocalIAmHandler(
return; return;
} }
static void Read_Properties( static void Read_Properties(void)
void)
{ {
uint32_t device_id = 0; uint32_t device_id = 0;
bool status = false; bool status = false;
@@ -93,32 +90,17 @@ static void Read_Properties(
properties in the Device Object. Note that this demo properties in the Device Object. Note that this demo
tests for error messages so that the device doesn't have tests for error messages so that the device doesn't have
to have all the properties listed here. */ to have all the properties listed here. */
const int object_props[] = { const int object_props[] = { PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
PROP_OBJECT_NAME, PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
PROP_OBJECT_TYPE, PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
PROP_SYSTEM_STATUS, PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_VENDOR_NAME, PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
PROP_VENDOR_IDENTIFIER, PROP_LOCAL_TIME, PROP_LOCAL_DATE, PROP_UTC_OFFSET,
PROP_MODEL_NAME, PROP_DAYLIGHT_SAVINGS_STATUS, PROP_APDU_SEGMENT_TIMEOUT,
PROP_FIRMWARE_REVISION, PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES,
PROP_APPLICATION_SOFTWARE_VERSION, PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_MAX_MASTER,
PROP_PROTOCOL_VERSION, PROP_MAX_INFO_FRAMES, PROP_DEVICE_ADDRESS_BINDING,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_LOCAL_TIME,
PROP_LOCAL_DATE,
PROP_UTC_OFFSET,
PROP_DAYLIGHT_SAVINGS_STATUS,
PROP_APDU_SEGMENT_TIMEOUT,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
PROP_DEVICE_ADDRESS_BINDING,
/* note: PROP_OBJECT_LIST is missing because /* note: PROP_OBJECT_LIST is missing because
the result can be very large. Read index 0 the result can be very large. Read index 0
which gives us the number of objects in the list, which gives us the number of objects in the list,
@@ -128,8 +110,7 @@ static void Read_Properties(
/* some proprietary properties */ /* some proprietary properties */
514, 515, 514, 515,
/* end of list */ /* end of list */
-1 -1 };
};
if (address_count()) { if (address_count()) {
if (address_get_by_index(index, &device_id, &max_apdu, &src)) { if (address_get_by_index(index, &device_id, &max_apdu, &src)) {
@@ -139,8 +120,10 @@ static void Read_Properties(
/* note: if we wanted to do this synchronously, we would get the /* note: if we wanted to do this synchronously, we would get the
invoke ID from the sending of the request, and wait until we invoke ID from the sending of the request, and wait until we
got the reply with matching invoke ID or the TSM of the got the reply with matching invoke ID or the TSM of the
invoke ID expired. This demo is doing things asynchronously. */ invoke ID expired. This demo is doing things asynchronously.
status = Send_Read_Property_Request(device_id, /* destination device */ */
status = Send_Read_Property_Request(
device_id, /* destination device */
OBJECT_DEVICE, device_id, object_props[property], OBJECT_DEVICE, device_id, object_props[property],
BACNET_ARRAY_ALL); BACNET_ARRAY_ALL);
if (status) if (status)
@@ -160,31 +143,28 @@ static void Read_Properties(
return; return;
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
handler_read_property_object_set(OBJECT_DEVICE, handler_read_property_object_set(OBJECT_DEVICE, Device_Encode_Property_APDU,
Device_Encode_Property_APDU, Device_Valid_Object_Instance_Number); Device_Valid_Object_Instance_Number);
/* we need to handle who-is to support dynamic device binding */ /* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
/* set the handler for all the services we don't implement */ /* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */ /* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(
handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
/* handle the data coming back from confirmed requests */ /* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_ack_handler(
handler_read_property_ack); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property_ack);
} }
static void print_address_cache( static void print_address_cache(void)
void)
{ {
unsigned i, j; unsigned i, j;
BACNET_ADDRESS address; BACNET_ADDRESS address;
@@ -205,8 +185,7 @@ static void print_address_cache(
} }
} }
static void print_tsm_stats( static void print_tsm_stats(void)
void)
{ {
int idle = 0; int idle = 0;
int total = 0; int total = 0;
@@ -216,8 +195,7 @@ static void print_tsm_stats(
fprintf(stderr, "TSM: %d idle of %d transactions\n", idle, total); fprintf(stderr, "TSM: %d idle of %d transactions\n", idle, total);
} }
static void sig_handler( static void sig_handler(int signo)
int signo)
{ {
datalink_cleanup(); datalink_cleanup();
print_address_cache(); print_address_cache();
@@ -226,9 +204,7 @@ static void sig_handler(
exit(0); exit(0);
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
BACNET_ADDRESS src = { 0 }; /* address where message came from */ BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
+4 -7
View File
@@ -40,8 +40,7 @@ static volatile unsigned long Millisecond_Counter;
static struct timespec start; static struct timespec start;
/* The timeGetTime function retrieves the system time, in milliseconds. /* The timeGetTime function retrieves the system time, in milliseconds.
The system time is the time elapsed since the OS was started. */ The system time is the time elapsed since the OS was started. */
unsigned long timeGetTime( unsigned long timeGetTime(void)
void)
{ {
struct timespec now; struct timespec now;
unsigned long ticks; unsigned long ticks;
@@ -54,9 +53,8 @@ unsigned long timeGetTime(
now.tv_sec = mts.tv_sec; now.tv_sec = mts.tv_sec;
now.tv_nsec = mts.tv_nsec; now.tv_nsec = mts.tv_nsec;
ticks = ticks = (now.tv_sec - start.tv_sec) * 1000 +
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec - (now.tv_nsec - start.tv_nsec) / 1000000;
start.tv_nsec) / 1000000;
return ticks; return ticks;
} }
@@ -82,8 +80,7 @@ unsigned long mstimer_now(void)
/** /**
* @brief Initialization for timer * @brief Initialization for timer
*/ */
void timer_init( void timer_init(void)
void)
{ {
clock_serv_t cclock; clock_serv_t cclock;
mach_timespec_t mts; mach_timespec_t mts;
+210 -281
View File
@@ -41,57 +41,30 @@
#include "bacnet/timestamp.h" #include "bacnet/timestamp.h"
#include "bacnet/basic/object/ai.h" #include "bacnet/basic/object/ai.h"
#ifndef MAX_ANALOG_INPUTS #ifndef MAX_ANALOG_INPUTS
#define MAX_ANALOG_INPUTS 2 #define MAX_ANALOG_INPUTS 2
#endif #endif
ANALOG_INPUT_DESCR AI_Descr[MAX_ANALOG_INPUTS]; ANALOG_INPUT_DESCR AI_Descr[MAX_ANALOG_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1 };
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = { PROP_DESCRIPTION, PROP_RELIABILITY,
PROP_DESCRIPTION,
PROP_RELIABILITY,
PROP_COV_INCREMENT, PROP_COV_INCREMENT,
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
PROP_TIME_DELAY, PROP_TIME_DELAY, PROP_NOTIFICATION_CLASS, PROP_HIGH_LIMIT, PROP_LOW_LIMIT,
PROP_NOTIFICATION_CLASS, PROP_DEADBAND, PROP_LIMIT_ENABLE, PROP_EVENT_ENABLE, PROP_ACKED_TRANSITIONS,
PROP_HIGH_LIMIT, PROP_NOTIFY_TYPE, PROP_EVENT_TIME_STAMPS,
PROP_LOW_LIMIT,
PROP_DEADBAND,
PROP_LIMIT_ENABLE,
PROP_EVENT_ENABLE,
PROP_ACKED_TRANSITIONS,
PROP_NOTIFY_TYPE,
PROP_EVENT_TIME_STAMPS,
#endif #endif
-1 -1 };
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = { 9997, 9998, 9999, -1 };
9997,
9998,
9999,
-1
};
void Analog_Input_Property_Lists( void Analog_Input_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Properties_Required; *pRequired = Properties_Required;
@@ -103,9 +76,7 @@ void Analog_Input_Property_Lists(
return; return;
} }
void Analog_Input_Init(void)
void Analog_Input_Init(
void)
{ {
unsigned i; unsigned i;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -132,13 +103,13 @@ void Analog_Input_Init(
} }
/* Set handler for GetEventInformation function */ /* Set handler for GetEventInformation function */
handler_get_event_information_set(OBJECT_ANALOG_INPUT, handler_get_event_information_set(
Analog_Input_Event_Information); OBJECT_ANALOG_INPUT, Analog_Input_Event_Information);
/* Set handler for AcknowledgeAlarm function */ /* Set handler for AcknowledgeAlarm function */
handler_alarm_ack_set(OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Ack); handler_alarm_ack_set(OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Ack);
/* Set handler for GetAlarmSummary Service */ /* Set handler for GetAlarmSummary Service */
handler_get_alarm_summary_set(OBJECT_ANALOG_INPUT, handler_get_alarm_summary_set(
Analog_Input_Alarm_Summary); OBJECT_ANALOG_INPUT, Analog_Input_Alarm_Summary);
#endif #endif
} }
} }
@@ -146,8 +117,7 @@ void Analog_Input_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned int index; unsigned int index;
@@ -160,8 +130,7 @@ bool Analog_Input_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
@@ -169,8 +138,7 @@ unsigned Analog_Input_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -178,8 +146,7 @@ uint32_t Analog_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Input_Instance_To_Index( unsigned Analog_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_INPUTS; unsigned index = MAX_ANALOG_INPUTS;
@@ -189,8 +156,7 @@ unsigned Analog_Input_Instance_To_Index(
return index; return index;
} }
float Analog_Input_Present_Value( float Analog_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
unsigned int index; unsigned int index;
@@ -203,8 +169,7 @@ float Analog_Input_Present_Value(
return value; return value;
} }
static void Analog_Input_COV_Detect(unsigned int index, static void Analog_Input_COV_Detect(unsigned int index, float value)
float value)
{ {
float prior_value = 0.0; float prior_value = 0.0;
float cov_increment = 0.0; float cov_increment = 0.0;
@@ -225,9 +190,7 @@ static void Analog_Input_COV_Detect(unsigned int index,
} }
} }
void Analog_Input_Present_Value_Set( void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
unsigned int index = 0; unsigned int index = 0;
@@ -239,8 +202,7 @@ void Analog_Input_Present_Value_Set(
} }
bool Analog_Input_Object_Name( bool Analog_Input_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[32] = ""; static char text_string[32] = "";
unsigned int index; unsigned int index;
@@ -250,8 +212,7 @@ bool Analog_Input_Object_Name(
status = characterstring_init_ansi(object_name, "Internal Temperature"); status = characterstring_init_ansi(object_name, "Internal Temperature");
else if (object_instance == 1) else if (object_instance == 1)
status = characterstring_init_ansi(object_name, "Magnetic field"); status = characterstring_init_ansi(object_name, "Magnetic field");
else else {
{
index = Analog_Input_Instance_To_Index(object_instance); index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
sprintf(text_string, "ANALOG INPUT %lu", (unsigned long)index); sprintf(text_string, "ANALOG INPUT %lu", (unsigned long)index);
@@ -261,8 +222,7 @@ bool Analog_Input_Object_Name(
return status; return status;
} }
bool Analog_Input_Change_Of_Value( bool Analog_Input_Change_Of_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
bool changed = false; bool changed = false;
@@ -275,8 +235,7 @@ bool Analog_Input_Change_Of_Value(
return changed; return changed;
} }
void Analog_Input_Change_Of_Value_Clear( void Analog_Input_Change_Of_Value_Clear(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
@@ -295,8 +254,7 @@ void Analog_Input_Change_Of_Value_Clear(
* @return true if the value list is encoded * @return true if the value list is encoded
*/ */
bool Analog_Input_Encode_Value_List( bool Analog_Input_Encode_Value_List(
uint32_t object_instance, uint32_t object_instance, BACNET_PROPERTY_VALUE *value_list)
BACNET_PROPERTY_VALUE * value_list)
{ {
bool status = false; bool status = false;
@@ -317,12 +275,12 @@ bool Analog_Input_Encode_Value_List(
value_list->value.context_specific = false; value_list->value.context_specific = false;
value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING; value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING;
bitstring_init(&value_list->value.type.Bit_String); bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(
STATUS_FLAG_IN_ALARM, false); &value_list->value.type.Bit_String, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(
STATUS_FLAG_FAULT, false); &value_list->value.type.Bit_String, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(
STATUS_FLAG_OVERRIDDEN, false); &value_list->value.type.Bit_String, STATUS_FLAG_OVERRIDDEN, false);
if (Analog_Input_Out_Of_Service(object_instance)) { if (Analog_Input_Out_Of_Service(object_instance)) {
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OUT_OF_SERVICE, true); STATUS_FLAG_OUT_OF_SERVICE, true);
@@ -339,8 +297,7 @@ bool Analog_Input_Encode_Value_List(
return status; return status;
} }
float Analog_Input_COV_Increment( float Analog_Input_COV_Increment(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
float value = 0; float value = 0;
@@ -353,9 +310,7 @@ float Analog_Input_COV_Increment(
return value; return value;
} }
void Analog_Input_COV_Increment_Set( void Analog_Input_COV_Increment_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -366,8 +321,7 @@ void Analog_Input_COV_Increment_Set(
} }
} }
bool Analog_Input_Out_Of_Service( bool Analog_Input_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
bool value = false; bool value = false;
@@ -380,22 +334,20 @@ bool Analog_Input_Out_Of_Service(
return value; return value;
} }
void Analog_Input_Out_Of_Service_Set( void Analog_Input_Out_Of_Service_Set(uint32_t object_instance, bool value)
uint32_t object_instance,
bool value)
{ {
unsigned index = 0; unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance); index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
/* BACnet Testing Observed Incident oi00104 /* BACnet Testing Observed Incident oi00104
The Changed flag was not being set when a client wrote to the Out-of-Service bit. The Changed flag was not being set when a client wrote to the
Revealed by BACnet Test Client v1.8.16 ( www.bac-test.com/bacnet-test-client-download ) Out-of-Service bit. Revealed by BACnet Test Client v1.8.16 (
BC 135.1: 8.2.1-A www.bac-test.com/bacnet-test-client-download ) BC 135.1: 8.2.1-A BC
BC 135.1: 8.2.2-A 135.1: 8.2.2-A Any discussions can be directed to edward@bac-test.com
Any discussions can be directed to edward@bac-test.com Please feel free to remove this comment when my changes accepted after
Please feel free to remove this comment when my changes accepted after suitable time for suitable time for review by all interested parties. Say 6 months ->
review by all interested parties. Say 6 months -> September 2016 */ September 2016 */
if (AI_Descr[index].Out_Of_Service != value) { if (AI_Descr[index].Out_Of_Service != value) {
AI_Descr[index].Changed = true; AI_Descr[index].Changed = true;
} }
@@ -405,8 +357,7 @@ void Analog_Input_Out_Of_Service_Set(
/* return apdu length, or BACNET_STATUS_ERROR on error */ /* return apdu length, or BACNET_STATUS_ERROR on error */
/* assumption - object already exists */ /* assumption - object already exists */
int Analog_Input_Read_Property( int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -433,9 +384,8 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch ((int)rpdata->object_property) { switch ((int)rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, &apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -451,9 +401,8 @@ int Analog_Input_Read_Property(
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -475,8 +424,7 @@ int Analog_Input_Read_Property(
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], CurrentAI->Event_State);
CurrentAI->Event_State);
#else #else
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
@@ -485,14 +433,12 @@ int Analog_Input_Read_Property(
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], CurrentAI->Reliability);
CurrentAI->Reliability);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
apdu_len = apdu_len =
encode_application_boolean(&apdu[0], encode_application_boolean(&apdu[0], CurrentAI->Out_Of_Service);
CurrentAI->Out_Of_Service);
break; break;
case PROP_UNITS: case PROP_UNITS:
@@ -501,8 +447,8 @@ int Analog_Input_Read_Property(
break; break;
case PROP_COV_INCREMENT: case PROP_COV_INCREMENT:
apdu_len = encode_application_real(&apdu[0], apdu_len =
CurrentAI->COV_Increment); encode_application_real(&apdu[0], CurrentAI->COV_Increment);
break; break;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -512,14 +458,12 @@ int Analog_Input_Read_Property(
break; break;
case PROP_NOTIFICATION_CLASS: case PROP_NOTIFICATION_CLASS:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], CurrentAI->Notification_Class);
CurrentAI->Notification_Class);
break; break;
case PROP_HIGH_LIMIT: case PROP_HIGH_LIMIT:
apdu_len = apdu_len = encode_application_real(&apdu[0], CurrentAI->High_Limit);
encode_application_real(&apdu[0], CurrentAI->High_Limit);
break; break;
case PROP_LOW_LIMIT: case PROP_LOW_LIMIT:
@@ -533,11 +477,11 @@ int Analog_Input_Read_Property(
case PROP_LIMIT_ENABLE: case PROP_LIMIT_ENABLE:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, 0, bitstring_set_bit(&bit_string, 0,
(CurrentAI-> (CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true
Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true : false); : false);
bitstring_set_bit(&bit_string, 1, bitstring_set_bit(&bit_string, 1,
(CurrentAI-> (CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true
Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false); : false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
@@ -545,14 +489,14 @@ int Analog_Input_Read_Property(
case PROP_EVENT_ENABLE: case PROP_EVENT_ENABLE:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
(CurrentAI-> (CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); : false);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
(CurrentAI-> (CurrentAI->Event_Enable & EVENT_ENABLE_TO_FAULT) ? true
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false); : false);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
(CurrentAI-> (CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); : false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
@@ -560,8 +504,7 @@ int Analog_Input_Read_Property(
case PROP_ACKED_TRANSITIONS: case PROP_ACKED_TRANSITIONS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL,
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
@@ -571,33 +514,27 @@ int Analog_Input_Read_Property(
break; break;
case PROP_NOTIFY_TYPE: case PROP_NOTIFY_TYPE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], CurrentAI->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
CurrentAI->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
break; break;
case PROP_EVENT_TIME_STAMPS: case PROP_EVENT_TIME_STAMPS:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
if (rpdata->array_index == 0) if (rpdata->array_index == 0)
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], MAX_BACNET_EVENT_TRANSITION);
MAX_BACNET_EVENT_TRANSITION);
/* 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 (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) { for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) {
len = len = encode_opening_tag(
encode_opening_tag(&apdu[apdu_len], &apdu[apdu_len], TIME_STAMP_DATETIME);
TIME_STAMP_DATETIME); len += encode_application_date(&apdu[apdu_len + len],
len +=
encode_application_date(&apdu[apdu_len + len],
&CurrentAI->Event_Time_Stamps[i].date); &CurrentAI->Event_Time_Stamps[i].date);
len += len += encode_application_time(&apdu[apdu_len + len],
encode_application_time(&apdu[apdu_len + len],
&CurrentAI->Event_Time_Stamps[i].time); &CurrentAI->Event_Time_Stamps[i].time);
len += len += encode_closing_tag(
encode_closing_tag(&apdu[apdu_len + len], &apdu[apdu_len + len], TIME_STAMP_DATETIME);
TIME_STAMP_DATETIME);
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
@@ -612,11 +549,9 @@ int Analog_Input_Read_Property(
} else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) {
apdu_len = apdu_len =
encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
apdu_len += apdu_len += encode_application_date(&apdu[apdu_len],
encode_application_date(&apdu[apdu_len],
&CurrentAI->Event_Time_Stamps[rpdata->array_index].date); &CurrentAI->Event_Time_Stamps[rpdata->array_index].date);
apdu_len += apdu_len += encode_application_time(&apdu[apdu_len],
encode_application_time(&apdu[apdu_len],
&CurrentAI->Event_Time_Stamps[rpdata->array_index].time); &CurrentAI->Event_Time_Stamps[rpdata->array_index].time);
apdu_len += apdu_len +=
encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
@@ -632,11 +567,13 @@ int Analog_Input_Read_Property(
apdu_len = encode_application_real(&apdu[0], 90.510F); apdu_len = encode_application_real(&apdu[0], 90.510F);
break; break;
case 9998: case 9998:
/* test case for unsigned encoding-decoding unsigned value correctly */ /* test case for unsigned encoding-decoding unsigned value correctly
*/
apdu_len = encode_application_unsigned(&apdu[0], 90); apdu_len = encode_application_unsigned(&apdu[0], 90);
break; break;
case 9999: case 9999:
/* test case for signed encoding-decoding negative value correctly */ /* test case for signed encoding-decoding negative value correctly
*/
apdu_len = encode_application_signed(&apdu[0], -200); apdu_len = encode_application_signed(&apdu[0], -200);
break; break;
default: default:
@@ -646,8 +583,9 @@ int Analog_Input_Read_Property(
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->object_property != PROP_EVENT_TIME_STAMPS) if ((apdu_len >= 0) &&
&& (rpdata->array_index != BACNET_ARRAY_ALL)) { (rpdata->object_property != PROP_EVENT_TIME_STAMPS) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -657,8 +595,7 @@ int Analog_Input_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Input_Write_Property( bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -667,9 +604,8 @@ bool Analog_Input_Write_Property(
ANALOG_INPUT_DESCR *CurrentAI; ANALOG_INPUT_DESCR *CurrentAI;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -693,14 +629,13 @@ bool Analog_Input_Write_Property(
switch ((int)wp_data->object_property) { switch ((int)wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if (CurrentAI->Out_Of_Service == true) { if (CurrentAI->Out_Of_Service == true) {
Analog_Input_Present_Value_Set(wp_data->object_instance, Analog_Input_Present_Value_Set(
value.type.Real); wp_data->object_instance, value.type.Real);
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
@@ -710,13 +645,11 @@ bool Analog_Input_Write_Property(
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
Analog_Input_Out_Of_Service_Set( Analog_Input_Out_Of_Service_Set(
wp_data->object_instance, wp_data->object_instance, value.type.Boolean);
value.type.Boolean);
} }
break; break;
@@ -730,14 +663,12 @@ bool Analog_Input_Write_Property(
break; break;
case PROP_COV_INCREMENT: case PROP_COV_INCREMENT:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if (value.type.Real >= 0.0) { if (value.type.Real >= 0.0) {
Analog_Input_COV_Increment_Set( Analog_Input_COV_Increment_Set(
wp_data->object_instance, wp_data->object_instance, value.type.Real);
value.type.Real);
} else { } else {
status = false; status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -769,8 +700,7 @@ bool Analog_Input_Write_Property(
break; break;
case PROP_HIGH_LIMIT: case PROP_HIGH_LIMIT:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
@@ -779,8 +709,7 @@ bool Analog_Input_Write_Property(
break; break;
case PROP_LOW_LIMIT: case PROP_LOW_LIMIT:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
@@ -789,8 +718,7 @@ bool Analog_Input_Write_Property(
break; break;
case PROP_DEADBAND: case PROP_DEADBAND:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
@@ -878,9 +806,7 @@ bool Analog_Input_Write_Property(
return status; return status;
} }
void Analog_Input_Intrinsic_Reporting(uint32_t object_instance)
void Analog_Input_Intrinsic_Reporting(
uint32_t object_instance)
{ {
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
BACNET_EVENT_NOTIFICATION_DATA event_data; BACNET_EVENT_NOTIFICATION_DATA event_data;
@@ -893,7 +819,6 @@ void Analog_Input_Intrinsic_Reporting(
float PresentVal = 0.0f; float PresentVal = 0.0f;
bool SendNotify = false; bool SendNotify = false;
object_index = Analog_Input_Instance_To_Index(object_instance); object_index = Analog_Input_Instance_To_Index(object_instance);
if (object_index < MAX_ANALOG_INPUTS) if (object_index < MAX_ANALOG_INPUTS)
CurrentAI = &AI_Descr[object_index]; CurrentAI = &AI_Descr[object_index];
@@ -904,7 +829,6 @@ void Analog_Input_Intrinsic_Reporting(
if (!CurrentAI->Limit_Enable) if (!CurrentAI->Limit_Enable)
return; /* limits are not configured */ return; /* limits are not configured */
if (CurrentAI->Ack_notify_data.bSendAckNotify) { if (CurrentAI->Ack_notify_data.bSendAckNotify) {
/* clean bSendAckNotify flag */ /* clean bSendAckNotify flag */
CurrentAI->Ack_notify_data.bSendAckNotify = false; CurrentAI->Ack_notify_data.bSendAckNotify = false;
@@ -930,10 +854,12 @@ void Analog_Input_Intrinsic_Reporting(
switch (CurrentAI->Event_State) { switch (CurrentAI->Event_State) {
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
/* A TO-OFFNORMAL event is generated under these conditions: /* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the High_Limit for a minimum (a) the Present_Value must exceed the High_Limit for a
period of time, specified in the Time_Delay property, and minimum period of time, specified in the Time_Delay property,
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and and (b) the HighLimitEnable flag must be set in the
(c) the TO-OFFNORMAL flag must be set in the Event_Enable property. */ Limit_Enable property, and
(c) the TO-OFFNORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal > CurrentAI->High_Limit) && if ((PresentVal > CurrentAI->High_Limit) &&
((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) && EVENT_HIGH_LIMIT_ENABLE) &&
@@ -947,10 +873,12 @@ void Analog_Input_Intrinsic_Reporting(
} }
/* A TO-OFFNORMAL event is generated under these conditions: /* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband (a) the Present_Value must exceed the Low_Limit plus the
for a minimum period of time, specified in the Time_Delay property, and Deadband for a minimum period of time, specified in the
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and Time_Delay property, and (b) the LowLimitEnable flag must be
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ set in the Limit_Enable property, and
(c) the TO-NORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal < CurrentAI->Low_Limit) && if ((PresentVal < CurrentAI->Low_Limit) &&
((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) && EVENT_LOW_LIMIT_ENABLE) &&
@@ -967,14 +895,17 @@ void Analog_Input_Intrinsic_Reporting(
break; break;
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
/* Once exceeded, the Present_Value must fall below the High_Limit minus /* Once exceeded, the Present_Value must fall below the
the Deadband before a TO-NORMAL event is generated under these conditions: High_Limit minus the Deadband before a TO-NORMAL event is
(a) the Present_Value must fall below the High_Limit minus the Deadband generated under these conditions: (a) the Present_Value must
for a minimum period of time, specified in the Time_Delay property, and fall below the High_Limit minus the Deadband for a minimum
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and period of time, specified in the Time_Delay property, and (b)
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ the HighLimitEnable flag must be set in the Limit_Enable
if ((PresentVal < CurrentAI->High_Limit - CurrentAI->Deadband) property, and (c) the TO-NORMAL flag must be set in the
&& ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == Event_Enable property. */
if ((PresentVal <
CurrentAI->High_Limit - CurrentAI->Deadband) &&
((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) && EVENT_HIGH_LIMIT_ENABLE) &&
((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) { EVENT_ENABLE_TO_NORMAL)) {
@@ -992,12 +923,14 @@ void Analog_Input_Intrinsic_Reporting(
/* Once the Present_Value has fallen below the Low_Limit, /* Once the Present_Value has fallen below the Low_Limit,
the Present_Value must exceed the Low_Limit plus the Deadband the Present_Value must exceed the Low_Limit plus the Deadband
before a TO-NORMAL event is generated under these conditions: before a TO-NORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband (a) the Present_Value must exceed the Low_Limit plus the
for a minimum period of time, specified in the Time_Delay property, and Deadband for a minimum period of time, specified in the
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and Time_Delay property, and (b) the LowLimitEnable flag must be
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ set in the Limit_Enable property, and
if ((PresentVal > CurrentAI->Low_Limit + CurrentAI->Deadband) (c) the TO-NORMAL flag must be set in the Event_Enable
&& ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == property. */
if ((PresentVal > CurrentAI->Low_Limit + CurrentAI->Deadband) &&
((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) && EVENT_LOW_LIMIT_ENABLE) &&
((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) { EVENT_ENABLE_TO_NORMAL)) {
@@ -1036,12 +969,12 @@ void Analog_Input_Intrinsic_Reporting(
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
if (FromState == EVENT_STATE_HIGH_LIMIT) { if (FromState == EVENT_STATE_HIGH_LIMIT) {
ExceededLimit = CurrentAI->High_Limit; ExceededLimit = CurrentAI->High_Limit;
characterstring_init_ansi(&msgText, characterstring_init_ansi(
"Back to normal state from high limit"); &msgText, "Back to normal state from high limit");
} else { } else {
ExceededLimit = CurrentAI->Low_Limit; ExceededLimit = CurrentAI->Low_Limit;
characterstring_init_ansi(&msgText, characterstring_init_ansi(
"Back to normal state from low limit"); &msgText, "Back to normal state from low limit");
} }
break; break;
@@ -1065,7 +998,6 @@ void Analog_Input_Intrinsic_Reporting(
} }
} }
if (SendNotify) { if (SendNotify) {
/* Event Object Identifier */ /* Event Object Identifier */
event_data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT; event_data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT;
@@ -1121,18 +1053,20 @@ void Analog_Input_Intrinsic_Reporting(
event_data.notificationParams.outOfRange.exceedingValue = event_data.notificationParams.outOfRange.exceedingValue =
PresentVal; PresentVal;
/* Status_Flags of the referenced object. */ /* Status_Flags of the referenced object. */
bitstring_init(&event_data.notificationParams.outOfRange. bitstring_init(
statusFlags); &event_data.notificationParams.outOfRange.statusFlags);
bitstring_set_bit(&event_data.notificationParams.outOfRange. bitstring_set_bit(
statusFlags, STATUS_FLAG_IN_ALARM, &event_data.notificationParams.outOfRange.statusFlags,
CurrentAI->Event_State ? true : false); STATUS_FLAG_IN_ALARM, CurrentAI->Event_State ? true : false);
bitstring_set_bit(&event_data.notificationParams.outOfRange. bitstring_set_bit(
statusFlags, STATUS_FLAG_FAULT, false); &event_data.notificationParams.outOfRange.statusFlags,
bitstring_set_bit(&event_data.notificationParams.outOfRange. STATUS_FLAG_FAULT, false);
statusFlags, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(
bitstring_set_bit(&event_data.notificationParams.outOfRange. &event_data.notificationParams.outOfRange.statusFlags,
statusFlags, STATUS_FLAG_OUT_OF_SERVICE, STATUS_FLAG_OVERRIDDEN, false);
CurrentAI->Out_Of_Service); bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_OUT_OF_SERVICE, CurrentAI->Out_Of_Service);
/* Deadband used for limit checking. */ /* Deadband used for limit checking. */
event_data.notificationParams.outOfRange.deadband = event_data.notificationParams.outOfRange.deadband =
CurrentAI->Deadband; CurrentAI->Deadband;
@@ -1151,24 +1085,24 @@ void Analog_Input_Intrinsic_Reporting(
case EVENT_STATE_OFFNORMAL: case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT: case EVENT_STATE_LOW_LIMIT:
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bIsAcked = false; .bIsAcked = false;
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
case EVENT_STATE_FAULT: case EVENT_STATE_FAULT:
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]. CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked =
bIsAcked = false; false;
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]. CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]
bIsAcked = false; .bIsAcked = false;
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
} }
} }
@@ -1176,17 +1110,14 @@ void Analog_Input_Intrinsic_Reporting(
#endif /* defined(INTRINSIC_REPORTING) */ #endif /* defined(INTRINSIC_REPORTING) */
} }
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
int Analog_Input_Event_Information( int Analog_Input_Event_Information(
unsigned index, unsigned index, BACNET_GET_EVENT_INFORMATION_DATA *getevent_data)
BACNET_GET_EVENT_INFORMATION_DATA * getevent_data)
{ {
bool IsNotAckedTransitions; bool IsNotAckedTransitions;
bool IsActiveEvent; bool IsActiveEvent;
int i; int i;
/* check index */ /* check index */
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
/* Event_State not equal to NORMAL */ /* Event_State not equal to NORMAL */
@@ -1195,12 +1126,13 @@ int Analog_Input_Event_Information(
/* Acked_Transitions property, which has at least one of the bits /* Acked_Transitions property, which has at least one of the bits
(TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */
IsNotAckedTransitions = IsNotAckedTransitions =
(AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. (AI_Descr[index]
bIsAcked == .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT]. .bIsAcked == false) |
bIsAcked == (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked ==
false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL]. false) |
bIsAcked == false); (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked ==
false);
} else } else
return -1; /* end of list */ return -1; /* end of list */
@@ -1215,8 +1147,9 @@ int Analog_Input_Event_Information(
bitstring_init(&getevent_data->acknowledgedTransitions); bitstring_init(&getevent_data->acknowledgedTransitions);
bitstring_set_bit(&getevent_data->acknowledgedTransitions, bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL, TRANSITION_TO_OFFNORMAL,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. AI_Descr[index]
bIsAcked); .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked);
bitstring_set_bit(&getevent_data->acknowledgedTransitions, bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_FAULT, TRANSITION_TO_FAULT,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
@@ -1234,35 +1167,31 @@ int Analog_Input_Event_Information(
/* Event Enable */ /* Event Enable */
bitstring_init(&getevent_data->eventEnable); bitstring_init(&getevent_data->eventEnable);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
(AI_Descr[index]. (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); : false);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT, bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT,
(AI_Descr[index]. (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT) ? true
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false); : false);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL, bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL,
(AI_Descr[index]. (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); : false);
/* Event Priorities */ /* Event Priorities */
Notification_Class_Get_Priorities(AI_Descr[index].Notification_Class, Notification_Class_Get_Priorities(
getevent_data->eventPriorities); AI_Descr[index].Notification_Class, getevent_data->eventPriorities);
return 1; /* active event */ return 1; /* active event */
} else } else
return 0; /* no active event at this index */ return 0; /* no active event at this index */
} }
int Analog_Input_Alarm_Ack( int Analog_Input_Alarm_Ack(
BACNET_ALARM_ACK_DATA * alarmack_data, BACNET_ALARM_ACK_DATA *alarmack_data, BACNET_ERROR_CODE *error_code)
BACNET_ERROR_CODE * error_code)
{ {
ANALOG_INPUT_DESCR *CurrentAI; ANALOG_INPUT_DESCR *CurrentAI;
unsigned int object_index; unsigned int object_index;
object_index = Analog_Input_Instance_To_Index(
object_index = alarmack_data->eventObjectIdentifier.instance);
Analog_Input_Instance_To_Index(alarmack_data->eventObjectIdentifier.
instance);
if (object_index < MAX_ANALOG_INPUTS) if (object_index < MAX_ANALOG_INPUTS)
CurrentAI = &AI_Descr[object_index]; CurrentAI = &AI_Descr[object_index];
@@ -1275,22 +1204,23 @@ int Analog_Input_Alarm_Ack(
case EVENT_STATE_OFFNORMAL: case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT: case EVENT_STATE_LOW_LIMIT:
if (CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. if (CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bIsAcked == false) { .bIsAcked == false) {
if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) { if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAI-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp, &CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
/* FIXME: Send ack notification */ /* FIXME: Send ack notification */
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked =
bIsAcked = true; true;
} else { } else {
*error_code = ERROR_CODE_INVALID_EVENT_STATE; *error_code = ERROR_CODE_INVALID_EVENT_STATE;
return -1; return -1;
@@ -1304,8 +1234,9 @@ int Analog_Input_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAI-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp, &CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
@@ -1327,8 +1258,9 @@ int Analog_Input_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAI-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp, &CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
@@ -1353,10 +1285,8 @@ int Analog_Input_Alarm_Ack(
} }
int Analog_Input_Alarm_Summary( int Analog_Input_Alarm_Summary(
unsigned index, unsigned index, BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data)
BACNET_GET_ALARM_SUMMARY_DATA * getalarm_data)
{ {
/* check index */ /* check index */
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
/* Event_State is not equal to NORMAL and /* Event_State is not equal to NORMAL and
@@ -1373,16 +1303,19 @@ int Analog_Input_Alarm_Summary(
bitstring_init(&getalarm_data->acknowledgedTransitions); bitstring_init(&getalarm_data->acknowledgedTransitions);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL, TRANSITION_TO_OFFNORMAL,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. AI_Descr[index]
bIsAcked); .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_FAULT, TRANSITION_TO_FAULT,
AI_Descr[index]. AI_Descr[index]
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); .Acked_Transitions[TRANSITION_TO_FAULT]
.bIsAcked);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_NORMAL, TRANSITION_TO_NORMAL,
AI_Descr[index]. AI_Descr[index]
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); .Acked_Transitions[TRANSITION_TO_NORMAL]
.bIsAcked);
return 1; /* active alarm */ return 1; /* active alarm */
} else } else
@@ -1392,14 +1325,12 @@ int Analog_Input_Alarm_Summary(
} }
#endif /* defined(INTRINSIC_REPORTING) */ #endif /* defined(INTRINSIC_REPORTING) */
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag, uint8_t ucExpectedTag,
BACNET_ERROR_CLASS *pErrorClass, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
@@ -1420,8 +1351,7 @@ bool WPValidateArgType(
return (bResult); return (bResult);
} }
void testAnalogInput( void testAnalogInput(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = { 0 }; uint8_t apdu[MAX_APDU] = { 0 };
int len = 0; int len = 0;
@@ -1450,8 +1380,7 @@ void testAnalogInput(
} }
#ifdef TEST_ANALOG_INPUT #ifdef TEST_ANALOG_INPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+3 -4
View File
@@ -10,8 +10,7 @@
#include "bacnet/datalink/bip.h" #include "bacnet/datalink/bip.h"
long bip_get_addr_by_name( long bip_get_addr_by_name(const char *host_name)
const char *host_name)
{ {
return 0; return 0;
} }
@@ -28,7 +27,6 @@ void bip_cleanup (void)
bool bip_init(char *ifname) bool bip_init(char *ifname)
{ {
tcpip_adapter_ip_info_t ip_info = { 0 }; tcpip_adapter_ip_info_t ip_info = { 0 };
int value = 1; int value = 1;
@@ -38,7 +36,8 @@ bool bip_init(char *ifname)
bip_set_interface(ifname); bip_set_interface(ifname);
bip_set_port(0xBAC0U); bip_set_port(0xBAC0U);
bip_set_addr(ip_info.ip.addr); bip_set_addr(ip_info.ip.addr);
bip_set_broadcast_addr((ip_info.ip.addr&ip_info.netmask.addr)|(~ip_info.netmask.addr)); bip_set_broadcast_addr(
(ip_info.ip.addr & ip_info.netmask.addr) | (~ip_info.netmask.addr));
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
struct sockaddr_in saddr = { 0 }; struct sockaddr_in saddr = { 0 };
+50 -89
View File
@@ -46,42 +46,25 @@
/* the Relinquish Default value */ /* the Relinquish Default value */
#define RELINQUISH_DEFAULT BINARY_INACTIVE #define RELINQUISH_DEFAULT BINARY_INACTIVE
/* Here is our Priority Array.*/ /* Here is our Priority Array.*/
static BACNET_BINARY_PV static BACNET_BINARY_PV Binary_Output_Level[MAX_BINARY_OUTPUTS]
Binary_Output_Level[MAX_BINARY_OUTPUTS][BACNET_MAX_PRIORITY]; [BACNET_MAX_PRIORITY];
/* Writable out-of-service allows others to play with our Present Value */ /* Writable out-of-service allows others to play with our Present Value */
/* without changing the physical output */ /* without changing the physical output */
static bool Out_Of_Service[MAX_BINARY_OUTPUTS]; static bool Out_Of_Service[MAX_BINARY_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Output_Properties_Required[] = { static const int Binary_Output_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS,
PROP_OBJECT_NAME, PROP_EVENT_STATE, PROP_OUT_OF_SERVICE, PROP_POLARITY, PROP_PRIORITY_ARRAY,
PROP_OBJECT_TYPE, PROP_RELINQUISH_DEFAULT, -1 };
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_POLARITY,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
static const int Binary_Output_Properties_Optional[] = { static const int Binary_Output_Properties_Optional[] = { PROP_DESCRIPTION,
PROP_DESCRIPTION, PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1 };
PROP_ACTIVE_TEXT,
PROP_INACTIVE_TEXT,
-1
};
static const int Binary_Output_Properties_Proprietary[] = { static const int Binary_Output_Properties_Proprietary[] = { -1 };
-1
};
void Binary_Output_Property_Lists( void Binary_Output_Property_Lists(
const int **pRequired, const int **pRequired, const int **pOptional, const int **pProprietary)
const int **pOptional,
const int **pProprietary)
{ {
if (pRequired) if (pRequired)
*pRequired = Binary_Output_Properties_Required; *pRequired = Binary_Output_Properties_Required;
@@ -93,8 +76,7 @@ void Binary_Output_Property_Lists(
return; return;
} }
void Binary_Output_Init( void Binary_Output_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
static bool initialized = false; static bool initialized = false;
@@ -116,8 +98,7 @@ void Binary_Output_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Binary_Output_Valid_Instance( bool Binary_Output_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_OUTPUTS) if (object_instance < MAX_BINARY_OUTPUTS)
return true; return true;
@@ -127,8 +108,7 @@ bool Binary_Output_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Binary_Output_Count( unsigned Binary_Output_Count(void)
void)
{ {
return MAX_BINARY_OUTPUTS; return MAX_BINARY_OUTPUTS;
} }
@@ -136,8 +116,7 @@ unsigned Binary_Output_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Binary_Output_Index_To_Instance( uint32_t Binary_Output_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -145,8 +124,7 @@ uint32_t Binary_Output_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Output_Instance_To_Index( unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_OUTPUTS; unsigned index = MAX_BINARY_OUTPUTS;
@@ -156,8 +134,7 @@ unsigned Binary_Output_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Output_Present_Value( BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = RELINQUISH_DEFAULT; BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0; unsigned index = 0;
@@ -176,8 +153,7 @@ BACNET_BINARY_PV Binary_Output_Present_Value(
return value; return value;
} }
bool Binary_Output_Out_Of_Service( bool Binary_Output_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
bool value = false; bool value = false;
unsigned index = 0; unsigned index = 0;
@@ -193,16 +169,14 @@ bool Binary_Output_Out_Of_Service(
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Binary_Output_Object_Name( bool Binary_Output_Object_Name(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
static char text_string[32] = ""; static char text_string[32] = "";
bool status = false; bool status = false;
if (object_instance == 0) if (object_instance == 0)
status = characterstring_init_ansi(object_name, "Led"); status = characterstring_init_ansi(object_name, "Led");
else else {
{
if (object_instance < MAX_BINARY_OUTPUTS) { if (object_instance < MAX_BINARY_OUTPUTS) {
sprintf(text_string, "BINARY OUTPUT %lu", sprintf(text_string, "BINARY OUTPUT %lu",
(unsigned long)object_instance); (unsigned long)object_instance);
@@ -212,10 +186,8 @@ bool Binary_Output_Object_Name(
return status; return status;
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Binary_Output_Read_Property( int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -235,9 +207,8 @@ int Binary_Output_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT, &apdu[0], OBJECT_BINARY_OUTPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
@@ -295,9 +266,8 @@ int Binary_Output_Read_Property(
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
else { else {
present_value = Binary_Output_Level[object_index][i]; present_value = Binary_Output_Level[object_index][i];
len = len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len], present_value);
present_value);
} }
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
@@ -317,11 +287,11 @@ int Binary_Output_Read_Property(
1] == BINARY_NULL) 1] == BINARY_NULL)
apdu_len = encode_application_null(&apdu[apdu_len]); apdu_len = encode_application_null(&apdu[apdu_len]);
else { else {
present_value = Binary_Output_Level[object_index] present_value =
Binary_Output_Level[object_index]
[rpdata->array_index - 1]; [rpdata->array_index - 1];
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len], present_value);
present_value);
} }
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -363,8 +333,7 @@ int Binary_Output_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Output_Write_Property( bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -374,9 +343,8 @@ bool Binary_Output_Write_Property(
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -402,16 +370,16 @@ bool Binary_Output_Write_Property(
(priority != 6 /* reserved */) && (priority != 6 /* reserved */) &&
(value.type.Enumerated <= MAX_BINARY_PV)) { (value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV)value.type.Enumerated; level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index = object_index = Binary_Output_Instance_To_Index(
Binary_Output_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
Binary_Output_Level[object_index][priority] = level; Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we /* Note: you could set the physical output here if we
are the highest priority. are the highest priority.
However, if Out of Service is TRUE, then don't set the However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
status = true; status = true;
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
@@ -424,24 +392,23 @@ bool Binary_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
level = BINARY_NULL; level = BINARY_NULL;
object_index = object_index = Binary_Output_Instance_To_Index(
Binary_Output_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority = wp_data->priority; priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) { if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--; priority--;
Binary_Output_Level[object_index][priority] = level; Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next /* Note: you could set the physical output here to the
highest priority, or to the relinquish default if no next highest priority, or to the relinquish default
priorities are set. if no priorities are set. However, if Out of Service
However, if Out of Service is TRUE, then don't set the is TRUE, then don't set the physical output. This
physical output. This comment may apply to the comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
} else { } else {
status = false; status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -451,14 +418,12 @@ bool Binary_Output_Write_Property(
} }
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
object_index = object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance); Binary_Output_Instance_To_Index(wp_data->object_instance);
Out_Of_Service[object_index] = Out_Of_Service[object_index] = value.type.Boolean;
value.type.Boolean;
} }
break; break;
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
@@ -484,14 +449,12 @@ bool Binary_Output_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue,
uint8_t ucExpectedTag, uint8_t ucExpectedTag,
BACNET_ERROR_CLASS *pErrorClass, BACNET_ERROR_CLASS *pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
@@ -504,8 +467,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testBinaryOutput( void testBinaryOutput(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = { 0 }; uint8_t apdu[MAX_APDU] = { 0 };
int len = 0; int len = 0;
@@ -534,8 +496,7 @@ void testBinaryOutput(
} }
#ifdef TEST_BINARY_OUTPUT #ifdef TEST_BINARY_OUTPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+181 -325
View File
File diff suppressed because it is too large Load Diff
+25 -30
View File
@@ -61,19 +61,18 @@ void StartBACnet()
/* set the handler for all the services we don't implement */ /* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */ /* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(
handler_read_property); SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE, apdu_set_confirmed_handler(
handler_read_property_multiple); SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, apdu_set_confirmed_handler(
handler_write_property); SERVICE_CONFIRMED_WRITE_PROPERTY, handler_write_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, apdu_set_confirmed_handler(
handler_cov_subscribe); SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
address_init(); address_init();
bip_init(NULL); bip_init(NULL);
@@ -90,8 +89,7 @@ esp_err_t wifi_event_handler(void *ctx, system_event_t *event)
case SYSTEM_EVENT_STA_CONNECTED: case SYSTEM_EVENT_STA_CONNECTED:
break; break;
case SYSTEM_EVENT_STA_GOT_IP: case SYSTEM_EVENT_STA_GOT_IP:
if (xEventGroupGetBits(wifi_event_group)!=CONNECTED_BIT) if (xEventGroupGetBits(wifi_event_group) != CONNECTED_BIT) {
{
xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);
StartBACnet(); StartBACnet();
} }
@@ -137,8 +135,7 @@ void setup()
gpio_set_level(BACNET_LED, 0); gpio_set_level(BACNET_LED, 0);
esp_err_t ret = nvs_flash_init(); esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
{
nvs_flash_erase(); nvs_flash_erase();
ret = nvs_flash_init(); ret = nvs_flash_init();
} }
@@ -149,9 +146,7 @@ void setup()
void BACnetTask(void *pvParameters) void BACnetTask(void *pvParameters)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
BACNET_ADDRESS src = { BACNET_ADDRESS src = { 0 };
0
};
unsigned timeout = 1; unsigned timeout = 1;
// Init Bacnet objets dictionnary // Init Bacnet objets dictionnary
@@ -162,18 +157,20 @@ void BACnetTask(void *pvParameters)
uint32_t tickcount = xTaskGetTickCount(); uint32_t tickcount = xTaskGetTickCount();
for (;;) for (;;) {
{ vTaskDelay(
vTaskDelay(10 / portTICK_PERIOD_MS); // could be remove to speed the code 10 / portTICK_PERIOD_MS); // could be remove to speed the code
// do nothing if not connected to wifi // do nothing if not connected to wifi
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); xEventGroupWaitBits(
wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
{ {
uint32_t newtick = xTaskGetTickCount(); uint32_t newtick = xTaskGetTickCount();
// one second elapse at least (maybe much more if Wifi was deconnected for a long) // one second elapse at least (maybe much more if Wifi was
if ((newtick<tickcount)||((newtick-tickcount)>=configTICK_RATE_HZ)) // deconnected for a long)
{ if ((newtick < tickcount) ||
((newtick - tickcount) >= configTICK_RATE_HZ)) {
tickcount = newtick; tickcount = newtick;
dcc_timer_seconds(1); dcc_timer_seconds(1);
bvlc_maintenance_timer(1); bvlc_maintenance_timer(1);
@@ -183,12 +180,10 @@ void BACnetTask(void *pvParameters)
// Read analog values from internal sensors // Read analog values from internal sensors
Analog_Input_Present_Value_Set(0, temprature_sens_read()); Analog_Input_Present_Value_Set(0, temprature_sens_read());
Analog_Input_Present_Value_Set(1, hall_sens_read()); Analog_Input_Present_Value_Set(1, hall_sens_read());
} }
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout); pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
if (pdu_len) if (pdu_len) {
{
npdu_handler(&src, &Rx_Buf[0], pdu_len); npdu_handler(&src, &Rx_Buf[0], pdu_len);
if (Binary_Output_Present_Value(0) == BINARY_ACTIVE) if (Binary_Output_Present_Value(0) == BINARY_ACTIVE)
@@ -204,9 +199,9 @@ void BACnetTask(void *pvParameters)
/* Entry point */ /* Entry point */
void app_main() void app_main()
{ {
// Cannot run BACnet code here, the default stack size is to small : 4096 byte // Cannot run BACnet code here, the default stack size is to small : 4096
xTaskCreate( // byte
BACnetTask, /* Function to implement the task */ xTaskCreate(BACnetTask, /* Function to implement the task */
"BACnetTask", /* Name of the task */ "BACnetTask", /* Name of the task */
10000, /* Stack size in words */ 10000, /* Stack size in words */
NULL, /* Task input parameter */ NULL, /* Task input parameter */
+17 -23
View File
@@ -82,14 +82,12 @@ clockp Clock Prescaler DataRate
*/ */
bool arcnet_valid( bool arcnet_valid(void)
void)
{ {
return (ARCNET_Sock_FD >= 0); return (ARCNET_Sock_FD >= 0);
} }
void arcnet_cleanup( void arcnet_cleanup(void)
void)
{ {
if (arcnet_valid()) if (arcnet_valid())
close(ARCNET_Sock_FD); close(ARCNET_Sock_FD);
@@ -98,8 +96,7 @@ void arcnet_cleanup(
return; return;
} }
static int arcnet_bind( static int arcnet_bind(char *interface_name)
char *interface_name)
{ {
int sock_fd = -1; /* return value */ int sock_fd = -1; /* return value */
struct ifreq ifr; struct ifreq ifr;
@@ -126,13 +123,15 @@ static int arcnet_bind(
"You might need to add the following to modules.conf\n" "You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n" "(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n" "alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n" "Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n"); "# modprobe af_packet\n");
exit(-1); exit(-1);
} }
if (ARCNET_Sock_FD >= 0) { if (ARCNET_Sock_FD >= 0) {
/* Bind the socket to an interface name so we only get packets from it */ /* Bind the socket to an interface name so we only get packets from it
*/
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET; ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
/*ARCNET_Socket_Address.sa_family = PF_INET; */ /*ARCNET_Socket_Address.sa_family = PF_INET; */
/* Clear the memory before copying */ /* Clear the memory before copying */
@@ -141,8 +140,8 @@ static int arcnet_bind(
/* Strcpy the interface name into the address */ /* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name, strncpy(ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data) - 1); sizeof(ARCNET_Socket_Address.sa_data) - 1);
fprintf(stderr, "arcnet: binding \"%s\"\n", fprintf(
ARCNET_Socket_Address.sa_data); stderr, "arcnet: binding \"%s\"\n", ARCNET_Socket_Address.sa_data);
if (bind(sock_fd, &ARCNET_Socket_Address, if (bind(sock_fd, &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)) != 0) { sizeof(ARCNET_Socket_Address)) != 0) {
/* Bind problem, close socket and return */ /* Bind problem, close socket and return */
@@ -152,7 +151,8 @@ static int arcnet_bind(
"You might need to add the following to modules.conf\n" "You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n" "(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n" "alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n" "Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n"); "# modprobe af_packet\n");
/* Close the socket */ /* Close the socket */
close(sock_fd); close(sock_fd);
@@ -180,8 +180,7 @@ static int arcnet_bind(
return sock_fd; return sock_fd;
} }
bool arcnet_init( bool arcnet_init(char *interface_name)
char *interface_name)
{ {
if (interface_name) if (interface_name)
ARCNET_Sock_FD = arcnet_bind(interface_name); ARCNET_Sock_FD = arcnet_bind(interface_name);
@@ -193,8 +192,7 @@ bool arcnet_init(
/* function to send a PDU out the socket */ /* function to send a PDU out the socket */
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
int arcnet_send_pdu( int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -240,8 +238,7 @@ int arcnet_send_pdu(
} }
memcpy(&pkt->soft.raw[4], pdu, pdu_len); memcpy(&pkt->soft.raw[4], pdu, pdu_len);
/* Send the packet */ /* Send the packet */
bytes = bytes = sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
(struct sockaddr *)&ARCNET_Socket_Address, (struct sockaddr *)&ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)); sizeof(ARCNET_Socket_Address));
/* did it get sent? */ /* did it get sent? */
@@ -253,8 +250,7 @@ int arcnet_send_pdu(
/* receives an framed packet */ /* receives an framed packet */
/* returns the number of octets in the PDU, or zero on failure */ /* returns the number of octets in the PDU, or zero on failure */
uint16_t arcnet_receive( uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -352,8 +348,7 @@ uint16_t arcnet_receive(
return pdu_len; return pdu_len;
} }
void arcnet_get_my_address( void arcnet_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; int i = 0;
@@ -368,8 +363,7 @@ void arcnet_get_my_address(
return; return;
} }
void arcnet_get_broadcast_address( void arcnet_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
+41 -67
View File
@@ -45,16 +45,16 @@
#include "bacnet/basic/bbmd6/h_bbmd6.h" #include "bacnet/basic/bbmd6/h_bbmd6.h"
#include "bacport.h" #include "bacport.h"
static void debug_print_ipv6(const char *str, const struct in6_addr * addr) { static void debug_print_ipv6(const char *str, const struct in6_addr *addr)
debug_printf( "BIP6: %s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", {
str, debug_printf("BIP6: %s "
(int)addr->s6_addr[0], (int)addr->s6_addr[1], "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%"
(int)addr->s6_addr[2], (int)addr->s6_addr[3], "02x:%02x%02x\n",
(int)addr->s6_addr[4], (int)addr->s6_addr[5], str, (int)addr->s6_addr[0], (int)addr->s6_addr[1],
(int)addr->s6_addr[6], (int)addr->s6_addr[7], (int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[4],
(int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[5], (int)addr->s6_addr[6], (int)addr->s6_addr[7],
(int)addr->s6_addr[10], (int)addr->s6_addr[11], (int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[10],
(int)addr->s6_addr[12], (int)addr->s6_addr[13], (int)addr->s6_addr[11], (int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]); (int)addr->s6_addr[14], (int)addr->s6_addr[15]);
} }
@@ -71,8 +71,7 @@ static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
* *
* @param ifname - C string for name or text address * @param ifname - C string for name or text address
*/ */
void bip6_set_interface( void bip6_set_interface(char *ifname)
char *ifname)
{ {
struct ifaddrs *ifa, *ifa_tmp; struct ifaddrs *ifa, *ifa_tmp;
struct sockaddr_in6 *sin; struct sockaddr_in6 *sin;
@@ -85,16 +84,13 @@ void bip6_set_interface(
ifa_tmp = ifa; ifa_tmp = ifa;
debug_printf("BIP6: seeking interface: %s\n", ifname); debug_printf("BIP6: seeking interface: %s\n", ifname);
while (ifa_tmp) { while (ifa_tmp) {
if ((ifa_tmp->ifa_addr) && if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
(ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
debug_printf("BIP6: found interface: %s\n", ifa_tmp->ifa_name); debug_printf("BIP6: found interface: %s\n", ifa_tmp->ifa_name);
} }
if ((ifa_tmp->ifa_addr) && if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
(ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
(strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) { (strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) {
sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr; sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr;
bvlc6_address_set(&BIP6_Addr, bvlc6_address_set(&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]),
ntohs(sin->sin6_addr.s6_addr16[0]),
ntohs(sin->sin6_addr.s6_addr16[1]), ntohs(sin->sin6_addr.s6_addr16[1]),
ntohs(sin->sin6_addr.s6_addr16[2]), ntohs(sin->sin6_addr.s6_addr16[2]),
ntohs(sin->sin6_addr.s6_addr16[3]), ntohs(sin->sin6_addr.s6_addr16[3]),
@@ -119,8 +115,7 @@ void bip6_set_interface(
* *
* @param port - IPv6 UDP port number * @param port - IPv6 UDP port number
*/ */
void bip6_set_port( void bip6_set_port(uint16_t port)
uint16_t port)
{ {
BIP6_Addr.port = port; BIP6_Addr.port = port;
BIP6_Broadcast_Addr.port = port; BIP6_Broadcast_Addr.port = port;
@@ -131,8 +126,7 @@ void bip6_set_port(
* *
* @return IPv6 UDP port number * @return IPv6 UDP port number
*/ */
uint16_t bip6_get_port( uint16_t bip6_get_port(void)
void)
{ {
return BIP6_Addr.port; return BIP6_Addr.port;
} }
@@ -143,8 +137,7 @@ uint16_t bip6_get_port(
* *
* @param addr - IPv6 source address * @param addr - IPv6 source address
*/ */
void bip6_get_broadcast_address( void bip6_get_broadcast_address(BACNET_ADDRESS *addr)
BACNET_ADDRESS * addr)
{ {
if (addr) { if (addr) {
addr->net = BACNET_BROADCAST_NETWORK; addr->net = BACNET_BROADCAST_NETWORK;
@@ -158,8 +151,7 @@ void bip6_get_broadcast_address(
* *
* @param addr - IPv6 source address * @param addr - IPv6 source address
*/ */
void bip6_get_my_address( void bip6_get_my_address(BACNET_ADDRESS *addr)
BACNET_ADDRESS * addr)
{ {
uint32_t device_id = 0; uint32_t device_id = 0;
@@ -174,8 +166,7 @@ void bip6_get_my_address(
* *
* @param addr - network IPv6 address * @param addr - network IPv6 address
*/ */
bool bip6_set_addr( bool bip6_set_addr(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
return bvlc6_address_copy(&BIP6_Addr, addr); return bvlc6_address_copy(&BIP6_Addr, addr);
} }
@@ -185,8 +176,7 @@ bool bip6_set_addr(
* *
* @return BACnet/IP address * @return BACnet/IP address
*/ */
bool bip6_get_addr( bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
return bvlc6_address_copy(addr, &BIP6_Addr); return bvlc6_address_copy(addr, &BIP6_Addr);
} }
@@ -196,8 +186,7 @@ bool bip6_get_addr(
* *
* @param addr - network IPv6 address * @param addr - network IPv6 address
*/ */
bool bip6_set_broadcast_addr( bool bip6_set_broadcast_addr(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
return bvlc6_address_copy(&BIP6_Broadcast_Addr, addr); return bvlc6_address_copy(&BIP6_Broadcast_Addr, addr);
} }
@@ -207,8 +196,7 @@ bool bip6_set_broadcast_addr(
* *
* @return BACnet/IP address * @return BACnet/IP address
*/ */
bool bip6_get_broadcast_addr( bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr); return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
} }
@@ -224,10 +212,7 @@ bool bip6_get_broadcast_addr(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
int bip6_send_mpdu( int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
BACNET_IP6_ADDRESS *dest,
uint8_t * mtu,
uint16_t mtu_len)
{ {
struct sockaddr_in6 bvlc_dest = { 0 }; struct sockaddr_in6 bvlc_dest = { 0 };
uint16_t addr16[8]; uint16_t addr16[8];
@@ -286,10 +271,7 @@ int bip6_send_pdu(BACNET_ADDRESS *dest,
* @return Number of bytes received, or 0 if none or timeout. * @return Number of bytes received, or 0 if none or timeout.
*/ */
uint16_t bip6_receive( uint16_t bip6_receive(
BACNET_ADDRESS * src, BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout)
uint8_t * npdu,
uint16_t max_npdu,
unsigned timeout)
{ {
uint16_t npdu_len = 0; /* return value */ uint16_t npdu_len = 0; /* return value */
fd_set read_fds; fd_set read_fds;
@@ -322,8 +304,7 @@ uint16_t bip6_receive(
max = BIP6_Socket; max = BIP6_Socket;
/* see if there is a packet for us */ /* see if there is a packet for us */
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
received_bytes = received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0,
recvfrom(BIP6_Socket, (char *) &npdu[0], max_npdu, 0,
(struct sockaddr *)&sin, &sin_len); (struct sockaddr *)&sin, &sin_len);
} else { } else {
return 0; return 0;
@@ -342,14 +323,10 @@ uint16_t bip6_receive(
} }
/* pass the packet into the BBMD handler */ /* pass the packet into the BBMD handler */
debug_print_ipv6("Received MPDU->", &sin.sin6_addr); debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
bvlc6_address_set(&addr, bvlc6_address_set(&addr, ntohs(sin.sin6_addr.s6_addr16[0]),
ntohs(sin.sin6_addr.s6_addr16[0]), ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[2]),
ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[3]), ntohs(sin.sin6_addr.s6_addr16[4]),
ntohs(sin.sin6_addr.s6_addr16[2]), ntohs(sin.sin6_addr.s6_addr16[5]), ntohs(sin.sin6_addr.s6_addr16[6]),
ntohs(sin.sin6_addr.s6_addr16[3]),
ntohs(sin.sin6_addr.s6_addr16[4]),
ntohs(sin.sin6_addr.s6_addr16[5]),
ntohs(sin.sin6_addr.s6_addr16[6]),
ntohs(sin.sin6_addr.s6_addr16[7])); ntohs(sin.sin6_addr.s6_addr16[7]));
addr.port = ntohs(sin.sin6_port); addr.port = ntohs(sin.sin6_port);
offset = bvlc6_handler(&addr, src, npdu, received_bytes); offset = bvlc6_handler(&addr, src, npdu, received_bytes);
@@ -371,8 +348,7 @@ uint16_t bip6_receive(
/** Cleanup and close out the BACnet/IP services by closing the socket. /** Cleanup and close out the BACnet/IP services by closing the socket.
* @ingroup DLBIP6 * @ingroup DLBIP6
*/ */
void bip6_cleanup( void bip6_cleanup(void)
void)
{ {
if (BIP6_Socket != -1) { if (BIP6_Socket != -1) {
close(BIP6_Socket); close(BIP6_Socket);
@@ -399,8 +375,7 @@ void bip6_cleanup(
* @return True if the socket is successfully opened for BACnet/IP, * @return True if the socket is successfully opened for BACnet/IP,
* else False if the socket functions fail. * else False if the socket functions fail.
*/ */
bool bip6_init( bool bip6_init(char *ifname)
char *ifname)
{ {
int status = 0; /* return from socket lib calls */ int status = 0; /* return from socket lib calls */
struct sockaddr_in6 server = { 0 }; struct sockaddr_in6 server = { 0 };
@@ -418,9 +393,8 @@ bool bip6_init(
} }
debug_printf("BIP6: IPv6 UDP port: 0x%04X\n", htons(BIP6_Addr.port)); debug_printf("BIP6: IPv6 UDP port: 0x%04X\n", htons(BIP6_Addr.port));
if (BIP6_Broadcast_Addr.address[0] == 0) { if (BIP6_Broadcast_Addr.address[0] == 0) {
bvlc6_address_set(&BIP6_Broadcast_Addr, bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0,
BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID);
BIP6_MULTICAST_GROUP_ID);
} }
/* assumes that the driver has already been initialized */ /* assumes that the driver has already been initialized */
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
@@ -429,26 +403,26 @@ bool bip6_init(
/* Allow us to use the same socket for sending and receiving */ /* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */ /* This makes sure that the src port is correct when sending */
sockopt = 1; sockopt = 1;
status = status = setsockopt(
setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt, BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
sizeof(sockopt));
if (status < 0) { if (status < 0) {
close(BIP6_Socket); close(BIP6_Socket);
BIP6_Socket = -1; BIP6_Socket = -1;
return status; return status;
} }
/* allow us to send a broadcast */ /* allow us to send a broadcast */
status = status = setsockopt(
setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt, BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt, sizeof(sockopt));
sizeof(sockopt));
if (status < 0) { if (status < 0) {
close(BIP6_Socket); close(BIP6_Socket);
BIP6_Socket = -1; BIP6_Socket = -1;
return false; return false;
} }
/* subscribe to a multicast address */ /* subscribe to a multicast address */
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], IP6_ADDRESS_MAX); memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0],
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address, sizeof(struct in6_addr)); IP6_ADDRESS_MAX);
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address,
sizeof(struct in6_addr));
/* Let system choose the interface */ /* Let system choose the interface */
join_request.ipv6mr_interface = 0; join_request.ipv6mr_interface = 0;
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+2 -4
View File
@@ -27,8 +27,7 @@
* @param true if DST is enabled and active * @param true if DST is enabled and active
* @return true if local time was retrieved * @return true if local time was retrieved
*/ */
bool datetime_local( bool datetime_local(BACNET_DATE *bdate,
BACNET_DATE * bdate,
BACNET_TIME *btime, BACNET_TIME *btime,
int16_t *utc_offset_minutes, int16_t *utc_offset_minutes,
bool *dst_active) bool *dst_active)
@@ -54,8 +53,7 @@ bool datetime_local(
* int tm_isdst Daylight Savings flag. * int tm_isdst Daylight Savings flag.
*/ */
datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900, datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900,
(uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday);
(uint8_t)tblock->tm_mday);
datetime_set_time(btime, (uint8_t)tblock->tm_hour, datetime_set_time(btime, (uint8_t)tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
(uint8_t)(tv.tv_usec / 10000)); (uint8_t)(tv.tv_usec / 10000));
+58 -80
View File
@@ -42,7 +42,8 @@
/* OS Specific include */ /* OS Specific include */
#include "bacport.h" #include "bacport.h"
/** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP. */ /** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP.
*/
/* Number of MS/TP Packets Rx/Tx */ /* Number of MS/TP Packets Rx/Tx */
uint16_t MSTP_Packets = 0; uint16_t MSTP_Packets = 0;
@@ -108,9 +109,8 @@ static struct timespec start;
* *
* @returns True if the difference is negative, otherwise 0. * @returns True if the difference is negative, otherwise 0.
*/ */
static int timespec_subtract(struct timespec *result, static int timespec_subtract(
const struct timespec *l, struct timespec *result, const struct timespec *l, const struct timespec *r)
const struct timespec *r)
{ {
#define NS_PER_S 1000000000 // nano-seconds per second #define NS_PER_S 1000000000 // nano-seconds per second
struct timespec right = *r; struct timespec right = *r;
@@ -154,8 +154,7 @@ static void timespec_add_ns(struct timespec *ts, long ns)
} }
} }
static uint32_t Timer_Silence( static uint32_t Timer_Silence(void *pArg)
void *pArg)
{ {
struct timespec now, diff; struct timespec now, diff;
int32_t res; int32_t res;
@@ -167,15 +166,12 @@ static uint32_t Timer_Silence(
return (res >= 0 ? res : 0); return (res >= 0 ? res : 0);
} }
static void Timer_Silence_Reset( static void Timer_Silence_Reset(void *pArg)
void *pArg)
{ {
clock_gettime(CLOCK_MONOTONIC, &start); clock_gettime(CLOCK_MONOTONIC, &start);
} }
static void get_abstime( static void get_abstime(struct timespec *abstime, unsigned long milliseconds)
struct timespec *abstime,
unsigned long milliseconds)
{ {
clock_gettime(CLOCK_MONOTONIC, abstime); clock_gettime(CLOCK_MONOTONIC, abstime);
if (milliseconds > 1000) { if (milliseconds > 1000) {
@@ -186,8 +182,7 @@ static void get_abstime(
timespec_add_ns(abstime, 1000000 * milliseconds); timespec_add_ns(abstime, 1000000 * milliseconds);
} }
void dlmstp_cleanup( void dlmstp_cleanup(void)
void)
{ {
pthread_cond_destroy(&Received_Frame_Flag); pthread_cond_destroy(&Received_Frame_Flag);
pthread_cond_destroy(&Receive_Packet_Flag); pthread_cond_destroy(&Receive_Packet_Flag);
@@ -198,8 +193,7 @@ void dlmstp_cleanup(
} }
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu( int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -229,8 +223,7 @@ int dlmstp_send_pdu(
return bytes_sent; return bytes_sent;
} }
uint16_t dlmstp_receive( uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -243,8 +236,8 @@ uint16_t dlmstp_receive(
to put the reply (if necessary) and process it */ to put the reply (if necessary) and process it */
pthread_mutex_lock(&Receive_Packet_Mutex); pthread_mutex_lock(&Receive_Packet_Mutex);
get_abstime(&abstime, timeout); get_abstime(&abstime, timeout);
pthread_cond_timedwait(&Receive_Packet_Flag, &Receive_Packet_Mutex, pthread_cond_timedwait(
&abstime); &Receive_Packet_Flag, &Receive_Packet_Mutex, &abstime);
if (Receive_Packet.ready) { if (Receive_Packet.ready) {
if (Receive_Packet.pdu_len) { if (Receive_Packet.pdu_len) {
MSTP_Packets++; MSTP_Packets++;
@@ -253,8 +246,7 @@ uint16_t dlmstp_receive(
sizeof(Receive_Packet.address)); sizeof(Receive_Packet.address));
} }
if (pdu) { if (pdu) {
memmove(pdu, &Receive_Packet.pdu, memmove(pdu, &Receive_Packet.pdu, sizeof(Receive_Packet.pdu));
sizeof(Receive_Packet.pdu));
} }
pdu_len = Receive_Packet.pdu_len; pdu_len = Receive_Packet.pdu_len;
} }
@@ -265,8 +257,7 @@ uint16_t dlmstp_receive(
return pdu_len; return pdu_len;
} }
static void *dlmstp_master_fsm_task( static void *dlmstp_master_fsm_task(void *pArg)
void *pArg)
{ {
uint32_t silence = 0; uint32_t silence = 0;
bool run_master = false; bool run_master = false;
@@ -314,9 +305,7 @@ static void *dlmstp_master_fsm_task(
return NULL; return NULL;
} }
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
BACNET_ADDRESS * src,
uint8_t mstp_address)
{ {
int i = 0; int i = 0;
@@ -340,8 +329,7 @@ void dlmstp_fill_bacnet_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 MSTP_Put_Receive( uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
@@ -359,8 +347,8 @@ uint16_t MSTP_Put_Receive(
} }
memmove((void *)&Receive_Packet.pdu[0], memmove((void *)&Receive_Packet.pdu[0],
(void *)&mstp_port->InputBuffer[0], pdu_len); (void *)&mstp_port->InputBuffer[0], pdu_len);
dlmstp_fill_bacnet_address(&Receive_Packet.address, dlmstp_fill_bacnet_address(
mstp_port->SourceAddress); &Receive_Packet.address, mstp_port->SourceAddress);
Receive_Packet.pdu_len = mstp_port->DataLength; Receive_Packet.pdu_len = mstp_port->DataLength;
Receive_Packet.ready = true; Receive_Packet.ready = true;
pthread_cond_signal(&Receive_Packet_Flag); pthread_cond_signal(&Receive_Packet_Flag);
@@ -373,8 +361,7 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */ /* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */ /* Return: amount of PDU data */
uint16_t MSTP_Get_Send( uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
uint8_t frame_type = 0; uint8_t frame_type = 0;
@@ -391,7 +378,8 @@ uint16_t MSTP_Get_Send(
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
} }
/* convert the PDU into the MSTP Frame */ /* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&PDU_Queue, NULL); (void)Ringbuf_Pop(&PDU_Queue, NULL);
@@ -399,8 +387,7 @@ uint16_t MSTP_Get_Send(
return pdu_len; return pdu_len;
} }
static bool dlmstp_compare_data_expecting_reply( static bool dlmstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint8_t * request_pdu,
uint16_t request_pdu_len, uint16_t request_pdu_len,
uint8_t src_address, uint8_t src_address,
uint8_t *reply_pdu, uint8_t *reply_pdu,
@@ -427,13 +414,13 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the request data */ /* decode the request data */
request.address.mac[0] = src_address; request.address.mac[0] = src_address;
request.address.mac_len = 1; request.address.mac_len = 1;
offset = offset = npdu_decode(
npdu_decode(&request_pdu[0], NULL, &request.address, &request_pdu[0], NULL, &request.address, &request.npdu_data);
&request.npdu_data);
if (request.npdu_data.network_layer_message) { if (request.npdu_data.network_layer_message) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Request is Network message.\n"); "DLMSTP: DER Compare failed: "
"Request is Network message.\n");
#endif #endif
return false; return false;
} }
@@ -441,7 +428,8 @@ static bool dlmstp_compare_data_expecting_reply(
if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) { if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Not Confirmed Request.\n"); "DLMSTP: DER Compare failed: "
"Not Confirmed Request.\n");
#endif #endif
return false; return false;
} }
@@ -455,12 +443,12 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */ /* decode the reply data */
reply.address.mac[0] = dest_address; reply.address.mac[0] = dest_address;
reply.address.mac_len = 1; reply.address.mac_len = 1;
offset = offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Reply is Network message.\n"); "DLMSTP: DER Compare failed: "
"Reply is Network message.\n");
#endif #endif
return false; return false;
} }
@@ -498,7 +486,8 @@ static bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) { if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n"); "DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif #endif
return false; return false;
} }
@@ -506,19 +495,22 @@ static bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) { if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n"); "DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif #endif
return false; return false;
} }
if (request.service_choice != reply.service_choice) { if (request.service_choice != reply.service_choice) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Service choice mismatch.\n"); "DLMSTP: DER Compare failed: "
"Service choice mismatch.\n");
#endif #endif
return false; return false;
} }
} }
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) { if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "DLMSTP: DER Compare failed: "
@@ -540,7 +532,8 @@ static bool dlmstp_compare_data_expecting_reply(
if (!bacnet_address_same(&request.address, &reply.address)) { if (!bacnet_address_same(&request.address, &reply.address)) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "BACnet Address mismatch.\n"); "DLMSTP: DER Compare failed: "
"BACnet Address mismatch.\n");
#endif #endif
return false; return false;
} }
@@ -550,8 +543,7 @@ static bool dlmstp_compare_data_expecting_reply(
/* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */ /* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */
uint16_t MSTP_Get_Reply( uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */ uint16_t pdu_len = 0; /* return value */
bool matched = false; bool matched = false;
@@ -564,8 +556,7 @@ uint16_t MSTP_Get_Reply(
} }
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue); pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
/* is this the reply to the DER? */ /* is this the reply to the DER? */
matched = matched = dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
mstp_port->DataLength, mstp_port->SourceAddress, mstp_port->DataLength, mstp_port->SourceAddress,
(uint8_t *)&pkt->buffer[0], pkt->length, pkt->destination_mac); (uint8_t *)&pkt->buffer[0], pkt->length, pkt->destination_mac);
if (!matched) { if (!matched) {
@@ -577,7 +568,8 @@ uint16_t MSTP_Get_Reply(
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
} }
/* convert the PDU into the MSTP Frame */ /* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&PDU_Queue, NULL); (void)Ringbuf_Pop(&PDU_Queue, NULL);
@@ -585,8 +577,7 @@ uint16_t MSTP_Get_Reply(
return pdu_len; return pdu_len;
} }
void dlmstp_set_mac_address( void dlmstp_set_mac_address(uint8_t mac_address)
uint8_t mac_address)
{ {
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
@@ -603,8 +594,7 @@ void dlmstp_set_mac_address(
return; return;
} }
uint8_t dlmstp_mac_address( uint8_t dlmstp_mac_address(void)
void)
{ {
return MSTP_Port.This_Station; return MSTP_Port.This_Station;
} }
@@ -616,8 +606,7 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */ /* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(uint8_t max_info_frames)
uint8_t max_info_frames)
{ {
if (max_info_frames >= 1) { if (max_info_frames >= 1) {
MSTP_Port.Nmax_info_frames = max_info_frames; MSTP_Port.Nmax_info_frames = max_info_frames;
@@ -631,8 +620,7 @@ void dlmstp_set_max_info_frames(
return; return;
} }
uint8_t dlmstp_max_info_frames( uint8_t dlmstp_max_info_frames(void)
void)
{ {
return MSTP_Port.Nmax_info_frames; return MSTP_Port.Nmax_info_frames;
} }
@@ -642,8 +630,7 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */ /* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
void dlmstp_set_max_master( void dlmstp_set_max_master(uint8_t max_master)
uint8_t max_master)
{ {
if (max_master <= 127) { if (max_master <= 127) {
if (MSTP_Port.This_Station <= max_master) { if (MSTP_Port.This_Station <= max_master) {
@@ -659,27 +646,23 @@ void dlmstp_set_max_master(
return; return;
} }
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void)
void)
{ {
return MSTP_Port.Nmax_master; return MSTP_Port.Nmax_master;
} }
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */ /* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
void dlmstp_set_baud_rate( void dlmstp_set_baud_rate(uint32_t baud)
uint32_t baud)
{ {
RS485_Set_Baud_Rate(baud); RS485_Set_Baud_Rate(baud);
} }
uint32_t dlmstp_baud_rate( uint32_t dlmstp_baud_rate(void)
void)
{ {
return RS485_Get_Baud_Rate(); return RS485_Get_Baud_Rate();
} }
void dlmstp_get_my_address( void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
@@ -694,8 +677,7 @@ void dlmstp_get_my_address(
return; return;
} }
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
@@ -712,8 +694,7 @@ void dlmstp_get_broadcast_address(
return; return;
} }
bool dlmstp_init( bool dlmstp_init(char *ifname)
char *ifname)
{ {
unsigned long hThread = 0; unsigned long hThread = 0;
pthread_condattr_t attr; pthread_condattr_t attr;
@@ -782,8 +763,7 @@ bool dlmstp_init(
#ifdef TEST_DLMSTP #ifdef TEST_DLMSTP
#include <stdio.h> #include <stdio.h>
void apdu_handler( void apdu_handler(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *apdu, /* APDU data */ uint8_t *apdu, /* APDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* for confirmed messages */ { /* for confirmed messages */
@@ -794,9 +774,7 @@ void apdu_handler(
static char *Network_Interface = NULL; static char *Network_Interface = NULL;
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
+89 -129
View File
@@ -41,20 +41,24 @@
#include "bacport.h" #include "bacport.h"
#include "bacnet/basic/sys/ringbuf.h" #include "bacnet/basic/sys/ringbuf.h"
/** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP. */ /** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP.
*/
#define BACNET_PDU_CONTROL_BYTE_OFFSET 1 #define BACNET_PDU_CONTROL_BYTE_OFFSET 1
#define BACNET_DATA_EXPECTING_REPLY_BIT 2 #define BACNET_DATA_EXPECTING_REPLY_BIT 2
#define BACNET_DATA_EXPECTING_REPLY(control) ( (control & (1 << BACNET_DATA_EXPECTING_REPLY_BIT) ) > 0 ) #define BACNET_DATA_EXPECTING_REPLY(control) \
((control & (1 << BACNET_DATA_EXPECTING_REPLY_BIT)) > 0)
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;} #define INCREMENT_AND_LIMIT_UINT16(x) \
uint32_t Timer_Silence( { \
void *poPort) if (x < 0xFFFF) \
x++; \
}
uint32_t Timer_Silence(void *poPort)
{ {
struct timeval now, tmp_diff; struct timeval now, tmp_diff;
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return -1; return -1;
} }
@@ -72,12 +76,10 @@ uint32_t Timer_Silence(
return (res >= 0 ? res : -res); return (res >= 0 ? res : -res);
} }
void Timer_Silence_Reset( void Timer_Silence_Reset(void *poPort)
void *poPort)
{ {
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -89,9 +91,7 @@ void Timer_Silence_Reset(
gettimeofday(&poSharedData->start, NULL); gettimeofday(&poSharedData->start, NULL);
} }
void get_abstime( void get_abstime(struct timespec *abstime, unsigned long milliseconds)
struct timespec *abstime,
unsigned long milliseconds)
{ {
struct timeval now, offset, result; struct timeval now, offset, result;
@@ -103,12 +103,10 @@ void get_abstime(
abstime->tv_nsec = result.tv_usec * 1000; abstime->tv_nsec = result.tv_usec * 1000;
} }
void dlmstp_cleanup( void dlmstp_cleanup(void *poPort)
void *poPort)
{ {
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -118,8 +116,7 @@ void dlmstp_cleanup(
} }
/* restore the old port settings */ /* restore the old port settings */
tcsetattr(poSharedData->RS485_Handle, TCSANOW, tcsetattr(poSharedData->RS485_Handle, TCSANOW, &poSharedData->RS485_oldtio);
&poSharedData->RS485_oldtio);
close(poSharedData->RS485_Handle); close(poSharedData->RS485_Handle);
pthread_cond_destroy(&poSharedData->Received_Frame_Flag); pthread_cond_destroy(&poSharedData->Received_Frame_Flag);
@@ -130,8 +127,7 @@ void dlmstp_cleanup(
} }
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu( int dlmstp_send_pdu(void *poPort,
void *poPort,
BACNET_ADDRESS *dest, /* destination address */ BACNET_ADDRESS *dest, /* destination address */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -140,8 +136,7 @@ int dlmstp_send_pdu(
struct mstp_pdu_packet *pkt; struct mstp_pdu_packet *pkt;
unsigned i = 0; unsigned i = 0;
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return 0; return 0;
} }
@@ -167,8 +162,7 @@ int dlmstp_send_pdu(
return bytes_sent; return bytes_sent;
} }
uint16_t dlmstp_receive( uint16_t dlmstp_receive(void *poPort,
void *poPort,
BACNET_ADDRESS *src, /* source address */ BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
@@ -178,8 +172,7 @@ uint16_t dlmstp_receive(
struct timespec abstime; struct timespec abstime;
int rv = 0; int rv = 0;
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return 0; return 0;
} }
@@ -213,8 +206,7 @@ uint16_t dlmstp_receive(
return pdu_len; return pdu_len;
} }
void *dlmstp_receive_fsm_task( void *dlmstp_receive_fsm_task(void *pArg)
void *pArg)
{ {
bool received_frame; bool received_frame;
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
@@ -235,8 +227,8 @@ void *dlmstp_receive_fsm_task(
(mstp_port->ReceivedInvalidFrame == false)) { (mstp_port->ReceivedInvalidFrame == false)) {
do { do {
RS485_Check_UART_Data(mstp_port); RS485_Check_UART_Data(mstp_port);
MSTP_Receive_Frame_FSM((volatile struct mstp_port_struct_t *) MSTP_Receive_Frame_FSM(
pArg); (volatile struct mstp_port_struct_t *)pArg);
received_frame = mstp_port->ReceivedValidFrame || received_frame = mstp_port->ReceivedValidFrame ||
mstp_port->ReceivedInvalidFrame; mstp_port->ReceivedInvalidFrame;
if (received_frame) { if (received_frame) {
@@ -250,8 +242,7 @@ void *dlmstp_receive_fsm_task(
return NULL; return NULL;
} }
void *dlmstp_master_fsm_task( void *dlmstp_master_fsm_task(void *pArg)
void *pArg)
{ {
uint32_t silence = 0; uint32_t silence = 0;
bool run_master = false; bool run_master = false;
@@ -309,9 +300,7 @@ void *dlmstp_master_fsm_task(
return NULL; return NULL;
} }
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
BACNET_ADDRESS * src,
uint8_t mstp_address)
{ {
int i = 0; int i = 0;
@@ -335,8 +324,7 @@ void dlmstp_fill_bacnet_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 MSTP_Put_Receive( uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData; SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
@@ -352,8 +340,8 @@ uint16_t MSTP_Put_Receive(
pdu_len = sizeof(poSharedData->Receive_Packet.pdu); pdu_len = sizeof(poSharedData->Receive_Packet.pdu);
memmove((void *)&poSharedData->Receive_Packet.pdu[0], memmove((void *)&poSharedData->Receive_Packet.pdu[0],
(void *)&mstp_port->InputBuffer[0], pdu_len); (void *)&mstp_port->InputBuffer[0], pdu_len);
dlmstp_fill_bacnet_address(&poSharedData->Receive_Packet.address, dlmstp_fill_bacnet_address(
mstp_port->SourceAddress); &poSharedData->Receive_Packet.address, mstp_port->SourceAddress);
poSharedData->Receive_Packet.pdu_len = mstp_port->DataLength; poSharedData->Receive_Packet.pdu_len = mstp_port->DataLength;
poSharedData->Receive_Packet.ready = true; poSharedData->Receive_Packet.ready = true;
sem_post(&poSharedData->Receive_Packet_Flag); sem_post(&poSharedData->Receive_Packet_Flag);
@@ -365,8 +353,7 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */ /* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */ /* Return: amount of PDU data */
uint16_t MSTP_Get_Send( uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
uint8_t frame_type = 0; uint8_t frame_type = 0;
@@ -388,7 +375,8 @@ uint16_t MSTP_Get_Send(
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
} }
/* convert the PDU into the MSTP Frame */ /* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&poSharedData->PDU_Queue, NULL); (void)Ringbuf_Pop(&poSharedData->PDU_Queue, NULL);
@@ -396,8 +384,7 @@ uint16_t MSTP_Get_Send(
return pdu_len; return pdu_len;
} }
bool dlmstp_compare_data_expecting_reply( bool dlmstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint8_t * request_pdu,
uint16_t request_pdu_len, uint16_t request_pdu_len,
uint8_t src_address, uint8_t src_address,
uint8_t *reply_pdu, uint8_t *reply_pdu,
@@ -424,13 +411,13 @@ bool dlmstp_compare_data_expecting_reply(
/* decode the request data */ /* decode the request data */
request.address.mac[0] = src_address; request.address.mac[0] = src_address;
request.address.mac_len = 1; request.address.mac_len = 1;
offset = offset = npdu_decode(
npdu_decode(&request_pdu[0], NULL, &request.address, &request_pdu[0], NULL, &request.address, &request.npdu_data);
&request.npdu_data);
if (request.npdu_data.network_layer_message) { if (request.npdu_data.network_layer_message) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Request is Network message.\n"); "DLMSTP: DER Compare failed: "
"Request is Network message.\n");
#endif #endif
return false; return false;
} }
@@ -438,7 +425,8 @@ bool dlmstp_compare_data_expecting_reply(
if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) { if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Not Confirmed Request.\n"); "DLMSTP: DER Compare failed: "
"Not Confirmed Request.\n");
#endif #endif
return false; return false;
} }
@@ -452,12 +440,12 @@ bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */ /* decode the reply data */
reply.address.mac[0] = dest_address; reply.address.mac[0] = dest_address;
reply.address.mac_len = 1; reply.address.mac_len = 1;
offset = offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Reply is Network message.\n"); "DLMSTP: DER Compare failed: "
"Reply is Network message.\n");
#endif #endif
return false; return false;
} }
@@ -495,7 +483,8 @@ bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) { if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n"); "DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif #endif
return false; return false;
} }
@@ -503,19 +492,22 @@ bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) { if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n"); "DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif #endif
return false; return false;
} }
if (request.service_choice != reply.service_choice) { if (request.service_choice != reply.service_choice) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "Service choice mismatch.\n"); "DLMSTP: DER Compare failed: "
"Service choice mismatch.\n");
#endif #endif
return false; return false;
} }
} }
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) { if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "DLMSTP: DER Compare failed: "
@@ -537,7 +529,8 @@ bool dlmstp_compare_data_expecting_reply(
if (!bacnet_address_same(&request.address, &reply.address)) { if (!bacnet_address_same(&request.address, &reply.address)) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DLMSTP: DER Compare failed: " "BACnet Address mismatch.\n"); "DLMSTP: DER Compare failed: "
"BACnet Address mismatch.\n");
#endif #endif
return false; return false;
} }
@@ -547,8 +540,7 @@ bool dlmstp_compare_data_expecting_reply(
/* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */ /* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */
uint16_t MSTP_Get_Reply( uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */ uint16_t pdu_len = 0; /* return value */
bool matched = false; bool matched = false;
@@ -565,21 +557,18 @@ uint16_t MSTP_Get_Reply(
} }
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&poSharedData->PDU_Queue); pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&poSharedData->PDU_Queue);
/* is this the reply to the DER? */ /* is this the reply to the DER? */
matched = matched = dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
mstp_port->DataLength, mstp_port->SourceAddress, mstp_port->DataLength, mstp_port->SourceAddress,
(uint8_t *)&pkt->buffer[0], pkt->length, pkt->destination_mac); (uint8_t *)&pkt->buffer[0], pkt->length, pkt->destination_mac);
if (!matched) { if (!matched) {
/* Walk the rest of the ring buffer to see if we can find a match */ /* Walk the rest of the ring buffer to see if we can find a match */
while (!matched && while (!matched &&
(pkt = (struct mstp_pdu_packet *)Ringbuf_Peek_Next(&poSharedData->PDU_Queue, (uint8_t *)pkt)) != NULL) { (pkt = (struct mstp_pdu_packet *)Ringbuf_Peek_Next(
matched = &poSharedData->PDU_Queue, (uint8_t *)pkt)) != NULL) {
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0], matched = dlmstp_compare_data_expecting_reply(
mstp_port->DataLength, &mstp_port->InputBuffer[0], mstp_port->DataLength,
mstp_port->SourceAddress, mstp_port->SourceAddress, (uint8_t *)&pkt->buffer[0],
(uint8_t *) & pkt->buffer[0], pkt->length, pkt->destination_mac);
pkt->length,
pkt->destination_mac);
} }
if (!matched) { if (!matched) {
/* Still didn't find a match so just bail out */ /* Still didn't find a match so just bail out */
@@ -592,7 +581,8 @@ uint16_t MSTP_Get_Reply(
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY; frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
} }
/* convert the PDU into the MSTP Frame */ /* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */ pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac, mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length); mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
/* This will pop the element no matter where we found it */ /* This will pop the element no matter where we found it */
@@ -601,13 +591,10 @@ uint16_t MSTP_Get_Reply(
return pdu_len; return pdu_len;
} }
void dlmstp_set_mac_address( void dlmstp_set_mac_address(void *poPort, uint8_t mac_address)
void *poPort,
uint8_t mac_address)
{ {
/* SHARED_MSTP_DATA * poSharedData; */ /* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -633,12 +620,10 @@ void dlmstp_set_mac_address(
return; return;
} }
uint8_t dlmstp_mac_address( uint8_t dlmstp_mac_address(void *poPort)
void *poPort)
{ {
/* SHARED_MSTP_DATA * poSharedData; */ /* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return 0; return 0;
} }
@@ -659,13 +644,10 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */ /* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(void *poPort, uint8_t max_info_frames)
void *poPort,
uint8_t max_info_frames)
{ {
/* SHARED_MSTP_DATA * poSharedData; */ /* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -688,12 +670,10 @@ void dlmstp_set_max_info_frames(
return; return;
} }
uint8_t dlmstp_max_info_frames( uint8_t dlmstp_max_info_frames(void *poPort)
void *poPort)
{ {
/* SHARED_MSTP_DATA * poSharedData; */ /* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return 0; return 0;
} }
@@ -712,13 +692,10 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */ /* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
void dlmstp_set_max_master( void dlmstp_set_max_master(void *poPort, uint8_t max_master)
void *poPort,
uint8_t max_master)
{ {
/* SHARED_MSTP_DATA * poSharedData; */ /* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -743,12 +720,10 @@ void dlmstp_set_max_master(
return; return;
} }
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void *poPort)
void *poPort)
{ {
/* SHARED_MSTP_DATA * poSharedData; */ /* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return 0; return 0;
} }
@@ -763,13 +738,10 @@ uint8_t dlmstp_max_master(
} }
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */ /* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
void dlmstp_set_baud_rate( void dlmstp_set_baud_rate(void *poPort, uint32_t baud)
void *poPort,
uint32_t baud)
{ {
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -799,12 +771,10 @@ void dlmstp_set_baud_rate(
} }
} }
uint32_t dlmstp_baud_rate( uint32_t dlmstp_baud_rate(void *poPort)
void *poPort)
{ {
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return false; return false;
} }
@@ -828,14 +798,11 @@ uint32_t dlmstp_baud_rate(
} }
} }
void dlmstp_get_my_address( void dlmstp_get_my_address(void *poPort, BACNET_ADDRESS *my_address)
void *poPort,
BACNET_ADDRESS * my_address)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return; return;
} }
@@ -854,8 +821,7 @@ void dlmstp_get_my_address(
return; return;
} }
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
@@ -872,30 +838,26 @@ void dlmstp_get_broadcast_address(
return; return;
} }
bool dlmstp_init( bool dlmstp_init(void *poPort, char *ifname)
void *poPort,
char *ifname)
{ {
unsigned long hThread = 0; unsigned long hThread = 0;
int rv = 0; int rv = 0;
SHARED_MSTP_DATA *poSharedData; SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
(struct mstp_port_struct_t *) poPort;
if (!mstp_port) { if (!mstp_port) {
return false; return false;
} }
poSharedData = (SHARED_MSTP_DATA *) ((struct mstp_port_struct_t *) poSharedData =
mstp_port)->UserData; (SHARED_MSTP_DATA *)((struct mstp_port_struct_t *)mstp_port)->UserData;
if (!poSharedData) { if (!poSharedData) {
return false; return false;
} }
poSharedData->RS485_Port_Name = ifname; poSharedData->RS485_Port_Name = ifname;
/* initialize PDU queue */ /* initialize PDU queue */
Ringbuf_Init(&poSharedData->PDU_Queue, Ringbuf_Init(&poSharedData->PDU_Queue, (uint8_t *)&poSharedData->PDU_Buffer,
(uint8_t *) & poSharedData->PDU_Buffer, sizeof(struct mstp_pdu_packet), sizeof(struct mstp_pdu_packet), MSTP_PDU_PACKET_COUNT);
MSTP_PDU_PACKET_COUNT);
/* initialize packet queue */ /* initialize packet queue */
poSharedData->Receive_Packet.ready = false; poSharedData->Receive_Packet.ready = false;
poSharedData->Receive_Packet.pdu_len = 0; poSharedData->Receive_Packet.pdu_len = 0;
@@ -913,8 +875,7 @@ bool dlmstp_init(
Open device for reading and writing. Open device for reading and writing.
Blocking mode - more CPU effecient Blocking mode - more CPU effecient
*/ */
poSharedData->RS485_Handle = poSharedData->RS485_Handle = open(poSharedData->RS485_Port_Name,
open(poSharedData->RS485_Port_Name,
O_RDWR | O_NOCTTY | O_NONBLOCK /*| O_NDELAY */); O_RDWR | O_NOCTTY | O_NONBLOCK /*| O_NDELAY */);
if (poSharedData->RS485_Handle < 0) { if (poSharedData->RS485_Handle < 0) {
perror(poSharedData->RS485_Port_Name); perror(poSharedData->RS485_Port_Name);
@@ -966,8 +927,7 @@ bool dlmstp_init(
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "MS/TP MAC: %02X\n", mstp_port->This_Station); fprintf(stderr, "MS/TP MAC: %02X\n", mstp_port->This_Station);
fprintf(stderr, "MS/TP Max_Master: %02X\n", mstp_port->Nmax_master); fprintf(stderr, "MS/TP Max_Master: %02X\n", mstp_port->Nmax_master);
fprintf(stderr, "MS/TP Max_Info_Frames: %u\n", fprintf(stderr, "MS/TP Max_Info_Frames: %u\n", mstp_port->Nmax_info_frames);
mstp_port->Nmax_info_frames);
#endif #endif
rv = pthread_create(&hThread, NULL, dlmstp_master_fsm_task, mstp_port); rv = pthread_create(&hThread, NULL, dlmstp_master_fsm_task, mstp_port);
+32 -49
View File
@@ -40,11 +40,12 @@
#include "bacnet/datalink/ethernet.h" #include "bacnet/datalink/ethernet.h"
#include "bacnet/bacint.h" #include "bacnet/bacint.h"
/** @file linux/ethernet.c Provides Linux-specific functions for BACnet/Ethernet. */ /** @file linux/ethernet.c Provides Linux-specific functions for
* BACnet/Ethernet. */
/* commonly used comparison address for ethernet */ /* commonly used comparison address for ethernet */
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 0xFF };
/* commonly used empty address for ethernet quick compare */ /* commonly used empty address for ethernet quick compare */
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 }; uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
@@ -54,14 +55,12 @@ uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0 };
static int eth802_sockfd = -1; /* 802.2 file handle */ static int eth802_sockfd = -1; /* 802.2 file handle */
static struct sockaddr eth_addr = { 0 }; /* used for binding 802.2 */ static struct sockaddr eth_addr = { 0 }; /* used for binding 802.2 */
bool ethernet_valid( bool ethernet_valid(void)
void)
{ {
return (eth802_sockfd >= 0); return (eth802_sockfd >= 0);
} }
void ethernet_cleanup( void ethernet_cleanup(void)
void)
{ {
if (ethernet_valid()) if (ethernet_valid())
close(eth802_sockfd); close(eth802_sockfd);
@@ -92,9 +91,7 @@ int setNonblocking(
#endif #endif
/* opens an 802.2 socket to receive and send packets */ /* opens an 802.2 socket to receive and send packets */
static int ethernet_bind( static int ethernet_bind(struct sockaddr *eth_addr, char *interface_name)
struct sockaddr *eth_addr,
char *interface_name)
{ {
int sock_fd = -1; /* return value */ int sock_fd = -1; /* return value */
#if 0 #if 0
@@ -121,13 +118,14 @@ static int ethernet_bind(
/* Attempt to open the socket for 802.2 ethernet frames */ /* Attempt to open the socket for 802.2 ethernet frames */
if ((sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0) { if ((sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0) {
/* Error occured */ /* Error occured */
fprintf(stderr, "ethernet: Error opening socket: %s\n", fprintf(
strerror(errno)); stderr, "ethernet: Error opening socket: %s\n", strerror(errno));
fprintf(stderr, fprintf(stderr,
"You might need to add the following to modules.conf\n" "You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n" "(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n" "alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n" "Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n"); "# modprobe af_packet\n");
exit(-1); exit(-1);
} }
@@ -156,7 +154,8 @@ static int ethernet_bind(
"You might need to add the following to modules.conf\n" "You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n" "(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n" "alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n" "Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n"); "# modprobe af_packet\n");
/* Close the socket */ /* Close the socket */
close(sock_fd); close(sock_fd);
@@ -169,9 +168,7 @@ static int ethernet_bind(
} }
/* function to find the local ethernet MAC address */ /* function to find the local ethernet MAC address */
static int get_local_hwaddr( static int get_local_hwaddr(const char *ifname, unsigned char *mac)
const char *ifname,
unsigned char *mac)
{ {
struct ifreq ifr; struct ifreq ifr;
int fd; int fd;
@@ -191,8 +188,7 @@ static int get_local_hwaddr(
return rv; return rv;
} }
bool ethernet_init( bool ethernet_init(char *interface_name)
char *interface_name)
{ {
if (interface_name) { if (interface_name) {
get_local_hwaddr(interface_name, Ethernet_MAC_Address); get_local_hwaddr(interface_name, Ethernet_MAC_Address);
@@ -205,29 +201,24 @@ bool ethernet_init(
return ethernet_valid(); return ethernet_valid();
} }
int ethernet_send( int ethernet_send(uint8_t *mtu, int mtu_len)
uint8_t * mtu,
int mtu_len)
{ {
int bytes = 0; int bytes = 0;
/* Send the packet */ /* Send the packet */
bytes = bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
sendto(eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *) &eth_addr, (struct sockaddr *)&eth_addr, sizeof(struct sockaddr));
sizeof(struct sockaddr));
/* did it get sent? */ /* did it get sent? */
if (bytes < 0) if (bytes < 0)
fprintf(stderr, "ethernet: Error sending packet: %s\n", fprintf(
strerror(errno)); stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
return bytes; return bytes;
} }
/* function to send a packet out the 802.2 socket */ /* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu( int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -284,21 +275,19 @@ int ethernet_send_pdu(
encode_unsigned16(&mtu[12], 3 + pdu_len); encode_unsigned16(&mtu[12], 3 + pdu_len);
/* Send the packet */ /* Send the packet */
bytes = bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
sendto(eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *) &eth_addr, (struct sockaddr *)&eth_addr, sizeof(struct sockaddr));
sizeof(struct sockaddr));
/* did it get sent? */ /* did it get sent? */
if (bytes < 0) if (bytes < 0)
fprintf(stderr, "ethernet: Error sending packet: %s\n", fprintf(
strerror(errno)); stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
return bytes; return bytes;
} }
/* receives an 802.2 framed packet */ /* receives an 802.2 framed packet */
/* returns the number of octets in the PDU, or zero on failure */ /* returns the number of octets in the PDU, or zero on failure */
uint16_t ethernet_receive( uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout) unsigned timeout)
@@ -359,8 +348,8 @@ uint16_t ethernet_receive(
/* check destination address for when */ /* check destination address for when */
/* the Ethernet card is in promiscious mode */ /* the Ethernet card is in promiscious mode */
if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0) if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0) &&
&& (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) { (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) {
/*fprintf(stderr, "ethernet: This packet isn't for us\n"); */ /*fprintf(stderr, "ethernet: This packet isn't for us\n"); */
return 0; return 0;
} }
@@ -374,12 +363,10 @@ uint16_t ethernet_receive(
else else
pdu_len = 0; pdu_len = 0;
return pdu_len; return pdu_len;
} }
void ethernet_set_my_address( void ethernet_set_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; int i = 0;
@@ -390,8 +377,7 @@ void ethernet_set_my_address(
return; return;
} }
void ethernet_get_my_address( void ethernet_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; int i = 0;
@@ -409,8 +395,7 @@ void ethernet_get_my_address(
return; return;
} }
void ethernet_get_broadcast_address( void ethernet_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
@@ -429,9 +414,7 @@ void ethernet_get_broadcast_address(
return; return;
} }
void ethernet_debug_address( void ethernet_debug_address(const char *info, BACNET_ADDRESS *dest)
const char *info,
BACNET_ADDRESS * dest)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
+4 -7
View File
@@ -41,17 +41,15 @@ static struct timespec start;
/** @brief The timeGetTime function retrieves the system time, in milliseconds. /** @brief The timeGetTime function retrieves the system time, in milliseconds.
* The system time is the time elapsed since Windows was started. * The system time is the time elapsed since Windows was started.
*/ */
static unsigned long timeGetTime( static unsigned long timeGetTime(void)
void)
{ {
struct timespec now; struct timespec now;
unsigned long ticks; unsigned long ticks;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
ticks = ticks = (now.tv_sec - start.tv_sec) * 1000 +
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec - (now.tv_nsec - start.tv_nsec) / 1000000;
start.tv_nsec) / 1000000;
return ticks; return ticks;
} }
@@ -77,8 +75,7 @@ unsigned long mstimer_now(void)
/** /**
* @brief Initialization for timer * @brief Initialization for timer
*/ */
void mstimer_init( void mstimer_init(void)
void)
{ {
clock_gettime(CLOCK_MONOTONIC, &start); clock_gettime(CLOCK_MONOTONIC, &start);
} }
+21 -30
View File
@@ -50,7 +50,8 @@
#include "bacnet/datalink/mstptext.h" #include "bacnet/datalink/mstptext.h"
#include "bacnet/bacint.h" #include "bacnet/bacint.h"
/** @file linux/mstpsnap.c Example application testing BACnet MS/TP on Linux. */ /** @file linux/mstpsnap.c Example application testing BACnet MS/TP on Linux.
*/
#ifndef max #ifndef max
#define max(a, b) (((a)(b)) ? (a) : (b)) #define max(a, b) (((a)(b)) ? (a) : (b))
@@ -64,8 +65,7 @@ static uint8_t RxBuffer[MAX_MPDU];
static uint8_t TxBuffer[MAX_MPDU]; static uint8_t TxBuffer[MAX_MPDU];
static struct mstimer Silence_Timer; static struct mstimer Silence_Timer;
static uint32_t Timer_Silence( static uint32_t Timer_Silence(void *pArg)
void *pArg)
{ {
uint32_t delta_time = 0; uint32_t delta_time = 0;
@@ -77,15 +77,13 @@ static uint32_t Timer_Silence(
return delta_time; return delta_time;
} }
static void Timer_Silence_Reset( static void Timer_Silence_Reset(void *pArg)
void *pArg)
{ {
mstimer_set(&Silence_Timer, 0); mstimer_set(&Silence_Timer, 0);
} }
/* functions used by the MS/TP state machine to put or get data */ /* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive( uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
(void)mstp_port; (void)mstp_port;
@@ -95,8 +93,7 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */ /* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */ /* Return: amount of PDU data */
uint16_t MSTP_Get_Send( uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
(void)timeout; (void)timeout;
@@ -104,17 +101,14 @@ uint16_t MSTP_Get_Send(
} }
uint16_t MSTP_Get_Reply( uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
(void)timeout; (void)timeout;
return 0; return 0;
} }
static int network_init( static int network_init(const char *name, int protocol)
const char *name,
int protocol)
{ {
/* check to see if we are being run as root */ /* check to see if we are being run as root */
if (getuid() != 0) { if (getuid() != 0) {
@@ -155,8 +149,7 @@ static int network_init(
} }
static void snap_received_packet( static void snap_received_packet(
volatile struct mstp_port_struct_t *mstp_port, volatile struct mstp_port_struct_t *mstp_port, int sockfd)
int sockfd)
{ {
uint16_t mtu_len = 0; /* number of octets of packet saved in file */ uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */ unsigned i = 0; /* counter */
@@ -208,15 +201,12 @@ static void snap_received_packet(
(void)write(sockfd, &mtu[0], mtu_len); (void)write(sockfd, &mtu[0], mtu_len);
} }
static void cleanup(void)
static void cleanup(
void)
{ {
} }
#if (!defined(_WIN32)) #if (!defined(_WIN32))
static void sig_int( static void sig_int(int signo)
int signo)
{ {
(void)signo; (void)signo;
@@ -224,8 +214,7 @@ static void sig_int(
exit(0); exit(0);
} }
void signal_init( void signal_init(void)
void)
{ {
signal(SIGINT, sig_int); signal(SIGINT, sig_int);
signal(SIGHUP, sig_int); signal(SIGHUP, sig_int);
@@ -234,9 +223,7 @@ void signal_init(
#endif #endif
/* simple test to packetize the data and print it */ /* simple test to packetize the data and print it */
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
volatile struct mstp_port_struct_t *mstp_port; volatile struct mstp_port_struct_t *mstp_port;
long my_baud = 38400; long my_baud = 38400;
@@ -250,12 +237,16 @@ int main(
printf("mstsnap [serial] [baud] [network]\r\n" printf("mstsnap [serial] [baud] [network]\r\n"
"Captures MS/TP packets from a serial interface\r\n" "Captures MS/TP packets from a serial interface\r\n"
"and sends them to a network interface using SNAP \r\n" "and sends them to a network interface using SNAP \r\n"
"protocol packets (mimics Cimetrics U+4 packet).\r\n" "\r\n" "protocol packets (mimics Cimetrics U+4 packet).\r\n"
"Command line options:\r\n" "[serial] - serial interface.\r\n" "\r\n"
"Command line options:\r\n"
"[serial] - serial interface.\r\n"
" defaults to /dev/ttyUSB0.\r\n" " defaults to /dev/ttyUSB0.\r\n"
"[baud] - baud rate. 9600, 19200, 38400, 57600, 115200\r\n" "[baud] - baud rate. 9600, 19200, 38400, 57600, 115200\r\n"
" defaults to 38400.\r\n" "[network] - network interface.\r\n" " defaults to 38400.\r\n"
" defaults to eth0.\r\n" ""); "[network] - network interface.\r\n"
" defaults to eth0.\r\n"
"");
return 0; return 0;
} }
/* initialize our interface */ /* initialize our interface */
+33 -47
View File
@@ -111,8 +111,7 @@ static uint8_t Rx_Buffer[4096];
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*********************************************************************/ *********************************************************************/
void RS485_Set_Interface( void RS485_Set_Interface(char *ifname)
char *ifname)
{ {
/* note: expects a constant char, or char from the heap */ /* note: expects a constant char, or char from the heap */
if (ifname) { if (ifname) {
@@ -126,8 +125,7 @@ void RS485_Set_Interface(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*********************************************************************/ *********************************************************************/
const char *RS485_Interface( const char *RS485_Interface(void)
void)
{ {
return RS485_Port_Name; return RS485_Port_Name;
} }
@@ -138,8 +136,7 @@ const char *RS485_Interface(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(void)
void)
{ {
uint32_t baud = 0; uint32_t baud = 0;
@@ -220,8 +217,7 @@ uint32_t RS485_Get_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t RS485_Get_Port_Baud_Rate( uint32_t RS485_Get_Port_Baud_Rate(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t * mstp_port)
{ {
uint32_t baud = 0; uint32_t baud = 0;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData; SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
@@ -300,8 +296,7 @@ uint32_t RS485_Get_Port_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(uint32_t baud)
uint32_t baud)
{ {
bool valid = true; bool valid = true;
@@ -406,11 +401,12 @@ void RS485_Send_Frame(
time to change from sending to receiving state. */ time to change from sending to receiving state. */
usleep(turnaround_time / baud); usleep(turnaround_time / baud);
/* /*
On success, the number of bytes written are returned (zero indicates On success, the number of bytes written are returned (zero
nothing was written). On error, -1 is returned, and errno is set indicates nothing was written). On error, -1 is returned, and
appropriately. If count is zero and the file descriptor refers to a errno is set appropriately. If count is zero and the file
regular file, 0 will be returned without causing any other effect. For descriptor refers to a regular file, 0 will be returned without
a special file, the results are not portable. causing any other effect. For a special file, the results are not
portable.
*/ */
written = write(RS485_Handle, buffer, nbytes); written = write(RS485_Handle, buffer, nbytes);
greska = errno; greska = errno;
@@ -431,11 +427,12 @@ void RS485_Send_Frame(
time to change from sending to receiving state. */ time to change from sending to receiving state. */
usleep(turnaround_time / baud); usleep(turnaround_time / baud);
/* /*
On success, the number of bytes written are returned (zero indicates On success, the number of bytes written are returned (zero
nothing was written). On error, -1 is returned, and errno is set indicates nothing was written). On error, -1 is returned, and
appropriately. If count is zero and the file descriptor refers to a errno is set appropriately. If count is zero and the file
regular file, 0 will be returned without causing any other effect. For descriptor refers to a regular file, 0 will be returned without
a special file, the results are not portable. causing any other effect. For a special file, the results are not
portable.
*/ */
written = write(poSharedData->RS485_Handle, buffer, nbytes); written = write(poSharedData->RS485_Handle, buffer, nbytes);
greska = errno; greska = errno;
@@ -461,8 +458,7 @@ void RS485_Send_Frame(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Check_UART_Data( void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
fd_set input; fd_set input;
struct timeval waiter; struct timeval waiter;
@@ -526,8 +522,7 @@ void RS485_Check_UART_Data(
/* grab bytes and stuff them into the FIFO every time */ /* grab bytes and stuff them into the FIFO every time */
FD_ZERO(&input); FD_ZERO(&input);
FD_SET(poSharedData->RS485_Handle, &input); FD_SET(poSharedData->RS485_Handle, &input);
n = select(poSharedData->RS485_Handle + 1, &input, NULL, NULL, n = select(poSharedData->RS485_Handle + 1, &input, NULL, NULL, &waiter);
&waiter);
if (n < 0) { if (n < 0) {
return; return;
} }
@@ -538,8 +533,7 @@ void RS485_Check_UART_Data(
} }
} }
void RS485_Cleanup( void RS485_Cleanup(void)
void)
{ {
/* restore the old port settings */ /* restore the old port settings */
tcsetattr(RS485_Handle, TCSANOW, &RS485_oldtio); tcsetattr(RS485_Handle, TCSANOW, &RS485_oldtio);
@@ -547,9 +541,7 @@ void RS485_Cleanup(
close(RS485_Handle); close(RS485_Handle);
} }
void RS485_Initialize(void)
void RS485_Initialize(
void)
{ {
struct termios newtio; struct termios newtio;
struct serial_struct newserial; struct serial_struct newserial;
@@ -600,14 +592,12 @@ void RS485_Initialize(
if (RS485_SpecBaud) { if (RS485_SpecBaud) {
/* 76800, custom divisor must be set */ /* 76800, custom divisor must be set */
newserial.flags |= ASYNC_SPD_CUST; newserial.flags |= ASYNC_SPD_CUST;
newserial.custom_divisor = newserial.custom_divisor = round(((float)newserial.baud_base) / 76800);
round(((float) newserial.baud_base) / 76800);
/* we must check that we calculated some sane value; /* we must check that we calculated some sane value;
small baud bases yield bad custom divisor values */ small baud bases yield bad custom divisor values */
baud_error = baud_error = fabs(1 -
fabs(1 - ((float)newserial.baud_base) / ((float)newserial.custom_divisor) /
((float) newserial.baud_base) / 76800);
((float) newserial.custom_divisor) / 76800);
if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) { if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) {
/* bad divisor */ /* bad divisor */
fprintf(stderr, "bad custom divisor %d, base baud %d\n", fprintf(stderr, "bad custom divisor %d, base baud %d\n",
@@ -650,24 +640,22 @@ void RS485_Print_Ports(void)
while (n--) { while (n--) {
if (strcmp(namelist[n]->d_name, "..") && if (strcmp(namelist[n]->d_name, "..") &&
strcmp(namelist[n]->d_name, ".")) { strcmp(namelist[n]->d_name, ".")) {
snprintf(device_dir, sizeof(device_dir), snprintf(device_dir, sizeof(device_dir), "%s%s/device", sysdir,
"%s%s/device", namelist[n]->d_name);
sysdir, namelist[n]->d_name);
// Stat the devicedir and handle it if it is a symlink // Stat the devicedir and handle it if it is a symlink
if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) { if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) {
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
snprintf(device_dir, sizeof(device_dir), snprintf(device_dir, sizeof(device_dir),
"%s%s/device/driver", "%s%s/device/driver", sysdir, namelist[n]->d_name);
sysdir, namelist[n]->d_name);
if (readlink(device_dir, buffer, sizeof(buffer)) > 0) { if (readlink(device_dir, buffer, sizeof(buffer)) > 0) {
valid_port = false; valid_port = false;
driver_name = basename(buffer); driver_name = basename(buffer);
if (strcmp(driver_name, "serial8250") == 0) { if (strcmp(driver_name, "serial8250") == 0) {
// serial8250-devices must be probed // serial8250-devices must be probed
snprintf(device_dir, sizeof(device_dir), snprintf(device_dir, sizeof(device_dir), "/dev/%s",
"/dev/%s", namelist[n]->d_name); namelist[n]->d_name);
fd = open(device_dir, fd = open(
O_RDWR | O_NONBLOCK | O_NOCTTY); device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd >= 0) { if (fd >= 0) {
// Get serial_info // Get serial_info
if (ioctl(fd, TIOCGSERIAL, &serinfo) == 0) { if (ioctl(fd, TIOCGSERIAL, &serinfo) == 0) {
@@ -699,9 +687,7 @@ void RS485_Print_Ports(void)
#ifdef TEST_RS485 #ifdef TEST_RS485
#include <string.h> #include <string.h>
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
volatile struct mstp_port_struct_t mstp_port = { 0 }; volatile struct mstp_port_struct_t mstp_port = { 0 };
uint8_t token_buf[8] = { 0x55, 0xFF, 0x00, 0x7E, 0x07, 0x00, 0x00, 0xFD }; uint8_t token_buf[8] = { 0x55, 0xFF, 0x00, 0x7E, 0x07, 0x00, 0x00, 0xFD };
+22 -33
View File
@@ -54,7 +54,8 @@
#include "bacnet/datalink/mstp.h" #include "bacnet/datalink/mstp.h"
#include "bacnet/datalink/mstptext.h" #include "bacnet/datalink/mstptext.h"
/** @file linux/rx_fsm.c Example app testing MS/TP Rx State Machine on Linux. */ /** @file linux/rx_fsm.c Example app testing MS/TP Rx State Machine on Linux.
*/
#ifndef max #ifndef max
#define max(a, b) (((a)(b)) ? (a) : (b)) #define max(a, b) (((a)(b)) ? (a) : (b))
@@ -71,27 +72,27 @@ static volatile struct mstp_port_struct_t MSTP_Port;
static uint8_t RxBuffer[MAX_MPDU]; static uint8_t RxBuffer[MAX_MPDU];
static uint8_t TxBuffer[MAX_MPDU]; static uint8_t TxBuffer[MAX_MPDU];
static uint16_t SilenceTime; static uint16_t SilenceTime;
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;} #define INCREMENT_AND_LIMIT_UINT16(x) \
static uint16_t Timer_Silence( { \
void) if (x < 0xFFFF) \
x++; \
}
static uint16_t Timer_Silence(void)
{ {
return SilenceTime; return SilenceTime;
} }
static void Timer_Silence_Reset( static void Timer_Silence_Reset(void)
void)
{ {
SilenceTime = 0; SilenceTime = 0;
} }
static void dlmstp_millisecond_timer( static void dlmstp_millisecond_timer(void)
void)
{ {
INCREMENT_AND_LIMIT_UINT16(SilenceTime); INCREMENT_AND_LIMIT_UINT16(SilenceTime);
} }
void *milliseconds_task( void *milliseconds_task(void *pArg)
void *pArg)
{ {
struct timespec timeOut, remains; struct timespec timeOut, remains;
@@ -107,8 +108,7 @@ void *milliseconds_task(
} }
/* functions used by the MS/TP state machine to put or get data */ /* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive( uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t * mstp_port)
{ {
(void)mstp_port; (void)mstp_port;
@@ -118,8 +118,7 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */ /* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */ /* Return: amount of PDU data */
uint16_t MSTP_Get_Send( uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
(void)timeout; (void)timeout;
@@ -127,8 +126,7 @@ uint16_t MSTP_Get_Send(
} }
uint16_t MSTP_Get_Reply( uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port, volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
(void)timeout; (void)timeout;
@@ -136,8 +134,7 @@ uint16_t MSTP_Get_Reply(
} }
/* returns a delta timestamp */ /* returns a delta timestamp */
int timestamp_ms( int timestamp_ms(void)
void)
{ {
struct timeval tv; struct timeval tv;
int delta_ticks = 0; int delta_ticks = 0;
@@ -161,8 +158,7 @@ static const char *Capture_Filename = "mstp.cap";
static FILE *pFile = NULL; /* stream pointer */ static FILE *pFile = NULL; /* stream pointer */
/* write packet to file in libpcap format */ /* write packet to file in libpcap format */
static void write_global_header( static void write_global_header(void)
void)
{ {
uint32_t magic_number = 0xa1b2c3d4; /* magic number */ uint32_t magic_number = 0xa1b2c3d4; /* magic number */
uint16_t version_major = 2; /* major version number */ uint16_t version_major = 2; /* major version number */
@@ -188,8 +184,7 @@ static void write_global_header(
} }
} }
static void write_received_packet( static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
uint32_t ts_sec; /* timestamp seconds */ uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */ uint32_t ts_usec; /* timestamp microseconds */
@@ -233,8 +228,7 @@ static void write_received_packet(
} }
} }
static void cleanup( static void cleanup(void)
void)
{ {
if (pFile) { if (pFile) {
fflush(pFile); /* stream pointer */ fflush(pFile); /* stream pointer */
@@ -244,8 +238,7 @@ static void cleanup(
} }
#if LOCAL_PRINT #if LOCAL_PRINT
static void print_received_packet( static void print_received_packet(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
unsigned i = 0; unsigned i = 0;
int timestamp = 0; int timestamp = 0;
@@ -280,8 +273,7 @@ static void print_received_packet(
} }
#endif #endif
static void sig_int( static void sig_int(int signo)
int signo)
{ {
(void)signo; (void)signo;
@@ -289,8 +281,7 @@ static void sig_int(
exit(0); exit(0);
} }
void signal_init( void signal_init(void)
void)
{ {
signal(SIGINT, sig_int); signal(SIGINT, sig_int);
signal(SIGHUP, sig_int); signal(SIGHUP, sig_int);
@@ -298,9 +289,7 @@ void signal_init(
} }
/* simple test to packetize the data and print it */ /* simple test to packetize the data and print it */
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
volatile struct mstp_port_struct_t *mstp_port; volatile struct mstp_port_struct_t *mstp_port;
int rc = 0; int rc = 0;
+27 -53
View File
@@ -76,28 +76,24 @@ uint32_t bip_stats_drop(void)
return BIP_Stats.drop; return BIP_Stats.drop;
} }
void bip_set_addr( void bip_set_addr(uint32_t net_address)
uint32_t net_address)
{ /* in network byte order */ { /* in network byte order */
BIP_Address.s_addr = net_address; BIP_Address.s_addr = net_address;
} }
/* returns network byte order */ /* returns network byte order */
uint32_t bip_get_addr( uint32_t bip_get_addr(void)
void)
{ {
return BIP_Address.s_addr; return BIP_Address.s_addr;
} }
void bip_set_broadcast_addr( void bip_set_broadcast_addr(uint32_t net_address)
uint32_t net_address)
{ /* in network byte order */ { /* in network byte order */
BIP_Broadcast_Address.s_addr = net_address; BIP_Broadcast_Address.s_addr = net_address;
} }
/* returns network byte order */ /* returns network byte order */
uint32_t bip_get_broadcast_addr( uint32_t bip_get_broadcast_addr(void)
void)
{ {
return BIP_Broadcast_Address.s_addr; return BIP_Broadcast_Address.s_addr;
} }
@@ -106,8 +102,7 @@ uint32_t bip_get_broadcast_addr(
* @brief Set the BACnet IPv4 UDP port number * @brief Set the BACnet IPv4 UDP port number
* @param port - IPv4 UDP port number - in host byte order * @param port - IPv4 UDP port number - in host byte order
*/ */
void bip_set_port( void bip_set_port(uint16_t port)
uint16_t port)
{ {
if (BIP_Port != htons(port)) { if (BIP_Port != htons(port)) {
BIP_Port_Changed = true; BIP_Port_Changed = true;
@@ -121,15 +116,12 @@ bool bip_port_changed(void)
} }
/* returns host byte order */ /* returns host byte order */
uint16_t bip_get_port( uint16_t bip_get_port(void)
void)
{ {
return ntohs(BIP_Port); return ntohs(BIP_Port);
} }
static void bip_mac_to_addr( static void bip_mac_to_addr(struct ip_addr *address, uint8_t *mac)
struct ip_addr *address,
uint8_t * mac)
{ {
if (mac && address) { if (mac && address) {
address->addr = ((u32_t)((((uint32_t)mac[0]) << 24) & 0xff000000)); address->addr = ((u32_t)((((uint32_t)mac[0]) << 24) & 0xff000000));
@@ -139,9 +131,7 @@ static void bip_mac_to_addr(
} }
} }
static void bip_addr_to_mac( static void bip_addr_to_mac(uint8_t *mac, struct ip_addr *address)
uint8_t * mac,
struct ip_addr *address)
{ {
if (mac && address) { if (mac && address) {
mac[0] = (uint8_t)(address->addr >> 24); mac[0] = (uint8_t)(address->addr >> 24);
@@ -151,8 +141,7 @@ static void bip_addr_to_mac(
} }
} }
static int bip_decode_bip_address( static int bip_decode_bip_address(BACNET_ADDRESS *bac_addr,
BACNET_ADDRESS * bac_addr,
struct ip_addr *address, /* in network format */ struct ip_addr *address, /* in network format */
uint16_t *port) uint16_t *port)
{ /* in network format */ { /* in network format */
@@ -177,9 +166,7 @@ static int bip_decode_bip_address(
* @return true if the packet was sent * @return true if the packet was sent
*/ */
static bool bip_send_mpdu( static bool bip_send_mpdu(
struct ip_addr *dst_ip, struct ip_addr *dst_ip, uint16_t port, struct pbuf *pkt)
uint16_t port,
struct pbuf *pkt)
{ {
err_t status = ERR_OK; err_t status = ERR_OK;
@@ -203,8 +190,7 @@ static bool bip_send_mpdu(
* *
* @return number of bytes sent * @return number of bytes sent
*/ */
int bip_send_pdu( int bip_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -260,9 +246,7 @@ int bip_send_pdu(
* *
* @return number of bytes encoded * @return number of bytes encoded
*/ */
static bool bvlc_send_result( static bool bvlc_send_result(struct ip_addr *addr, uint16_t result_code)
struct ip_addr *addr,
uint16_t result_code)
{ {
struct pbuf *pkt = NULL; struct pbuf *pkt = NULL;
uint8_t mtu[6] = { 0 }; uint8_t mtu[6] = { 0 };
@@ -284,8 +268,7 @@ static bool bvlc_send_result(
return bip_send_mpdu(addr, BIP_Port, pkt); return bip_send_mpdu(addr, BIP_Port, pkt);
} }
void bip_server_callback( void bip_server_callback(void *arg,
void *arg,
struct udp_pcb *upcb, struct udp_pcb *upcb,
struct pbuf *pkt, struct pbuf *pkt,
struct ip_addr *addr, struct ip_addr *addr,
@@ -294,9 +277,7 @@ void bip_server_callback(
uint8_t function = 0; uint8_t function = 0;
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
uint16_t pdu_offset = 0; uint16_t pdu_offset = 0;
BACNET_ADDRESS src = { BACNET_ADDRESS src = { 0 }; /* address where message came from */
0
}; /* address where message came from */
struct ip_addr sin_addr; struct ip_addr sin_addr;
uint16_t sin_port = 0; uint16_t sin_port = 0;
uint8_t *pdu = (uint8_t *)pkt->payload; uint8_t *pdu = (uint8_t *)pkt->payload;
@@ -340,23 +321,20 @@ void bip_server_callback(
pdu_offset = 10; pdu_offset = 10;
} }
} else if (function == BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE) { } else if (function == BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE) {
bvlc_send_result(addr, bvlc_send_result(
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK); addr, BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK);
} else if (function == BVLC_READ_BROADCAST_DIST_TABLE) { } else if (function == BVLC_READ_BROADCAST_DIST_TABLE) {
bvlc_send_result(addr, bvlc_send_result(
BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK); addr, BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK);
} else if (function == BVLC_REGISTER_FOREIGN_DEVICE) { } else if (function == BVLC_REGISTER_FOREIGN_DEVICE) {
bvlc_send_result(addr, bvlc_send_result(addr, BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK);
BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK);
} else if (function == BVLC_READ_FOREIGN_DEVICE_TABLE) { } else if (function == BVLC_READ_FOREIGN_DEVICE_TABLE) {
bvlc_send_result(addr, bvlc_send_result(addr, BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK);
BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK);
} else if (function == BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY) { } else if (function == BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY) {
bvlc_send_result(addr, bvlc_send_result(
BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK); addr, BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK);
} else if (function == BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK) { } else if (function == BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK) {
bvlc_send_result(addr, bvlc_send_result(addr, BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK);
BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK);
} }
if (pdu_len) { if (pdu_len) {
BIP_STATS_INC(recv); BIP_STATS_INC(recv);
@@ -376,8 +354,7 @@ void bip_server_callback(
pbuf_free(pkt); pbuf_free(pkt);
} }
void bip_get_my_address( void bip_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; int i = 0;
@@ -396,8 +373,7 @@ void bip_get_my_address(
return; return;
} }
void bip_get_broadcast_address( void bip_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
@@ -433,16 +409,14 @@ void bip_get_broadcast_address(
* @return True if the socket is successfully opened for BACnet/IP, * @return True if the socket is successfully opened for BACnet/IP,
* else False if the socket functions fail. * else False if the socket functions fail.
*/ */
bool bip_init( bool bip_init(char *ifname)
char *ifname)
{ {
(void)ifname; (void)ifname;
/* Create a new UDP control block */ /* Create a new UDP control block */
Server_upcb = udp_new(); Server_upcb = udp_new();
if (Server_upcb == NULL) { if (Server_upcb == NULL) {
/* increase MEMP_NUM_UDP_PCB in lwipopts.h */ /* increase MEMP_NUM_UDP_PCB in lwipopts.h */
while (1) { while (1) { };
};
} }
/* Bind the upcb to the UDP_PORT port */ /* Bind the upcb to the UDP_PORT port */
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */ /* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
+13 -23
View File
@@ -44,8 +44,7 @@ static uint8_t Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
@@ -54,21 +53,18 @@ bool Analog_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
char *Analog_Input_Name( char *Analog_Input_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[16] = ""; /* okay for single thread */ static char text_string[16] = ""; /* okay for single thread */
@@ -80,8 +76,7 @@ char *Analog_Input_Name(
return NULL; return NULL;
} }
float Analog_Input_Present_Value( float Analog_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
@@ -91,9 +86,7 @@ float Analog_Input_Present_Value(
return value; return value;
} }
void Analog_Input_Present_Value_Set( void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
if (object_instance < MAX_ANALOG_INPUTS) { if (object_instance < MAX_ANALOG_INPUTS) {
Present_Value[object_instance] = value; Present_Value[object_instance] = value;
@@ -102,8 +95,7 @@ void Analog_Input_Present_Value_Set(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object has already exists */
int Analog_Input_Read_Property( int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -117,16 +109,15 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, &apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Analog_Input_Name(rpdata->object_instance)); &char_string, Analog_Input_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -135,9 +126,8 @@ int Analog_Input_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
+18 -23
View File
@@ -43,20 +43,17 @@
/* me */ /* me */
#include "bacnet/apdu.h" #include "bacnet/apdu.h"
uint16_t apdu_timeout( uint16_t apdu_timeout(void)
void)
{ {
return 3000; return 3000;
} }
uint8_t apdu_retries( uint8_t apdu_retries(void)
void)
{ {
return 3; return 3;
} }
bool apdu_service_supported( bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
BACNET_SERVICES_SUPPORTED service_supported)
{ {
bool status = false; bool status = false;
@@ -75,8 +72,7 @@ bool apdu_service_supported(
return status; return status;
} }
uint16_t apdu_decode_confirmed_service_request( uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
uint8_t * apdu, /* APDU data */
uint16_t apdu_len, uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA *service_data, BACNET_CONFIRMED_SERVICE_DATA *service_data,
uint8_t *service_choice, uint8_t *service_choice,
@@ -110,8 +106,7 @@ uint16_t apdu_decode_confirmed_service_request(
When the initiation of communications is disabled, When the initiation of communications is disabled,
all APDUs shall be processed and responses returned as all APDUs shall be processed and responses returned as
required... */ required... */
static bool apdu_confirmed_dcc_disabled( static bool apdu_confirmed_dcc_disabled(uint8_t service_choice)
uint8_t service_choice)
{ {
bool status = false; bool status = false;
@@ -136,8 +131,7 @@ static bool apdu_confirmed_dcc_disabled(
DISABLE_INITIATION, the responding BACnet-user shall DISABLE_INITIATION, the responding BACnet-user shall
discontinue the initiation of messages except for I-Am discontinue the initiation of messages except for I-Am
requests issued in accordance with the Who-Is service procedure.*/ requests issued in accordance with the Who-Is service procedure.*/
static bool apdu_unconfirmed_dcc_disabled( static bool apdu_unconfirmed_dcc_disabled(uint8_t service_choice)
uint8_t service_choice)
{ {
bool status = false; bool status = false;
@@ -159,8 +153,7 @@ static bool apdu_unconfirmed_dcc_disabled(
return status; return status;
} }
void apdu_handler( void apdu_handler(BACNET_ADDRESS *src,
BACNET_ADDRESS * src,
uint8_t *apdu, /* APDU data */ uint8_t *apdu, /* APDU data */
uint16_t apdu_len) uint16_t apdu_len)
{ {
@@ -174,21 +167,23 @@ void apdu_handler(
/* PDU Type */ /* PDU Type */
switch (apdu[0] & 0xF0) { switch (apdu[0] & 0xF0) {
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ len = apdu_decode_confirmed_service_request(
&apdu[0], /* APDU data */
apdu_len, &service_data, &service_choice, &service_request, apdu_len, &service_data, &service_choice, &service_request,
&service_request_len); &service_request_len);
if (apdu_confirmed_dcc_disabled(service_choice)) { if (apdu_confirmed_dcc_disabled(service_choice)) {
/* When network communications are completely disabled, /* When network communications are completely disabled,
only DeviceCommunicationControl and ReinitializeDevice APDUs only DeviceCommunicationControl and ReinitializeDevice
shall be processed and no messages shall be initiated. */ APDUs shall be processed and no messages shall be
initiated. */
break; break;
} }
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
handler_read_property(service_request, service_request_len, handler_read_property(service_request, service_request_len,
src, &service_data); src, &service_data);
} else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) { } else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
handler_write_property(service_request, handler_write_property(service_request, service_request_len,
service_request_len, src, &service_data); src, &service_data);
} else if (service_choice == } else if (service_choice ==
SERVICE_CONFIRMED_REINITIALIZE_DEVICE) { SERVICE_CONFIRMED_REINITIALIZE_DEVICE) {
handler_reinitialize_device(service_request, handler_reinitialize_device(service_request,
@@ -208,10 +203,10 @@ void apdu_handler(
service_request_len = apdu_len - 2; service_request_len = apdu_len - 2;
if (apdu_unconfirmed_dcc_disabled(service_choice)) { if (apdu_unconfirmed_dcc_disabled(service_choice)) {
/* When network communications are disabled, /* When network communications are disabled,
only DeviceCommunicationControl and ReinitializeDevice APDUs only DeviceCommunicationControl and ReinitializeDevice
shall be processed and no messages shall be initiated. APDUs shall be processed and no messages shall be
If communications have been initiation disabled, then initiated. If communications have been initiation
WhoIs may be processed. */ disabled, then WhoIs may be processed. */
break; break;
} }
if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) { if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) {
+19 -30
View File
@@ -54,8 +54,7 @@ static uint8_t Present_Value[MAX_ANALOG_VALUES];
/* we need to have our arrays initialized before answering any calls */ /* we need to have our arrays initialized before answering any calls */
static bool Analog_Value_Initialized = false; static bool Analog_Value_Initialized = false;
void Analog_Value_Init( void Analog_Value_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -74,8 +73,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
Analog_Value_Init(); Analog_Value_Init();
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
@@ -86,8 +84,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(void)
void)
{ {
Analog_Value_Init(); Analog_Value_Init();
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
@@ -96,8 +93,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
Analog_Value_Init(); Analog_Value_Init();
return index; return index;
@@ -106,8 +102,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_VALUES; unsigned index = MAX_ANALOG_VALUES;
@@ -118,8 +113,7 @@ unsigned Analog_Value_Instance_To_Index(
return index; return index;
} }
float Analog_Value_Present_Value( float Analog_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = ANALOG_RELINQUISH_DEFAULT; float value = ANALOG_RELINQUISH_DEFAULT;
unsigned index = 0; unsigned index = 0;
@@ -135,8 +129,7 @@ float Analog_Value_Present_Value(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
char *Analog_Value_Name( char *Analog_Value_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -149,8 +142,7 @@ char *Analog_Value_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Read_Property( int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -170,14 +162,13 @@ int Analog_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, &apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Analog_Value_Name(rpdata->object_instance)); &char_string, Analog_Value_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -287,8 +278,7 @@ int Analog_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -304,9 +294,8 @@ bool Analog_Value_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -332,16 +321,16 @@ bool Analog_Value_Write_Property(
(priority != 6 /* reserved */) && (priority != 6 /* reserved */) &&
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) { (value.type.Real >= 0.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(
Analog_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
Present_Value[object_index] = level; Present_Value[object_index] = level;
/* Note: you could set the physical output here if we /* Note: you could set the physical output here if we
are the highest priority. are the highest priority.
However, if Out of Service is TRUE, then don't set the However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
status = true; status = true;
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
+12 -21
View File
@@ -40,8 +40,7 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
static void Binary_Input_Initialize( static void Binary_Input_Initialize(void)
void)
{ {
static bool initialized = false; static bool initialized = false;
unsigned i; unsigned i;
@@ -55,8 +54,7 @@ static void Binary_Input_Initialize(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Input_Valid_Instance( bool Binary_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_INPUTS) if (object_instance < MAX_BINARY_INPUTS)
return true; return true;
@@ -65,15 +63,13 @@ bool Binary_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Input_Count( unsigned Binary_Input_Count(void)
void)
{ {
return MAX_BINARY_INPUTS; return MAX_BINARY_INPUTS;
} }
/* we simply have 0-n object instances.*/ /* we simply have 0-n object instances.*/
uint32_t Binary_Input_Index_To_Instance( uint32_t Binary_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -81,8 +77,7 @@ uint32_t Binary_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index( unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_INPUTS; unsigned index = MAX_BINARY_INPUTS;
@@ -92,8 +87,7 @@ unsigned Binary_Input_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Input_Present_Value( BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0; unsigned index = 0;
@@ -107,8 +101,7 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
return value; return value;
} }
char *Binary_Input_Name( char *Binary_Input_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[16] = ""; /* okay for single thread */ static char text_string[16] = ""; /* okay for single thread */
@@ -122,8 +115,7 @@ char *Binary_Input_Name(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */ /* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property( int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -140,15 +132,14 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT, &apdu[0], OBJECT_BINARY_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
/* note: object name must be unique in our device */ /* note: object name must be unique in our device */
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Binary_Input_Name(rpdata->object_instance)); &char_string, Binary_Input_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
+18 -31
View File
@@ -40,8 +40,7 @@
static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES]; static BACNET_BINARY_PV Present_Value[MAX_BINARY_VALUES];
static void Binary_Value_Initialize( static void Binary_Value_Initialize(void)
void)
{ {
static bool initialized = false; static bool initialized = false;
unsigned i; unsigned i;
@@ -55,8 +54,7 @@ static void Binary_Value_Initialize(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
bool Binary_Value_Valid_Instance( bool Binary_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_VALUES) if (object_instance < MAX_BINARY_VALUES)
return true; return true;
@@ -65,22 +63,19 @@ bool Binary_Value_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Value_Count( unsigned Binary_Value_Count(void)
void)
{ {
return MAX_BINARY_VALUES; return MAX_BINARY_VALUES;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Binary_Value_Index_To_Instance( uint32_t Binary_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Binary_Value_Instance_To_Index( unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_VALUES; unsigned index = MAX_BINARY_VALUES;
@@ -90,8 +85,7 @@ unsigned Binary_Value_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Value_Present_Value( BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
@@ -104,8 +98,7 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
char *Binary_Value_Name( char *Binary_Value_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[16] = ""; /* okay for single thread */ static char text_string[16] = ""; /* okay for single thread */
@@ -118,8 +111,7 @@ char *Binary_Value_Name(
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Binary_Value_Read_Property( int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -140,16 +132,15 @@ int Binary_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, &apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Binary_Value_Name(rpdata->object_instance)); &char_string, Binary_Value_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -158,8 +149,7 @@ int Binary_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE); encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
present_value = present_value = Binary_Value_Present_Value(rpdata->object_instance);
Binary_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value); apdu_len = encode_application_enumerated(&apdu[0], present_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -200,8 +190,7 @@ int Binary_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Value_Write_Property( bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -216,9 +205,8 @@ bool Binary_Value_Write_Property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -245,9 +233,8 @@ bool Binary_Value_Write_Property(
(value.type.Enumerated >= MIN_BINARY_PV) && (value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) { (value.type.Enumerated <= MAX_BINARY_PV)) {
level = value.type.Enumerated; level = value.type.Enumerated;
object_index = object_index = Binary_Value_Instance_To_Index(
Binary_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
/* NOTE: this Binary value has no priority array */ /* NOTE: this Binary value has no priority array */
Present_Value[object_index] = level; Present_Value[object_index] = level;
+52 -83
View File
@@ -54,8 +54,7 @@ static uint8_t Database_Revision;
BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE; BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_IDLE;
static char Reinit_Password[16] = "filister"; static char Reinit_Password[16] = "filister";
bool Device_Reinitialize( bool Device_Reinitialize(BACNET_REINITIALIZE_DEVICE_DATA *rd_data)
BACNET_REINITIALIZE_DEVICE_DATA * rd_data)
{ {
bool status = false; bool status = false;
@@ -98,14 +97,12 @@ bool Device_Reinitialize(
return status; return status;
} }
BACNET_REINITIALIZED_STATE Device_Reinitialized_State( BACNET_REINITIALIZED_STATE Device_Reinitialized_State(void)
void)
{ {
return Reinitialize_State; return Reinitialize_State;
} }
void Device_Init( void Device_Init(object_functions_t *object_table)
object_functions_t * object_table)
{ {
(void)object_table; (void)object_table;
Reinitialize_State = BACNET_REINIT_IDLE; Reinitialize_State = BACNET_REINIT_IDLE;
@@ -118,14 +115,12 @@ void Device_Init(
} }
/* methods to manipulate the data */ /* methods to manipulate the data */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(void)
void)
{ {
return Object_Instance_Number; return Object_Instance_Number;
} }
bool Device_Set_Object_Instance_Number( bool Device_Set_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
@@ -144,62 +139,52 @@ bool Device_Set_Object_Instance_Number(
return status; return status;
} }
bool Device_Valid_Object_Instance_Number( bool Device_Valid_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
/* BACnet allows for a wildcard instance number */ /* BACnet allows for a wildcard instance number */
return (Object_Instance_Number == object_id); return (Object_Instance_Number == object_id);
} }
BACNET_DEVICE_STATUS Device_System_Status( BACNET_DEVICE_STATUS Device_System_Status(void)
void)
{ {
return System_Status; return System_Status;
} }
int Device_Set_System_Status( int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
BACNET_DEVICE_STATUS status,
bool local)
{ {
if (status < MAX_DEVICE_STATUS) { if (status < MAX_DEVICE_STATUS) {
System_Status = status; System_Status = status;
} }
} }
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(void)
void)
{ {
return BACNET_VENDOR_ID; return BACNET_VENDOR_ID;
} }
uint8_t Device_Protocol_Version( uint8_t Device_Protocol_Version(void)
void)
{ {
return BACNET_PROTOCOL_VERSION; return BACNET_PROTOCOL_VERSION;
} }
uint8_t Device_Protocol_Revision( uint8_t Device_Protocol_Revision(void)
void)
{ {
return BACNET_PROTOCOL_REVISION; return BACNET_PROTOCOL_REVISION;
} }
BACNET_SEGMENTATION Device_Segmentation_Supported( BACNET_SEGMENTATION Device_Segmentation_Supported(void)
void)
{ {
return SEGMENTATION_NONE; return SEGMENTATION_NONE;
} }
uint32_t Device_Database_Revision( uint32_t Device_Database_Revision(void)
void)
{ {
return Database_Revision; return Database_Revision;
} }
/* Since many network clients depend on the object list */ /* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */ /* for discovery, it must be consistent! */
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(void)
void)
{ {
unsigned count = 1; /* at least 1 for device object */ unsigned count = 1; /* at least 1 for device object */
@@ -215,9 +200,7 @@ unsigned Device_Object_List_Count(
/* Since many network clients depend on the object list */ /* Since many network clients depend on the object list */
/* for discovery, it must be consistent! */ /* for discovery, it must be consistent! */
bool Device_Object_List_Identifier( bool Device_Object_List_Identifier(
uint32_t array_index, uint32_t array_index, BACNET_OBJECT_TYPE *object_type, uint32_t *instance)
BACNET_OBJECT_TYPE *object_type,
uint32_t * instance)
{ {
bool status = false; bool status = false;
uint32_t object_index = 0; uint32_t object_index = 0;
@@ -287,8 +270,7 @@ bool Device_Object_List_Identifier(
} }
/* returns true if successful */ /* returns true if successful */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
static char string_buffer[28]; static char string_buffer[28];
static BACNET_CHARACTER_STRING char_string; static BACNET_CHARACTER_STRING char_string;
@@ -313,9 +295,8 @@ int Device_Read_Property_Local(
/* FIXME: change the hardcoded names to suit your application */ /* FIXME: change the hardcoded names to suit your application */
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_DEVICE, &apdu[0], OBJECT_DEVICE, 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");
@@ -334,8 +315,7 @@ int Device_Read_Property_Local(
break; break;
case PROP_SYSTEM_STATUS: case PROP_SYSTEM_STATUS:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], Device_System_Status());
Device_System_Status());
break; break;
case PROP_VENDOR_NAME: case PROP_VENDOR_NAME:
(void)strcpypgm2ram(&string_buffer[0], BACNET_VENDOR_NAME); (void)strcpypgm2ram(&string_buffer[0], BACNET_VENDOR_NAME);
@@ -344,9 +324,8 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_VENDOR_IDENTIFIER: case PROP_VENDOR_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Vendor_Identifier());
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");
@@ -373,22 +352,20 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_PROTOCOL_VERSION: case PROP_PROTOCOL_VERSION:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Protocol_Version());
Device_Protocol_Version());
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Protocol_Revision());
Device_Protocol_Revision());
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */ /* Note: list of services that are executed, not initiated. */
bitstring_init(&bit_string); bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */ /* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t) i, bitstring_set_bit(
apdu_service_supported(i)); &bit_string, (uint8_t)i, apdu_service_supported(i));
} }
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
@@ -419,11 +396,10 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */ /* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
if (Device_Object_List_Identifier(i, &object_type, if (Device_Object_List_Identifier(
&instance)) { i, &object_type, &instance)) {
len = len = encode_application_object_id(
encode_application_object_id(&apdu[apdu_len], &apdu[apdu_len], object_type, instance);
object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
@@ -442,11 +418,10 @@ int Device_Read_Property_Local(
} }
} }
} else { } else {
if (Device_Object_List_Identifier(rpdata->array_index, if (Device_Object_List_Identifier(
&object_type, &instance)) rpdata->array_index, &object_type, &instance))
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], object_type, &apdu[0], object_type, instance);
instance);
else { else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -458,9 +433,8 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break; break;
case PROP_SEGMENTATION_SUPPORTED: case PROP_SEGMENTATION_SUPPORTED:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Device_Segmentation_Supported());
Device_Segmentation_Supported());
break; break;
case PROP_APDU_TIMEOUT: case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout()); apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
@@ -472,14 +446,12 @@ int Device_Read_Property_Local(
/* 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 = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Device_Database_Revision());
Device_Database_Revision());
break; break;
case PROP_MAX_INFO_FRAMES: case PROP_MAX_INFO_FRAMES:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
dlmstp_max_info_frames());
break; break;
case PROP_MAX_MASTER: case PROP_MAX_MASTER:
apdu_len = apdu_len =
@@ -531,8 +503,7 @@ int Device_Read_Property_Local(
return apdu_len; return apdu_len;
} }
int Device_Read_Property( int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = BACNET_STATUS_ERROR; int apdu_len = BACNET_STATUS_ERROR;
@@ -572,8 +543,7 @@ int Device_Read_Property(
return apdu_len; return apdu_len;
} }
bool Device_Write_Property_Local( bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -585,9 +555,8 @@ bool Device_Write_Property_Local(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(
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? */
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -606,8 +575,8 @@ bool Device_Write_Property_Local(
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(value.type. (Device_Set_Object_Instance_Number(
Object_Id.instance))) { value.type.Object_Id.instance))) {
/* we could send an I-Am broadcast to let the world know */ /* we could send an I-Am broadcast to let the world know */
status = true; status = true;
} else { } else {
@@ -660,10 +629,11 @@ bool Device_Write_Property_Local(
if (len <= 20) { if (len <= 20) {
/* FIXME: set the name */ /* FIXME: set the name */
/* Display_Set_Name( /* Display_Set_Name(
characterstring_value(&value.type.Character_String)); */ characterstring_value(&value.type.Character_String));
/* FIXME: All the object names in a device must be unique. */
Disallow setting the Device Object Name to any objects in /* FIXME: All the object names in a device must be
the device. */ unique. Disallow setting the Device Object Name to
any objects in the device. */
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = wp_data->error_code =
@@ -729,8 +699,7 @@ bool Device_Write_Property_Local(
return status; return status;
} }
bool Device_Write_Property( bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* Ever the pessamist! */ bool status = false; /* Ever the pessamist! */
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
+24 -38
View File
@@ -48,16 +48,18 @@ static DLMSTP_PACKET Receive_Buffer;
volatile struct mstp_port_struct_t MSTP_Port; volatile struct mstp_port_struct_t MSTP_Port;
#pragma udata #pragma udata
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;} #define INCREMENT_AND_LIMIT_UINT16(x) \
{ \
if (x < 0xFFFF) \
x++; \
}
void dlmstp_millisecond_timer( void dlmstp_millisecond_timer(void)
void)
{ {
INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer); INCREMENT_AND_LIMIT_UINT16(MSTP_Port.SilenceTimer);
} }
void dlmstp_reinit( void dlmstp_reinit(void)
void)
{ {
RS485_Reinit(); RS485_Reinit();
dlmstp_set_my_address(DEFAULT_MAC_ADDRESS); dlmstp_set_my_address(DEFAULT_MAC_ADDRESS);
@@ -65,8 +67,7 @@ void dlmstp_reinit(
dlmstp_set_max_master(DEFAULT_MAX_MASTER); dlmstp_set_max_master(DEFAULT_MAX_MASTER);
} }
void dlmstp_init( void dlmstp_init(void)
void)
{ {
uint8_t data; uint8_t data;
@@ -79,15 +80,13 @@ void dlmstp_init(
MSTP_Init(&MSTP_Port); MSTP_Init(&MSTP_Port);
} }
void dlmstp_cleanup( void dlmstp_cleanup(void)
void)
{ {
/* nothing to do for static buffers */ /* nothing to do for static buffers */
} }
/* returns number of bytes sent on success, zero on failure */ /* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu( int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */ BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len) unsigned pdu_len)
@@ -115,8 +114,7 @@ int dlmstp_send_pdu(
if ((MAX_HEADER + pdu_len) > MAX_MPDU) { if ((MAX_HEADER + pdu_len) > MAX_MPDU) {
return -4; return -4;
} }
bytes_sent = bytes_sent = MSTP_Create_Frame((uint8_t *)&MSTP_Port.TxBuffer[0],
MSTP_Create_Frame((uint8_t *) & MSTP_Port.TxBuffer[0],
sizeof(MSTP_Port.TxBuffer), MSTP_Port.TxFrameType, sizeof(MSTP_Port.TxBuffer), MSTP_Port.TxFrameType,
MSTP_Port.TxDestination, MSTP_Port.This_Station, pdu, pdu_len); MSTP_Port.TxDestination, MSTP_Port.This_Station, pdu, pdu_len);
MSTP_Port.TxLength = bytes_sent; MSTP_Port.TxLength = bytes_sent;
@@ -127,8 +125,7 @@ int dlmstp_send_pdu(
return bytes_sent; return bytes_sent;
} }
void dlmstp_task( void dlmstp_task(void)
void)
{ {
bool bytes_remaining; bool bytes_remaining;
bool received_frame; bool received_frame;
@@ -139,8 +136,8 @@ void dlmstp_task(
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);
received_frame = MSTP_Port.ReceivedValidFrame || received_frame =
MSTP_Port.ReceivedInvalidFrame; MSTP_Port.ReceivedValidFrame || MSTP_Port.ReceivedInvalidFrame;
if (received_frame) if (received_frame)
break; break;
} while (bytes_remaining); } while (bytes_remaining);
@@ -167,9 +164,7 @@ void dlmstp_task(
return; return;
} }
void dlmstp_fill_bacnet_address( void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
BACNET_ADDRESS * src,
uint8_t mstp_address)
{ {
int i = 0; int i = 0;
@@ -193,8 +188,7 @@ void dlmstp_fill_bacnet_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 */
@@ -204,8 +198,7 @@ uint16_t dlmstp_put_receive(
Receive_Buffer.ready = true; Receive_Buffer.ready = true;
} }
void dlmstp_set_my_address( void dlmstp_set_my_address(uint8_t mac_address)
uint8_t mac_address)
{ {
/* Master Nodes can only have address 0-127 */ /* Master Nodes can only have address 0-127 */
if (mac_address <= 127) { if (mac_address <= 127) {
@@ -222,8 +215,7 @@ void dlmstp_set_my_address(
return; return;
} }
uint8_t dlmstp_my_address( uint8_t dlmstp_my_address(void)
void)
{ {
return MSTP_Port.This_Station; return MSTP_Port.This_Station;
} }
@@ -235,8 +227,7 @@ uint8_t dlmstp_my_address(
/* nodes. This may be used to allocate more or less of the available link */ /* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */ /* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */ /* node, its value shall be 1. */
void dlmstp_set_max_info_frames( void dlmstp_set_max_info_frames(uint8_t max_info_frames)
uint8_t max_info_frames)
{ {
if (max_info_frames >= 1) { if (max_info_frames >= 1) {
MSTP_Port.Nmax_info_frames = max_info_frames; MSTP_Port.Nmax_info_frames = max_info_frames;
@@ -250,8 +241,7 @@ void dlmstp_set_max_info_frames(
return; return;
} }
unsigned dlmstp_max_info_frames( unsigned dlmstp_max_info_frames(void)
void)
{ {
return MSTP_Port.Nmax_info_frames; return MSTP_Port.Nmax_info_frames;
} }
@@ -261,8 +251,7 @@ unsigned dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */ /* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */ /* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */ /* its value shall be 127. */
void dlmstp_set_max_master( void dlmstp_set_max_master(uint8_t max_master)
uint8_t max_master)
{ {
if (max_master <= 127) { if (max_master <= 127) {
if (MSTP_Port.This_Station <= max_master) { if (MSTP_Port.This_Station <= max_master) {
@@ -278,14 +267,12 @@ void dlmstp_set_max_master(
return; return;
} }
uint8_t dlmstp_max_master( uint8_t dlmstp_max_master(void)
void)
{ {
return MSTP_Port.Nmax_master; return MSTP_Port.Nmax_master;
} }
void dlmstp_get_my_address( void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
int i = 0; /* counter */ int i = 0; /* counter */
@@ -300,8 +287,7 @@ void dlmstp_get_my_address(
return; return;
} }
void dlmstp_get_broadcast_address( void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ /* destination address */ { /* destination address */
int i = 0; /* counter */ int i = 0; /* counter */
+23 -39
View File
@@ -30,42 +30,32 @@
/* from main.c */ /* from main.c */
extern volatile uint8_t Milliseconds; extern volatile uint8_t Milliseconds;
void InterruptHandlerHigh( void InterruptHandlerHigh(void);
void); void InterruptHandlerLow(void);
void InterruptHandlerLow( void Interrupt_Timer2(void);
void); void Interrupt_Timer3(void);
void Interrupt_Timer2( void Interrupt_Timer4(void);
void); void Interrupt_USART_Rx(void);
void Interrupt_Timer3( void Interrupt_USART_Tx(void);
void); void Interrupt_CCP2(void);
void Interrupt_Timer4( void INT0_Interrupt(void);
void);
void Interrupt_USART_Rx(
void);
void Interrupt_USART_Tx(
void);
void Interrupt_CCP2(
void);
void INT0_Interrupt(
void);
#pragma code InterruptVectorHigh = 0x08 #pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh( void InterruptVectorHigh(void)
void)
{ {
/* jump to interrupt routine */ /* jump to interrupt routine */
_asm goto InterruptHandlerHigh _endasm} _asm goto InterruptHandlerHigh _endasm
}
#pragma code #pragma code
#pragma code InterruptVectorLow = 0x18 #pragma code InterruptVectorLow = 0x18
void InterruptVectorLow( void InterruptVectorLow(void)
void)
{ {
/* jump to interrupt routine */ /* jump to interrupt routine */
_asm goto InterruptHandlerLow _endasm} _asm goto InterruptHandlerLow _endasm
}
#pragma code #pragma code
#pragma interrupt InterruptHandlerHigh #pragma interrupt InterruptHandlerHigh
void InterruptHandlerHigh( void InterruptHandlerHigh(void)
void)
{ {
#if 0 #if 0
/* check for USART Rx int */ /* check for USART Rx int */
@@ -92,11 +82,10 @@ void InterruptHandlerHigh(
} }
} }
#pragma interruptlow InterruptHandlerLow save = PROD, section(".tmpdata"), TABLAT, TBLPTR, section \ #pragma interruptlow InterruptHandlerLow save = PROD, section(".tmpdata"), \
("MATH_DATA") TABLAT, TBLPTR, section("MATH_DATA")
void InterruptHandlerLow( void InterruptHandlerLow(void)
void)
{ {
/* check for timer2 int */ /* check for timer2 int */
if ((PIR1bits.TMR2IF) && (PIE1bits.TMR2IE)) { if ((PIR1bits.TMR2IF) && (PIE1bits.TMR2IE)) {
@@ -180,27 +169,22 @@ void InterruptHandlerLow(
*/ */
} }
void Interrupt_Timer2( void Interrupt_Timer2(void)
void)
{ {
} }
void Interrupt_Timer3( void Interrupt_Timer3(void)
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 Interrupt_Timer4(void)
void)
{ {
/* Milisecond is our system tick */ /* Milisecond is our system tick */
if (Milliseconds < 0xFF) if (Milliseconds < 0xFF)
++Milliseconds; ++Milliseconds;
} }
void Interrupt_CCP2( void Interrupt_CCP2(void)
void)
{ {
} }
+6 -12
View File
@@ -92,8 +92,7 @@
volatile uint8_t Milliseconds = 0; volatile uint8_t Milliseconds = 0;
volatile uint8_t Zero_Cross_Timeout = 0; volatile uint8_t Zero_Cross_Timeout = 0;
void Reinitialize( void Reinitialize(void)
void)
{ {
uint8_t i; uint8_t i;
char name = 0; char name = 0;
@@ -101,8 +100,7 @@ void Reinitialize(
_asm reset _endasm return; _asm reset _endasm return;
} }
void Global_Int( void Global_Int(enum INT_STATE state)
enum INT_STATE state)
{ {
static uint8_t intstate = 0; static uint8_t intstate = 0;
@@ -125,8 +123,7 @@ void Global_Int(
} }
} }
void Hardware_Initialize( void Hardware_Initialize(void)
void)
{ {
TRISA = 0x00; TRISA = 0x00;
TRISB = 0x00; TRISB = 0x00;
@@ -153,8 +150,7 @@ void Hardware_Initialize(
Global_Int(INT_ENABLED); Global_Int(INT_ENABLED);
} }
void Initialize_Variables( void Initialize_Variables(void)
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();
@@ -164,8 +160,7 @@ void Initialize_Variables(
Milliseconds = 0; Milliseconds = 0;
} }
void MainTasks( void MainTasks(void)
void)
{ {
static uint16_t millisecond_counter = 0; static uint16_t millisecond_counter = 0;
/* Handle our millisecond counters */ /* Handle our millisecond counters */
@@ -180,8 +175,7 @@ void MainTasks(
} }
} }
void main( void main(void)
void)
{ {
RCONbits.NOT_POR = 1; RCONbits.NOT_POR = 1;
RCONbits.NOT_RI = 1; RCONbits.NOT_RI = 1;
+133 -113
View File
@@ -150,16 +150,18 @@
#define Tusage_timeout 20 #define Tusage_timeout 20
/* we need to be able to increment without rolling over */ /* we need to be able to increment without rolling over */
#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} #define INCREMENT_AND_LIMIT_UINT8(x) \
{ \
if (x < 0xFF) \
x++; \
}
bool MSTP_Line_Active( bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
return (mstp_port->EventCount > Nmin_octets); return (mstp_port->EventCount > Nmin_octets);
} }
unsigned MSTP_Create_Frame( unsigned MSTP_Create_Frame(uint8_t *buffer, /* where frame is loaded */
uint8_t * buffer, /* where frame is loaded */
unsigned buffer_len, /* amount of space available */ unsigned buffer_len, /* amount of space available */
uint8_t frame_type, /* type of frame to send - see defines */ uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */ uint8_t destination, /* destination address */
@@ -235,21 +237,22 @@ void MSTP_Create_And_Send_Frame(
/* FIXME: be sure to reset SilenceTimer after each octet is sent! */ /* FIXME: be sure to reset SilenceTimer after each octet is sent! */
} }
void MSTP_Receive_Frame_FSM( void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
#if PRINT_ENABLED_RECEIVE_DATA #if PRINT_ENABLED_RECEIVE_DATA
static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE; static MSTP_RECEIVE_STATE receive_state = MSTP_RECEIVE_STATE_IDLE;
#endif #endif
#if PRINT_ENABLED_RECEIVE #if PRINT_ENABLED_RECEIVE
fprintf(stderr, fprintf(stderr,
"MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u Silence=%u\n", "MSTP Rx: State=%s Data=%02X hCRC=%02X Index=%u EC=%u DateLen=%u "
"Silence=%u\n",
mstptext_receive_state(mstp_port->receive_state), mstptext_receive_state(mstp_port->receive_state),
mstp_port->DataRegister, mstp_port->HeaderCRC, mstp_port->Index, mstp_port->DataRegister, mstp_port->HeaderCRC, mstp_port->Index,
mstp_port->EventCount, mstp_port->DataLength, mstp_port->SilenceTimer); mstp_port->EventCount, mstp_port->DataLength, mstp_port->SilenceTimer);
#endif #endif
switch (mstp_port->receive_state) { switch (mstp_port->receive_state) {
/* In the IDLE state, the node waits for the beginning of a frame. */ /* In the IDLE state, the node waits for the beginning of a frame.
*/
case MSTP_RECEIVE_STATE_IDLE: case MSTP_RECEIVE_STATE_IDLE:
/* EatAnError */ /* EatAnError */
if (mstp_port->ReceiveError == true) { if (mstp_port->ReceiveError == true) {
@@ -283,7 +286,8 @@ void MSTP_Receive_Frame_FSM(
} }
} }
break; break;
/* In the PREAMBLE state, the node waits for the second octet of the preamble. */ /* In the PREAMBLE state, the node waits for the second octet of the
* preamble. */
case MSTP_RECEIVE_STATE_PREAMBLE: case MSTP_RECEIVE_STATE_PREAMBLE:
/* Timeout */ /* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) { if (mstp_port->SilenceTimer > Tframe_abort) {
@@ -330,11 +334,13 @@ void MSTP_Receive_Frame_FSM(
} }
} }
break; break;
/* In the HEADER state, the node waits for the fixed message header. */ /* In the HEADER state, the node waits for the fixed message header.
*/
case MSTP_RECEIVE_STATE_HEADER: case MSTP_RECEIVE_STATE_HEADER:
/* Timeout */ /* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) { if (mstp_port->SilenceTimer > Tframe_abort) {
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
mstp_port->ReceivedInvalidFrame = true; mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */ /* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -344,7 +350,8 @@ void MSTP_Receive_Frame_FSM(
mstp_port->ReceiveError = false; mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
mstp_port->ReceivedInvalidFrame = true; mstp_port->ReceivedInvalidFrame = true;
/* wait for the start of a frame. */ /* wait for the start of a frame. */
mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE;
@@ -356,9 +363,8 @@ void MSTP_Receive_Frame_FSM(
if (mstp_port->Index == 0) { if (mstp_port->Index == 0) {
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC = mstp_port->HeaderCRC = CRC_Calc_Header(
CRC_Calc_Header(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->HeaderCRC);
mstp_port->FrameType = mstp_port->DataRegister; mstp_port->FrameType = mstp_port->DataRegister;
mstp_port->DataAvailable = false; mstp_port->DataAvailable = false;
mstp_port->Index = 1; mstp_port->Index = 1;
@@ -368,9 +374,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 1) { else if (mstp_port->Index == 1) {
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC = mstp_port->HeaderCRC = CRC_Calc_Header(
CRC_Calc_Header(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->HeaderCRC);
mstp_port->DestinationAddress = mstp_port->DataRegister; mstp_port->DestinationAddress = mstp_port->DataRegister;
mstp_port->DataAvailable = false; mstp_port->DataAvailable = false;
mstp_port->Index = 2; mstp_port->Index = 2;
@@ -380,9 +385,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 2) { else if (mstp_port->Index == 2) {
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC = mstp_port->HeaderCRC = CRC_Calc_Header(
CRC_Calc_Header(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->HeaderCRC);
mstp_port->SourceAddress = mstp_port->DataRegister; mstp_port->SourceAddress = mstp_port->DataRegister;
mstp_port->DataAvailable = false; mstp_port->DataAvailable = false;
mstp_port->Index = 3; mstp_port->Index = 3;
@@ -392,9 +396,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 3) { else if (mstp_port->Index == 3) {
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC = mstp_port->HeaderCRC = CRC_Calc_Header(
CRC_Calc_Header(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->HeaderCRC);
mstp_port->DataLength = mstp_port->DataRegister * 256; mstp_port->DataLength = mstp_port->DataRegister * 256;
mstp_port->DataAvailable = false; mstp_port->DataAvailable = false;
mstp_port->Index = 4; mstp_port->Index = 4;
@@ -404,9 +407,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 4) { else if (mstp_port->Index == 4) {
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC = mstp_port->HeaderCRC = CRC_Calc_Header(
CRC_Calc_Header(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->HeaderCRC);
mstp_port->DataLength += mstp_port->DataRegister; mstp_port->DataLength += mstp_port->DataRegister;
mstp_port->DataAvailable = false; mstp_port->DataAvailable = false;
mstp_port->Index = 5; mstp_port->Index = 5;
@@ -416,21 +418,21 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->Index == 5) { else if (mstp_port->Index == 5) {
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount); INCREMENT_AND_LIMIT_UINT8(mstp_port->EventCount);
mstp_port->HeaderCRC = mstp_port->HeaderCRC = CRC_Calc_Header(
CRC_Calc_Header(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->HeaderCRC);
mstp_port->HeaderCRC);
mstp_port->DataAvailable = false; mstp_port->DataAvailable = false;
/* don't wait for next state - do it here */ /* don't wait for next state - do it here */
if (mstp_port->HeaderCRC != 0x55) { if (mstp_port->HeaderCRC != 0x55) {
/* BadCRC */ /* BadCRC */
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the
* reception of a frame */
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;
} else { } else {
if ((mstp_port->DestinationAddress == if ((mstp_port->DestinationAddress ==
mstp_port->This_Station) mstp_port->This_Station) ||
|| (mstp_port->DestinationAddress == (mstp_port->DestinationAddress ==
MSTP_BROADCAST_ADDRESS)) { MSTP_BROADCAST_ADDRESS)) {
/* FrameTooLong */ /* FrameTooLong */
if (mstp_port->DataLength > MAX_MPDU) { if (mstp_port->DataLength > MAX_MPDU) {
@@ -443,7 +445,8 @@ void MSTP_Receive_Frame_FSM(
} }
/* 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_port->receive_state =
@@ -465,7 +468,6 @@ void MSTP_Receive_Frame_FSM(
} }
} }
} }
/* not per MS/TP standard, but it is a case not covered */ /* not per MS/TP standard, but it is a case not covered */
else { else {
@@ -480,11 +482,13 @@ void MSTP_Receive_Frame_FSM(
} }
} }
break; break;
/* In the DATA state, the node waits for the data portion of a frame. */ /* In the DATA state, the node waits for the data portion of a
* frame. */
case MSTP_RECEIVE_STATE_DATA: case MSTP_RECEIVE_STATE_DATA:
/* Timeout */ /* Timeout */
if (mstp_port->SilenceTimer > Tframe_abort) { if (mstp_port->SilenceTimer > Tframe_abort) {
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
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;
@@ -493,7 +497,8 @@ void MSTP_Receive_Frame_FSM(
else if (mstp_port->ReceiveError == true) { else if (mstp_port->ReceiveError == true) {
mstp_port->ReceiveError = false; mstp_port->ReceiveError = false;
mstp_port->SilenceTimer = 0; mstp_port->SilenceTimer = 0;
/* indicate that an error has occurred during the reception of a frame */ /* indicate that an error has occurred during the reception of a
* frame */
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;
@@ -503,9 +508,8 @@ void MSTP_Receive_Frame_FSM(
#endif #endif
/* DataOctet */ /* DataOctet */
if (mstp_port->Index < mstp_port->DataLength) { if (mstp_port->Index < mstp_port->DataLength) {
mstp_port->DataCRC = mstp_port->DataCRC = CRC_Calc_Data(
CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->DataCRC);
mstp_port->DataCRC);
mstp_port->InputBuffer[mstp_port->Index] = mstp_port->InputBuffer[mstp_port->Index] =
mstp_port->DataRegister; mstp_port->DataRegister;
mstp_port->Index++; mstp_port->Index++;
@@ -513,17 +517,15 @@ void MSTP_Receive_Frame_FSM(
} }
/* CRC1 */ /* CRC1 */
else if (mstp_port->Index == mstp_port->DataLength) { else if (mstp_port->Index == mstp_port->DataLength) {
mstp_port->DataCRC = mstp_port->DataCRC = CRC_Calc_Data(
CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->DataCRC);
mstp_port->DataCRC);
mstp_port->Index++; mstp_port->Index++;
mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA; mstp_port->receive_state = MSTP_RECEIVE_STATE_DATA;
} }
/* CRC2 */ /* CRC2 */
else if (mstp_port->Index == (mstp_port->DataLength + 1)) { else if (mstp_port->Index == (mstp_port->DataLength + 1)) {
mstp_port->DataCRC = mstp_port->DataCRC = CRC_Calc_Data(
CRC_Calc_Data(mstp_port->DataRegister, mstp_port->DataRegister, mstp_port->DataCRC);
mstp_port->DataCRC);
/* STATE DATA CRC - no need for new state */ /* STATE DATA CRC - no need for new state */
/* indicate the complete reception of a valid frame */ /* indicate the complete reception of a valid frame */
if (mstp_port->DataCRC == 0xF0B8) if (mstp_port->DataCRC == 0xF0B8)
@@ -553,8 +555,7 @@ void MSTP_Receive_Frame_FSM(
return; return;
} }
static bool mstp_compare_data_expecting_reply( static bool mstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint8_t * request_pdu,
uint16_t request_pdu_len, uint16_t request_pdu_len,
uint8_t src_address, uint8_t src_address,
uint8_t *reply_pdu, uint8_t *reply_pdu,
@@ -578,9 +579,8 @@ static bool mstp_compare_data_expecting_reply(
/* decode the request data */ /* decode the request data */
request.address.mac[0] = src_address; request.address.mac[0] = src_address;
request.address.mac_len = 1; request.address.mac_len = 1;
offset = offset = npdu_decode(
npdu_decode(&request_pdu[0], NULL, &request.address, &request_pdu[0], NULL, &request.address, &request.npdu_data);
&request.npdu_data);
if (request.npdu_data.network_layer_message) { if (request.npdu_data.network_layer_message) {
return false; return false;
} }
@@ -597,8 +597,7 @@ static bool mstp_compare_data_expecting_reply(
/* decode the reply data */ /* decode the reply data */
reply.address.mac[0] = dest_address; reply.address.mac[0] = dest_address;
reply.address.mac_len = 1; reply.address.mac_len = 1;
offset = offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
return false; return false;
} }
@@ -639,7 +638,8 @@ static bool mstp_compare_data_expecting_reply(
return false; return false;
} }
} }
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) { if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false; return false;
} }
#if 0 #if 0
@@ -657,8 +657,7 @@ static bool mstp_compare_data_expecting_reply(
} }
/* returns true if we need to transition immediately */ /* returns true if we need to transition immediately */
bool MSTP_Master_Node_FSM( bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t * mstp_port)
{ {
int mtu_len = 0; int mtu_len = 0;
int frame_type = 0; int frame_type = 0;
@@ -684,11 +683,12 @@ bool MSTP_Master_Node_FSM(
if (mstp_port->master_state != master_state) { if (mstp_port->master_state != master_state) {
master_state = mstp_port->master_state; master_state = mstp_port->master_state;
fprintf(stderr, fprintf(stderr,
"MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u %s\n", "MSTP: TS=%02X[%02X] NS=%02X[%02X] PS=%02X[%02X] EC=%u TC=%u ST=%u "
mstp_port->This_Station, next_this_station, "%s\n",
mstp_port->Next_Station, next_next_station, mstp_port->This_Station, next_this_station, mstp_port->Next_Station,
mstp_port->Poll_Station, next_poll_station, mstp_port->EventCount, next_next_station, mstp_port->Poll_Station, next_poll_station,
mstp_port->TokenCount, mstp_port->SilenceTimer, mstp_port->EventCount, mstp_port->TokenCount,
mstp_port->SilenceTimer,
mstptext_master_state(mstp_port->master_state)); mstptext_master_state(mstp_port->master_state));
} }
#endif #endif
@@ -727,16 +727,17 @@ bool MSTP_Master_Node_FSM(
} else if (mstp_port->ReceivedValidFrame == true) { } else if (mstp_port->ReceivedValidFrame == true) {
#if PRINT_ENABLED_MASTER #if PRINT_ENABLED_MASTER
fprintf(stderr, fprintf(stderr,
"MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u FC=%u ST=%u Type=%s\n", "MSTP: ReceivedValidFrame Src=%02X Dest=%02X DataLen=%u "
"FC=%u ST=%u Type=%s\n",
mstp_port->SourceAddress, mstp_port->DestinationAddress, mstp_port->SourceAddress, mstp_port->DestinationAddress,
mstp_port->DataLength, mstp_port->FrameCount, mstp_port->DataLength, mstp_port->FrameCount,
mstp_port->SilenceTimer, mstp_port->SilenceTimer,
mstptext_frame_type(mstp_port->FrameType)); mstptext_frame_type(mstp_port->FrameType));
#endif #endif
/* destined for me! */ /* destined for me! */
if ((mstp_port->DestinationAddress == mstp_port->This_Station) if ((mstp_port->DestinationAddress ==
|| (mstp_port->DestinationAddress == mstp_port->This_Station) ||
MSTP_BROADCAST_ADDRESS)) { (mstp_port->DestinationAddress == MSTP_BROADCAST_ADDRESS)) {
switch (mstp_port->FrameType) { switch (mstp_port->FrameType) {
/* ReceivedToken */ /* ReceivedToken */
case FRAME_TYPE_TOKEN: case FRAME_TYPE_TOKEN:
@@ -763,14 +764,16 @@ bool MSTP_Master_Node_FSM(
} }
break; break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* 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],
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],
mstp_port->DataLength); mstp_port->DataLength);
@@ -808,8 +811,8 @@ bool MSTP_Master_Node_FSM(
transition_now = true; transition_now = true;
} else { } else {
uint8_t destination = mstp_port->TxBuffer[3]; uint8_t destination = mstp_port->TxBuffer[3];
RS485_Send_Frame(mstp_port, RS485_Send_Frame(mstp_port, (uint8_t *)&mstp_port->TxBuffer[0],
(uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength); mstp_port->TxLength);
mstp_port->FrameCount++; mstp_port->FrameCount++;
switch (mstp_port->TxFrameType) { switch (mstp_port->TxFrameType) {
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
@@ -845,8 +848,10 @@ bool MSTP_Master_Node_FSM(
mstp_port->FrameCount = mstp_port->Nmax_info_frames; mstp_port->FrameCount = mstp_port->Nmax_info_frames;
mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
/* Any retry of the data frame shall await the next entry */ /* Any retry of the data frame shall await the next entry */
/* to the USE_TOKEN state. (Because of the length of the timeout, */ /* to the USE_TOKEN state. (Because of the length of the
/* this transition will cause the token to be passed regardless */ * timeout, */
/* this transition will cause the token to be passed regardless
*/
/* of the initial value of FrameCount.) */ /* of the initial value of FrameCount.) */
transition_now = true; transition_now = true;
} else { } else {
@@ -854,8 +859,7 @@ bool MSTP_Master_Node_FSM(
/* InvalidFrame */ /* InvalidFrame */
/* error in frame reception */ /* error in frame reception */
mstp_port->ReceivedInvalidFrame = false; mstp_port->ReceivedInvalidFrame = false;
mstp_port->master_state = mstp_port->master_state = MSTP_MASTER_STATE_DONE_WITH_TOKEN;
MSTP_MASTER_STATE_DONE_WITH_TOKEN;
transition_now = true; transition_now = true;
} else if (mstp_port->ReceivedValidFrame == true) { } else if (mstp_port->ReceivedValidFrame == true) {
if (mstp_port->DestinationAddress == if (mstp_port->DestinationAddress ==
@@ -872,9 +876,13 @@ bool MSTP_Master_Node_FSM(
break; break;
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
/* ReceivedReply */ /* ReceivedReply */
/* or a proprietary type that indicates a reply */ /* or a proprietary type that indicates a reply
/* indicate successful reception to the higher layers */ */
dlmstp_put_receive(mstp_port->SourceAddress, /* source MS/TP address */ /* indicate successful reception to the higher
* layers */
dlmstp_put_receive(
mstp_port->SourceAddress, /* source MS/TP
address */
(uint8_t *)&mstp_port->InputBuffer[0], (uint8_t *)&mstp_port->InputBuffer[0],
mstp_port->DataLength); mstp_port->DataLength);
mstp_port->master_state = mstp_port->master_state =
@@ -927,7 +935,8 @@ bool MSTP_Master_Node_FSM(
(mstp_port->Next_Station != next_this_station)) { (mstp_port->Next_Station != next_this_station)) {
/* SoleMaster */ /* SoleMaster */
/* there are no other known master nodes to */ /* there are no other known master nodes to */
/* which the token may be sent (true master-slave operation). */ /* which the token may be sent (true master-slave
* operation). */
mstp_port->FrameCount = 0; mstp_port->FrameCount = 0;
mstp_port->TokenCount++; mstp_port->TokenCount++;
mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_USE_TOKEN;
@@ -935,9 +944,12 @@ bool MSTP_Master_Node_FSM(
} else { } else {
/* SendToken */ /* SendToken */
/* Npoll changed in Errata SSPC-135-2004 */ /* Npoll changed in Errata SSPC-135-2004 */
/* The comparison of NS and TS+1 eliminates the Poll For Master */ /* The comparison of NS and TS+1 eliminates the Poll For
/* if there are no addresses between TS and NS, since there is no */ * Master */
/* address at which a new master node may be found in that case. */ /* if there are no addresses between TS and NS, since there
* is no */
/* address at which a new master node may be found in that
* case. */
mstp_port->TokenCount++; mstp_port->TokenCount++;
/* transmit a Token frame to NS */ /* transmit a Token frame to NS */
MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN, MSTP_Create_And_Send_Frame(mstp_port, FRAME_TYPE_TOKEN,
@@ -957,11 +969,12 @@ bool MSTP_Master_Node_FSM(
/* no known successor node */ /* no known successor node */
mstp_port->Next_Station = mstp_port->This_Station; mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */ mstp_port->TokenCount =
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */ 1; /* changed in Errata SSPC-135-2004 */
/* mstp_port->EventCount = 0; removed in Addendum
* 135-2004d-8 */
/* find a new successor to TS */ /* find a new successor to TS */
mstp_port->master_state = mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
MSTP_MASTER_STATE_POLL_FOR_MASTER;
} else { } else {
/* ResetMaintenancePFM */ /* ResetMaintenancePFM */
mstp_port->Poll_Station = mstp_port->This_Station; mstp_port->Poll_Station = mstp_port->This_Station;
@@ -970,7 +983,8 @@ bool MSTP_Master_Node_FSM(
mstp_port->Next_Station, mstp_port->This_Station, NULL, mstp_port->Next_Station, mstp_port->This_Station, NULL,
0); 0);
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 1; /* changed in Errata SSPC-135-2004 */ mstp_port->TokenCount =
1; /* changed in Errata SSPC-135-2004 */
mstp_port->EventCount = 0; mstp_port->EventCount = 0;
mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN; mstp_port->master_state = MSTP_MASTER_STATE_PASS_TOKEN;
} }
@@ -990,7 +1004,8 @@ bool MSTP_Master_Node_FSM(
if (mstp_port->SilenceTimer < Tusage_timeout) { if (mstp_port->SilenceTimer < Tusage_timeout) {
if (mstp_port->EventCount > Nmin_octets) { if (mstp_port->EventCount > Nmin_octets) {
/* SawTokenUser */ /* SawTokenUser */
/* Assume that a frame has been sent by the new token user. */ /* Assume that a frame has been sent by the new token user.
*/
/* Enter the IDLE state to process the frame. */ /* Enter the IDLE state to process the frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
transition_now = true; transition_now = true;
@@ -1019,15 +1034,17 @@ bool MSTP_Master_Node_FSM(
mstp_port->Next_Station = mstp_port->This_Station; mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0; mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed in Addendum 135-2004d-8 */ /* mstp_port->EventCount = 0; removed in Addendum
* 135-2004d-8 */
/* find a new successor to TS */ /* find a new successor to TS */
mstp_port->master_state = mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
} }
break; break;
/* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes greater */ /* The NO_TOKEN state is entered if mstp_port->SilenceTimer becomes
/* than Tno_token, indicating that there has been no network activity */ * greater */
/* than Tno_token, indicating that there has been no network
* activity */
/* for that period of time. The timeout is continued to determine */ /* for that period of time. The timeout is continued to determine */
/* whether or not this node may create a token. */ /* whether or not this node may create a token. */
case MSTP_MASTER_STATE_NO_TOKEN: case MSTP_MASTER_STATE_NO_TOKEN:
@@ -1036,7 +1053,8 @@ bool MSTP_Master_Node_FSM(
if (mstp_port->EventCount > Nmin_octets) { if (mstp_port->EventCount > Nmin_octets) {
/* SawFrame */ /* SawFrame */
/* Some other node exists at a lower address. */ /* Some other node exists at a lower address. */
/* Enter the IDLE state to receive and process the incoming frame. */ /* Enter the IDLE state to receive and process the incoming
* frame. */
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
transition_now = true; transition_now = true;
} }
@@ -1056,10 +1074,11 @@ bool MSTP_Master_Node_FSM(
mstp_port->Next_Station = mstp_port->This_Station; mstp_port->Next_Station = mstp_port->This_Station;
mstp_port->RetryCount = 0; mstp_port->RetryCount = 0;
mstp_port->TokenCount = 0; mstp_port->TokenCount = 0;
/* mstp_port->EventCount = 0; removed Addendum 135-2004d-8 */ /* mstp_port->EventCount = 0; removed Addendum 135-2004d-8
/* enter the POLL_FOR_MASTER state to find a new successor to TS. */ */
mstp_port->master_state = /* enter the POLL_FOR_MASTER state to find a new successor
MSTP_MASTER_STATE_POLL_FOR_MASTER; * to TS. */
mstp_port->master_state = MSTP_MASTER_STATE_POLL_FOR_MASTER;
} }
} }
break; break;
@@ -1068,8 +1087,9 @@ bool MSTP_Master_Node_FSM(
/* a successor node. */ /* a successor node. */
case MSTP_MASTER_STATE_POLL_FOR_MASTER: case MSTP_MASTER_STATE_POLL_FOR_MASTER:
if (mstp_port->ReceivedValidFrame == true) { if (mstp_port->ReceivedValidFrame == true) {
if ((mstp_port->DestinationAddress == mstp_port->This_Station) if ((mstp_port->DestinationAddress ==
&& (mstp_port->FrameType == mstp_port->This_Station) &&
(mstp_port->FrameType ==
FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) { FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER)) {
/* ReceivedReplyToPFM */ /* ReceivedReplyToPFM */
mstp_port->SoleMaster = false; mstp_port->SoleMaster = false;
@@ -1128,7 +1148,8 @@ bool MSTP_Master_Node_FSM(
/* Re-enter the current state. */ /* Re-enter the current state. */
} else { } else {
/* DeclareSoleMaster */ /* DeclareSoleMaster */
/* to indicate that this station is the only master */ /* to indicate that this station is the only master
*/
mstp_port->SoleMaster = true; mstp_port->SoleMaster = true;
mstp_port->FrameCount = 0; mstp_port->FrameCount = 0;
mstp_port->master_state = mstp_port->master_state =
@@ -1148,11 +1169,10 @@ bool MSTP_Master_Node_FSM(
/* Compare the APDU type received and /* Compare the APDU type received and
see if the message is that same APDU type see if the message is that same APDU type
along with the matching src/dest and invoke ID */ along with the matching src/dest and invoke ID */
matched = matched = mstp_compare_data_expecting_reply(
mstp_compare_data_expecting_reply(&mstp_port->InputBuffer &mstp_port->InputBuffer[0], mstp_port->DataLength,
[0], mstp_port->DataLength, mstp_port->SourceAddress, mstp_port->SourceAddress, &mstp_port->TxBuffer[8],
&mstp_port->TxBuffer[8], mstp_port->TxLength, mstp_port->TxLength, mstp_port->TxDestination);
mstp_port->TxDestination);
} }
if (matched && mstp_port->TxReady) { if (matched && mstp_port->TxReady) {
/* Reply */ /* Reply */
@@ -1160,10 +1180,11 @@ bool MSTP_Master_Node_FSM(
/* within Treply_delay after the reception of the */ /* within Treply_delay after the reception of the */
/* final octet of the requesting frame */ /* final octet of the requesting frame */
/* (the mechanism used to determine this is a local matter), */ /* (the mechanism used to determine this is a local matter), */
/* then call MSTP_Create_And_Send_Frame to transmit the reply frame */ /* then call MSTP_Create_And_Send_Frame to transmit the reply
* frame */
/* and enter the IDLE state to wait for the next frame. */ /* and enter the IDLE state to wait for the next frame. */
RS485_Send_Frame(mstp_port, RS485_Send_Frame(mstp_port, (uint8_t *)&mstp_port->TxBuffer[0],
(uint8_t *) & mstp_port->TxBuffer[0], mstp_port->TxLength); mstp_port->TxLength);
mstp_port->TxReady = false; mstp_port->TxReady = false;
mstp_port->master_state = MSTP_MASTER_STATE_IDLE; mstp_port->master_state = MSTP_MASTER_STATE_IDLE;
} else if (mstp_port->SilenceTimer > Treply_delay) { } else if (mstp_port->SilenceTimer > Treply_delay) {
@@ -1193,8 +1214,7 @@ bool MSTP_Master_Node_FSM(
/* note: This_Station should be set with the MAC address */ /* note: This_Station should be set with the MAC address */
/* note: Nmax_info_frames should be set */ /* note: Nmax_info_frames should be set */
/* note: Nmax_master should be set */ /* note: Nmax_master should be set */
void MSTP_Init( void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
int i; /*loop counter */ int i; /*loop counter */
@@ -1233,7 +1253,8 @@ void MSTP_Init(
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 */
for (i = 0; i < sizeof(mstp_port->TxBuffer); i++) { for (i = 0; i < sizeof(mstp_port->TxBuffer); i++) {
mstp_port->TxBuffer[i] = 0; mstp_port->TxBuffer[i] = 0;
@@ -1241,6 +1262,5 @@ void MSTP_Init(
mstp_port->TxLength = 0; mstp_port->TxLength = 0;
mstp_port->TxReady = false; mstp_port->TxReady = false;
mstp_port->TxFrameType = 0; mstp_port->TxFrameType = 0;
} }
} }
+11 -20
View File
@@ -107,8 +107,7 @@ void RS485_Send_Frame(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_Check_UART_Data( bool RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t * mstp_port)
{ {
/* check for data */ /* check for data */
if (!FIFO_Empty(&FIFO_Rx)) { if (!FIFO_Empty(&FIFO_Rx)) {
@@ -128,8 +127,7 @@ bool RS485_Check_UART_Data(
NOTES: none NOTES: none
*************************************************************************** */ *************************************************************************** */
void RS485_Interrupt_Rx( void RS485_Interrupt_Rx(void)
void)
{ {
uint8_t data_byte; uint8_t data_byte;
@@ -154,14 +152,14 @@ void RS485_Interrupt_Rx(
NOTES: none NOTES: none
*************************************************************************** */ *************************************************************************** */
void RS485_Interrupt_Tx( void RS485_Interrupt_Tx(void)
void)
{ {
if (!FIFO_Empty(&FIFO_Tx)) { if (!FIFO_Empty(&FIFO_Tx)) {
TXREG2 = FIFO_Get(&FIFO_Tx); TXREG2 = FIFO_Get(&FIFO_Tx);
} else { } else {
/* wait for the USART to be empty */ /* wait for the USART to be empty */
while (!TXSTA2bits.TRMT); while (!TXSTA2bits.TRMT)
;
/* disable this interrupt */ /* disable this interrupt */
PIE3bits.TX2IE = 0; PIE3bits.TX2IE = 0;
/* enable the receiver */ /* enable the receiver */
@@ -179,8 +177,7 @@ void RS485_Interrupt_Tx(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(void)
void)
{ {
return RS485_Baud_Rate; return RS485_Baud_Rate;
} }
@@ -191,8 +188,7 @@ uint32_t RS485_Get_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(uint32_t baud)
uint32_t baud)
{ {
bool valid = true; bool valid = true;
@@ -229,10 +225,8 @@ bool RS485_Set_Baud_Rate(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Initialize_Port( void RS485_Initialize_Port(void)
void)
{ {
/* Reset USART registers to POR state */ /* Reset USART registers to POR state */
TXSTA2 = 0; TXSTA2 = 0;
RCSTA2 = 0; RCSTA2 = 0;
@@ -309,8 +303,7 @@ void RS485_Initialize_Port(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Disable_Port( void RS485_Disable_Port(void)
void)
{ {
RCSTA2 &= 0x4F; /* Disable the receiver */ RCSTA2 &= 0x4F; /* Disable the receiver */
TXSTA2bits.TXEN = 0; /* and transmitter */ TXSTA2bits.TXEN = 0; /* and transmitter */
@@ -323,8 +316,7 @@ void RS485_Disable_Port(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Reinit( void RS485_Reinit(void)
void)
{ {
RS485_Set_Baud_Rate(38400); RS485_Set_Baud_Rate(38400);
} }
@@ -335,8 +327,7 @@ void RS485_Reinit(
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Initialize( void RS485_Initialize(void)
void)
{ {
/* Init the Rs485 buffers */ /* Init the Rs485 buffers */
FIFO_Init(&FIFO_Rx, RS485_Rx_Buffer, sizeof(RS485_Rx_Buffer)); FIFO_Init(&FIFO_Rx, RS485_Rx_Buffer, sizeof(RS485_Rx_Buffer));
+13 -23
View File
@@ -44,8 +44,7 @@ static uint8_t Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
@@ -54,21 +53,18 @@ bool Analog_Input_Valid_Instance(
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
char *Analog_Input_Name( char *Analog_Input_Name(uint32_t object_instance)
uint32_t object_instance)
{ {
static char text_string[16] = ""; /* okay for single thread */ static char text_string[16] = ""; /* okay for single thread */
@@ -80,8 +76,7 @@ char *Analog_Input_Name(
return NULL; return NULL;
} }
float Analog_Input_Present_Value( float Analog_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
@@ -91,9 +86,7 @@ float Analog_Input_Present_Value(
return value; return value;
} }
void Analog_Input_Present_Value_Set( void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
if (object_instance < MAX_ANALOG_INPUTS) { if (object_instance < MAX_ANALOG_INPUTS) {
Present_Value[object_instance] = value; Present_Value[object_instance] = value;
@@ -102,8 +95,7 @@ void Analog_Input_Present_Value_Set(
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object has already exists */
int Analog_Input_Read_Property( int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -117,16 +109,15 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, &apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
Analog_Input_Name(rpdata->object_instance)); &char_string, Analog_Input_Name(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
@@ -135,9 +126,8 @@ int Analog_Input_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
+18 -23
View File
@@ -43,20 +43,17 @@
/* me */ /* me */
#include "bacnet/apdu.h" #include "bacnet/apdu.h"
uint16_t apdu_timeout( uint16_t apdu_timeout(void)
void)
{ {
return 3000; return 3000;
} }
uint8_t apdu_retries( uint8_t apdu_retries(void)
void)
{ {
return 3; return 3;
} }
bool apdu_service_supported( bool apdu_service_supported(BACNET_SERVICES_SUPPORTED service_supported)
BACNET_SERVICES_SUPPORTED service_supported)
{ {
bool status = false; bool status = false;
@@ -75,8 +72,7 @@ bool apdu_service_supported(
return status; return status;
} }
uint16_t apdu_decode_confirmed_service_request( uint16_t apdu_decode_confirmed_service_request(uint8_t *apdu, /* APDU data */
uint8_t * apdu, /* APDU data */
uint16_t apdu_len, uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA *service_data, BACNET_CONFIRMED_SERVICE_DATA *service_data,
uint8_t *service_choice, uint8_t *service_choice,
@@ -110,8 +106,7 @@ uint16_t apdu_decode_confirmed_service_request(
When the initiation of communications is disabled, When the initiation of communications is disabled,
all APDUs shall be processed and responses returned as all APDUs shall be processed and responses returned as
required... */ required... */
static bool apdu_confirmed_dcc_disabled( static bool apdu_confirmed_dcc_disabled(uint8_t service_choice)
uint8_t service_choice)
{ {
bool status = false; bool status = false;
@@ -136,8 +131,7 @@ static bool apdu_confirmed_dcc_disabled(
DISABLE_INITIATION, the responding BACnet-user shall DISABLE_INITIATION, the responding BACnet-user shall
discontinue the initiation of messages except for I-Am discontinue the initiation of messages except for I-Am
requests issued in accordance with the Who-Is service procedure.*/ requests issued in accordance with the Who-Is service procedure.*/
static bool apdu_unconfirmed_dcc_disabled( static bool apdu_unconfirmed_dcc_disabled(uint8_t service_choice)
uint8_t service_choice)
{ {
bool status = false; bool status = false;
@@ -159,8 +153,7 @@ static bool apdu_unconfirmed_dcc_disabled(
return status; return status;
} }
void apdu_handler( void apdu_handler(BACNET_ADDRESS *src,
BACNET_ADDRESS * src,
uint8_t *apdu, /* APDU data */ uint8_t *apdu, /* APDU data */
uint16_t apdu_len) uint16_t apdu_len)
{ {
@@ -174,21 +167,23 @@ void apdu_handler(
/* PDU Type */ /* PDU Type */
switch (apdu[0] & 0xF0) { switch (apdu[0] & 0xF0) {
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ len = apdu_decode_confirmed_service_request(
&apdu[0], /* APDU data */
apdu_len, &service_data, &service_choice, &service_request, apdu_len, &service_data, &service_choice, &service_request,
&service_request_len); &service_request_len);
if (apdu_confirmed_dcc_disabled(service_choice)) { if (apdu_confirmed_dcc_disabled(service_choice)) {
/* When network communications are completely disabled, /* When network communications are completely disabled,
only DeviceCommunicationControl and ReinitializeDevice APDUs only DeviceCommunicationControl and ReinitializeDevice
shall be processed and no messages shall be initiated. */ APDUs shall be processed and no messages shall be
initiated. */
break; break;
} }
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
handler_read_property(service_request, service_request_len, handler_read_property(service_request, service_request_len,
src, &service_data); src, &service_data);
} else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) { } else if (service_choice == SERVICE_CONFIRMED_WRITE_PROPERTY) {
handler_write_property(service_request, handler_write_property(service_request, service_request_len,
service_request_len, src, &service_data); src, &service_data);
} else if (service_choice == } else if (service_choice ==
SERVICE_CONFIRMED_REINITIALIZE_DEVICE) { SERVICE_CONFIRMED_REINITIALIZE_DEVICE) {
handler_reinitialize_device(service_request, handler_reinitialize_device(service_request,
@@ -208,10 +203,10 @@ void apdu_handler(
service_request_len = apdu_len - 2; service_request_len = apdu_len - 2;
if (apdu_unconfirmed_dcc_disabled(service_choice)) { if (apdu_unconfirmed_dcc_disabled(service_choice)) {
/* When network communications are disabled, /* When network communications are disabled,
only DeviceCommunicationControl and ReinitializeDevice APDUs only DeviceCommunicationControl and ReinitializeDevice
shall be processed and no messages shall be initiated. APDUs shall be processed and no messages shall be
If communications have been initiation disabled, then initiated. If communications have been initiation
WhoIs may be processed. */ disabled, then WhoIs may be processed. */
break; break;
} }
if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) { if (service_choice == SERVICE_UNCONFIRMED_WHO_IS) {

Some files were not shown because too many files have changed in this diff Show More