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:
@@ -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 \
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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"
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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__)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+25
-30
@@ -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
@@ -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
@@ -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,
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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 *) ð_addr,
|
(struct sockaddr *)ð_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 *) ð_addr,
|
(struct sockaddr *)ð_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 */
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user