diff --git a/bacnet-stack/demo/handler/h_cov.c b/bacnet-stack/demo/handler/h_cov.c index 412bf032..a5f6e06e 100644 --- a/bacnet-stack/demo/handler/h_cov.c +++ b/bacnet-stack/demo/handler/h_cov.c @@ -426,8 +426,8 @@ static bool cov_subscribe( switch (cov_data->monitoredObjectIdentifier.type) { case OBJECT_BINARY_INPUT: - if (Binary_Input_Valid_Instance( - cov_data->monitoredObjectIdentifier.instance)) { + if (Binary_Input_Valid_Instance(cov_data-> + monitoredObjectIdentifier.instance)) { status = cov_list_subscribe(src, cov_data, error_class, error_code); } else { diff --git a/bacnet-stack/demo/handler/h_rpm.c b/bacnet-stack/demo/handler/h_rpm.c index 5ab5715c..a911b752 100644 --- a/bacnet-stack/demo/handler/h_rpm.c +++ b/bacnet-stack/demo/handler/h_rpm.c @@ -244,8 +244,7 @@ int RPM_Encode_Property( rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0], error_class, error_code); len = - memcopy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len, - max_apdu); + memcopy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len, max_apdu); if (!len) { return 0; } @@ -344,8 +343,8 @@ void handler_read_property_multiple( rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], object_type, object_instance); copy_len = - memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], - apdu_len, len, sizeof(Handler_Transmit_Buffer)); + memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], apdu_len, + len, sizeof(Handler_Transmit_Buffer)); if (!copy_len) { apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], diff --git a/bacnet-stack/demo/handler/h_rpm_a.c b/bacnet-stack/demo/handler/h_rpm_a.c index ec4016fd..458cca6c 100644 --- a/bacnet-stack/demo/handler/h_rpm_a.c +++ b/bacnet-stack/demo/handler/h_rpm_a.c @@ -45,11 +45,11 @@ /* note: initial the linked list of read_access_data */ static int rpm_ack_decode_service_request( uint8_t * apdu, - int apdu_len, /* total length of the apdu */ + int apdu_len, /* total length of the apdu */ BACNET_READ_ACCESS_DATA * read_access_data) { - int decoded_len = 0; /* return value */ - int len = 0; /* number of bytes returned from decoding */ + int decoded_len = 0; /* return value */ + int len = 0; /* number of bytes returned from decoding */ BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; @@ -60,9 +60,8 @@ static int rpm_ack_decode_service_request( rpm_object = read_access_data; old_rpm_object = rpm_object; while (rpm_object && apdu_len) { - len = rpm_ack_decode_object_id( - apdu, apdu_len, - &rpm_object->object_type, + len = + rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type, &rpm_object->object_instance); if (len <= 0) { old_rpm_object->next = NULL; @@ -76,9 +75,8 @@ static int rpm_ack_decode_service_request( rpm_object->listOfProperties = rpm_property; old_rpm_property = rpm_property; while (rpm_property && apdu_len) { - len = rpm_ack_decode_object_property( - apdu, - apdu_len, + len = + rpm_ack_decode_object_property(apdu, apdu_len, &rpm_property->propertyIdentifier, &rpm_property->propertyArrayIndex); if (len <= 0) { @@ -94,15 +92,13 @@ static int rpm_ack_decode_service_request( apdu_len--; apdu++; /* note: if this is an array, there will be - more than one element to decode */ + more than one element to decode */ value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); rpm_property->value = value; old_value = value; while (value && (apdu_len > 0)) { - len = bacapp_decode_application_data( - apdu, - apdu_len, - value); + len = + bacapp_decode_application_data(apdu, apdu_len, value); decoded_len += len; apdu_len -= len; apdu += len; @@ -113,7 +109,8 @@ static int rpm_ack_decode_service_request( break; } else { old_value = value; - value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); + value = + calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); old_value->next = value; } } @@ -174,8 +171,7 @@ static void PrintReadPropertyMultipleData( } #endif while (value) { - bacapp_print_value(stdout, - value, + bacapp_print_value(stdout, value, listOfProperties->propertyIdentifier); #if PRINT_ENABLED if (value->next) { @@ -205,19 +201,20 @@ void handler_read_property_multiple_ack( BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data) { int len = 0; - BACNET_READ_ACCESS_DATA * rpm_data; - BACNET_READ_ACCESS_DATA * old_rpm_data; + BACNET_READ_ACCESS_DATA *rpm_data; + BACNET_READ_ACCESS_DATA *old_rpm_data; BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *old_rpm_property; BACNET_APPLICATION_DATA_VALUE *value; BACNET_APPLICATION_DATA_VALUE *old_value; (void) src; - (void) service_data; /* we could use these... */ + (void) service_data; /* we could use these... */ rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); if (rpm_data) { - len = rpm_ack_decode_service_request(service_request, service_len, + len = + rpm_ack_decode_service_request(service_request, service_len, rpm_data); } #if 1 diff --git a/bacnet-stack/demo/handler/h_ucov.c b/bacnet-stack/demo/handler/h_ucov.c index e543ea25..2e81dbf3 100644 --- a/bacnet-stack/demo/handler/h_ucov.c +++ b/bacnet-stack/demo/handler/h_ucov.c @@ -1,85 +1,81 @@ -/************************************************************************** -* -* Copyright (C) 2008 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -/* special for this module */ -#include "cov.h" -#include "bactext.h" - -/* note: nothing is specified in BACnet about what to do with the - information received from Unconfirmed COV Notifications. */ -void handler_ucov_notification( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src) -{ - BACNET_COV_DATA cov_data; - BACNET_PROPERTY_VALUE property_value; - int len = 0; - - /* create linked list to store data if more - than one property value is expected */ - property_value.next = NULL; - cov_data.listOfValues = &property_value; -#if PRINT_ENABLED - fprintf(stderr, "UCOV: Received Notification!\n"); -#endif - /* decode the service request only */ - len = cov_notify_decode_service_request( - service_request, service_len, &cov_data); -#if PRINT_ENABLED - if (len > 0) { - fprintf(stderr, "UCOV: PID=%u ", - cov_data.subscriberProcessIdentifier); - fprintf(stderr, "instance=%u ", - cov_data.initiatingDeviceIdentifier); - fprintf(stderr, "%s %u ", - bactext_object_type_name( - cov_data.monitoredObjectIdentifier.type), - cov_data.monitoredObjectIdentifier.instance); - fprintf(stderr, "time remaining=%u seconds ", - cov_data.timeRemaining); - fprintf(stderr, "%s ", - bactext_property_name(property_value.propertyIdentifier)); - if (property_value.propertyArrayIndex != BACNET_ARRAY_ALL) { - fprintf(stderr, "%u ", - property_value.propertyArrayIndex); - } - fprintf(stderr, "\n"); - } else { - fprintf(stderr, "UCOV: Unable to decode service request!\n"); - } -#endif -} +/************************************************************************** +* +* Copyright (C) 2008 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "apdu.h" +#include "npdu.h" +#include "abort.h" +/* special for this module */ +#include "cov.h" +#include "bactext.h" + +/* note: nothing is specified in BACnet about what to do with the + information received from Unconfirmed COV Notifications. */ +void handler_ucov_notification( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src) +{ + BACNET_COV_DATA cov_data; + BACNET_PROPERTY_VALUE property_value; + int len = 0; + + /* create linked list to store data if more + than one property value is expected */ + property_value.next = NULL; + cov_data.listOfValues = &property_value; +#if PRINT_ENABLED + fprintf(stderr, "UCOV: Received Notification!\n"); +#endif + /* decode the service request only */ + len = + cov_notify_decode_service_request(service_request, service_len, + &cov_data); +#if PRINT_ENABLED + if (len > 0) { + fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier); + fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); + fprintf(stderr, "%s %u ", + bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), + cov_data.monitoredObjectIdentifier.instance); + fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); + fprintf(stderr, "%s ", + bactext_property_name(property_value.propertyIdentifier)); + if (property_value.propertyArrayIndex != BACNET_ARRAY_ALL) { + fprintf(stderr, "%u ", property_value.propertyArrayIndex); + } + fprintf(stderr, "\n"); + } else { + fprintf(stderr, "UCOV: Unable to decode service request!\n"); + } +#endif +} diff --git a/bacnet-stack/demo/handler/s_iam.c b/bacnet-stack/demo/handler/s_iam.c index 59f9eef4..1ff8eda6 100644 --- a/bacnet-stack/demo/handler/s_iam.c +++ b/bacnet-stack/demo/handler/s_iam.c @@ -1,94 +1,93 @@ -/************************************************************************** -* -* Copyright (C) 2008 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include "config.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "address.h" -#include "tsm.h" -#include "dcc.h" -#include "npdu.h" -#include "apdu.h" -#include "device.h" -#include "datalink.h" -#include "iam.h" -/* some demo stuff needed */ -#include "handlers.h" - -int iam_encode_pdu( - uint8_t * buffer, - BACNET_ADDRESS * dest, - BACNET_NPDU_DATA * npdu_data) -{ - int len = 0; - int pdu_len = 0; - - /* I-Am is a global broadcast */ - datalink_get_broadcast_address(dest); - /* encode the NPDU portion of the packet */ - npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(&buffer[0], dest, NULL, npdu_data); - /* encode the APDU portion of the packet */ - len = - iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(), - MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); - pdu_len += len; - - return pdu_len; -} - -void Send_I_Am( - uint8_t * buffer) -{ - int pdu_len = 0; - BACNET_ADDRESS dest; - int bytes_sent = 0; - BACNET_NPDU_DATA npdu_data; - -#if 0 - /* note: there is discussion in the BACnet committee - that we should allow a device to reply with I-Am - so that dynamic binding always work. If the DCC - initiator loses the MAC address and routing info, - they can never re-enable DCC because they can't - find the device with WhoIs/I-Am */ - /* are we are forbidden to send? */ - if (!dcc_communication_enabled()) - return 0; -#endif - /* encode the data */ - pdu_len = iam_encode_pdu(buffer, &dest, &npdu_data); - /* send data */ - bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); - -#if PRINT_ENABLED - if (bytes_sent <= 0) - fprintf(stderr, "Failed to Send I-Am Reply (%s)!\n", - strerror(errno)); -#endif -} +/************************************************************************** +* +* Copyright (C) 2008 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include "config.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "address.h" +#include "tsm.h" +#include "dcc.h" +#include "npdu.h" +#include "apdu.h" +#include "device.h" +#include "datalink.h" +#include "iam.h" +/* some demo stuff needed */ +#include "handlers.h" + +int iam_encode_pdu( + uint8_t * buffer, + BACNET_ADDRESS * dest, + BACNET_NPDU_DATA * npdu_data) +{ + int len = 0; + int pdu_len = 0; + + /* I-Am is a global broadcast */ + datalink_get_broadcast_address(dest); + /* encode the NPDU portion of the packet */ + npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(&buffer[0], dest, NULL, npdu_data); + /* encode the APDU portion of the packet */ + len = + iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(), + MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); + pdu_len += len; + + return pdu_len; +} + +void Send_I_Am( + uint8_t * buffer) +{ + int pdu_len = 0; + BACNET_ADDRESS dest; + int bytes_sent = 0; + BACNET_NPDU_DATA npdu_data; + +#if 0 + /* note: there is discussion in the BACnet committee + that we should allow a device to reply with I-Am + so that dynamic binding always work. If the DCC + initiator loses the MAC address and routing info, + they can never re-enable DCC because they can't + find the device with WhoIs/I-Am */ + /* are we are forbidden to send? */ + if (!dcc_communication_enabled()) + return 0; +#endif + /* encode the data */ + pdu_len = iam_encode_pdu(buffer, &dest, &npdu_data); + /* send data */ + bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); + +#if PRINT_ENABLED + if (bytes_sent <= 0) + fprintf(stderr, "Failed to Send I-Am Reply (%s)!\n", strerror(errno)); +#endif +} diff --git a/bacnet-stack/demo/handler/s_router.c b/bacnet-stack/demo/handler/s_router.c index 94832683..f8a321d1 100644 --- a/bacnet-stack/demo/handler/s_router.c +++ b/bacnet-stack/demo/handler/s_router.c @@ -69,8 +69,7 @@ void Send_Who_Is_Router_To_Network( BACNET_NPDU_DATA npdu_data; npdu_encode_npdu_network(&npdu_data, - NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, - false, + NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, false, MESSAGE_PRIORITY_NORMAL); /* fixme: should dnet/dlen/dadr be set in NPDU? */ pdu_len = @@ -112,8 +111,7 @@ void Send_I_Am_Router_To_Network( unsigned index = 0; npdu_encode_npdu_network(&npdu_data, - NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, - false, + NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, false, MESSAGE_PRIORITY_NORMAL); pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data); @@ -157,9 +155,7 @@ void Send_Initialize_Routing_Table( BACNET_ROUTER_PORT *router_port; unsigned i = 0; /* counter */ - npdu_encode_npdu_network(&npdu_data, - NETWORK_MESSAGE_INIT_RT_TABLE, - true, + npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE, true, MESSAGE_PRIORITY_NORMAL); pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data); @@ -208,10 +204,8 @@ void Send_Initialize_Routing_Table_Ack( int bytes_sent = 0; BACNET_NPDU_DATA npdu_data; - npdu_encode_npdu_network(&npdu_data, - NETWORK_MESSAGE_INIT_RT_TABLE_ACK, - false, - MESSAGE_PRIORITY_NORMAL); + npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK, + false, MESSAGE_PRIORITY_NORMAL); pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data); /* encode the optional DNET list portion of the packet */ diff --git a/bacnet-stack/demo/handler/s_rpm.c b/bacnet-stack/demo/handler/s_rpm.c index 76321681..df15ef96 100644 --- a/bacnet-stack/demo/handler/s_rpm.c +++ b/bacnet-stack/demo/handler/s_rpm.c @@ -48,7 +48,7 @@ uint8_t Send_Read_Property_Multiple_Request( uint8_t * pdu, size_t max_pdu, uint32_t device_id, /* destination device */ - BACNET_READ_ACCESS_DATA *read_access_data) + BACNET_READ_ACCESS_DATA * read_access_data) { BACNET_ADDRESS dest; BACNET_ADDRESS my_address; @@ -72,14 +72,10 @@ uint8_t Send_Read_Property_Multiple_Request( /* encode the NPDU portion of the packet */ datalink_get_my_address(&my_address); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); - pdu_len = - npdu_encode_pdu(&pdu[0], &dest, &my_address, - &npdu_data); + pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data); /* encode the APDU portion of the packet */ - len = rpm_encode_apdu( - &pdu[pdu_len], - max_pdu - pdu_len, - invoke_id, + len = + rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id, read_access_data); if (len <= 0) { return 0; @@ -94,8 +90,7 @@ uint8_t Send_Read_Property_Multiple_Request( tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, &npdu_data, &pdu[0], (uint16_t) pdu_len); bytes_sent = - datalink_send_pdu(&dest, &npdu_data, - &pdu[0], pdu_len); + datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len); #if PRINT_ENABLED if (bytes_sent <= 0) fprintf(stderr, diff --git a/bacnet-stack/demo/initrouter/main.c b/bacnet-stack/demo/initrouter/main.c index 73e3e4b9..71583f48 100644 --- a/bacnet-stack/demo/initrouter/main.c +++ b/bacnet-stack/demo/initrouter/main.c @@ -86,9 +86,9 @@ static void MyRejectHandler( } static void My_Router_Handler( - BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data, - uint8_t * npdu, /* PDU data */ + BACNET_ADDRESS * src, + BACNET_NPDU_DATA * npdu_data, + uint8_t * npdu, /* PDU data */ uint16_t npdu_len) { uint16_t npdu_offset = 0; @@ -122,26 +122,26 @@ static void My_Router_Handler( } } port_mappings = npdu[0]; - printf("\nPort Mappings: %u\n",port_mappings); + printf("\nPort Mappings: %u\n", port_mappings); npdu_offset = 1; npdu_len--; while (npdu_len) { len = decode_unsigned16(&npdu[npdu_offset], &dnet); - printf("DNET=%hu, ",dnet); + printf("DNET=%hu, ", dnet); npdu_offset += len; npdu_len -= len; if (!npdu_len) { break; } port_id = npdu[npdu_offset]; - printf("Port ID=%u, ",port_id); + printf("Port ID=%u, ", port_id); npdu_offset++; npdu_len--; if (!npdu_len) { break; } port_info_len = npdu[npdu_offset]; - printf("Port Info Length=%u, ",port_info_len); + printf("Port Info Length=%u, ", port_info_len); npdu_offset++; npdu_len--; printf("Port Info=\""); @@ -150,7 +150,7 @@ static void My_Router_Handler( break; } if (j < port_info_len) { - printf("%02X",npdu[npdu_offset]); + printf("%02X", npdu[npdu_offset]); npdu_offset++; npdu_len--; } @@ -182,7 +182,7 @@ static void My_NPDU_Handler( apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data); if (npdu_data.network_layer_message) { - My_Router_Handler(src,&npdu_data,&pdu[apdu_offset], + My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], (uint16_t) (pdu_len - apdu_offset)); } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && @@ -325,7 +325,8 @@ static void address_parse(BACNET_ADDRESS * dst, dst->mac_len = 6; for (index = 0; index < 4; index++) { dst->mac[index] = mac[index]; - } encode_unsigned16(&dst->mac[4], + } + encode_unsigned16(&dst->mac[4], port); } else { count = @@ -364,22 +365,14 @@ int main(int argc, char *argv[]) { filename_remove_path(argv[0])); return 0; } - if (( - argc > 1) && ( - strcmp(argv[1], - "--help") == 0)) { + if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { printf("Send BACnet Initialize-Routing-Table message to a network\r\n" "and wait for responses. Displays their network information.\r\n" - "\r\n" - "address:\r\n" + "\r\n" "address:\r\n" "MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\r\n" - "DNET ID Len Info:\r\n" - "Port-info data:\r\n" - " DNET:\r\n" - " Destination network number 0-65534\r\n" - " ID:\r\n" - " Port Identifier number 0-255\r\n" - " Info:\r\n" + "DNET ID Len Info:\r\n" "Port-info data:\r\n" " DNET:\r\n" + " Destination network number 0-65534\r\n" " ID:\r\n" + " Port Identifier number 0-255\r\n" " Info:\r\n" " Octet string of data, up to 255 octets\r\n" "To query the complete routing table, do not include any port-info.\r\n" "To query using Initialize-Routing-Table message to 192.168.0.18:\r\n" diff --git a/bacnet-stack/demo/mstpcap/main.c b/bacnet-stack/demo/mstpcap/main.c index d44e8ea6..03aa4464 100644 --- a/bacnet-stack/demo/mstpcap/main.c +++ b/bacnet-stack/demo/mstpcap/main.c @@ -139,7 +139,7 @@ static void milliseconds_task_win32( /* functions used by the MS/TP state machine to put or get data */ uint16_t MSTP_Put_Receive( - volatile struct mstp_port_struct_t * mstp_port) + volatile struct mstp_port_struct_t *mstp_port) { (void) mstp_port; @@ -217,7 +217,7 @@ static void write_received_packet( fwrite(&ts_sec, sizeof(ts_sec), 1, pFile); fwrite(&ts_usec, sizeof(ts_usec), 1, pFile); if (mstp_port->DataLength) { - max_data = min(mstp_port->InputBufferSize,mstp_port->DataLength); + max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength); incl_len = orig_len = 8 + max_data + 2; } else { incl_len = orig_len = 8; diff --git a/bacnet-stack/demo/object/bo.c b/bacnet-stack/demo/object/bo.c index 6d6ff6ef..3e6ebdd5 100644 --- a/bacnet-stack/demo/object/bo.c +++ b/bacnet-stack/demo/object/bo.c @@ -308,12 +308,12 @@ int Binary_Output_Encode_Property_APDU( apdu_len = encode_application_enumerated(&apdu[0], present_value); break; case PROP_ACTIVE_TEXT: - characterstring_init_ansi(&char_string,"on" ); + characterstring_init_ansi(&char_string, "on"); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; case PROP_INACTIVE_TEXT: - characterstring_init_ansi(&char_string,"off" ); + characterstring_init_ansi(&char_string, "off"); apdu_len = encode_application_character_string(&apdu[0], &char_string); break; diff --git a/bacnet-stack/demo/readpropm/main.c b/bacnet-stack/demo/readpropm/main.c index 72017fed..4368b7d4 100644 --- a/bacnet-stack/demo/readpropm/main.c +++ b/bacnet-stack/demo/readpropm/main.c @@ -216,23 +216,21 @@ static void Init_DataLink( #endif } -void cleanup(void) -{ +void cleanup(void) { BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *old_rpm_property; - rpm_object = Read_Access_Data; - old_rpm_object = rpm_object; - while (rpm_object) { + rpm_object = Read_Access_Data; + old_rpm_object = rpm_object; + while (rpm_object) { rpm_property = rpm_object->listOfProperties; while (rpm_property) { old_rpm_property = rpm_property; rpm_property = rpm_property->next; free(old_rpm_property); - } - old_rpm_object = rpm_object; + } old_rpm_object = rpm_object; rpm_object = rpm_object->next; free(old_rpm_object); } @@ -251,14 +249,16 @@ int main(int argc, char *argv[]) { time_t timeout_seconds = 0; uint8_t invoke_id = 0; bool found = false; - uint8_t buffer[MAX_PDU] = {0}; + uint8_t buffer[MAX_PDU] = { + 0}; BACNET_READ_ACCESS_DATA *rpm_object; BACNET_PROPERTY_REFERENCE *rpm_property; if (argc < 5) { printf("Usage: %s device-instance object-type object-instance " - "property index [object-type ...]\r\n", filename_remove_path(argv[0])); + "property index [object-type ...]\r\n", + filename_remove_path(argv[0])); if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { printf("device-instance:\r\n" "BACnet Device Object Instance number that you are\r\n" @@ -285,8 +285,7 @@ int main(int argc, char *argv[]) { "If the property is an array, individual elements can\r\n" "be read. If this parameter is missing and the property\r\n" "is an array, the entire array will be read.\r\n" - "\r\nExample:\r\n" - "If you want read the ALL property in\r\n" + "\r\nExample:\r\n" "If you want read the ALL property in\r\n" "Device object 123, you would use the following command:\r\n" "%s 123 8 123 8 -1\r\n" "If you want read the OPTIONAL property in\r\n" @@ -294,10 +293,8 @@ int main(int argc, char *argv[]) { "%s 123 8 123 80 -1\r\n" "If you want read the REQUIRED property in\r\n" "Device object 123, you would use the following command:\r\n" - "%s 123 8 123 105 -1\r\n", - filename_remove_path(argv[0]), - filename_remove_path(argv[0]), - filename_remove_path(argv[0])); + "%s 123 8 123 105 -1\r\n", filename_remove_path(argv[0]), + filename_remove_path(argv[0]), filename_remove_path(argv[0])); } return 0; } @@ -315,8 +312,7 @@ int main(int argc, char *argv[]) { arg_sets = 0; while (rpm_object) { tag_value_arg = 2 + (arg_sets * 4); - rpm_object->object_type = - strtol(argv[tag_value_arg], NULL, 0); + rpm_object->object_type = strtol(argv[tag_value_arg], NULL, 0); tag_value_arg++; args_remaining--; if (args_remaining <= 0) { @@ -328,8 +324,7 @@ int main(int argc, char *argv[]) { rpm_object->object_type, MAX_BACNET_OBJECT_TYPE + 1); return 1; } - rpm_object->object_instance = - strtol(argv[tag_value_arg], NULL, 0); + rpm_object->object_instance = strtol(argv[tag_value_arg], NULL, 0); tag_value_arg++; args_remaining--; if (args_remaining <= 0) { @@ -350,12 +345,14 @@ int main(int argc, char *argv[]) { tag_value_arg++; args_remaining--; if (args_remaining <= 0) { - fprintf(stderr, "Error: not enough object property quads.\r\n"); + fprintf(stderr, + "Error: not enough object property quads.\r\n"); return 1; } if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { fprintf(stderr, "property=%u - it must be less than %u\r\n", - rpm_property->propertyIdentifier, MAX_BACNET_PROPERTY_ID + 1); + rpm_property->propertyIdentifier, + MAX_BACNET_PROPERTY_ID + 1); return 1; } rpm_property->propertyArrayIndex = @@ -413,10 +410,9 @@ int main(int argc, char *argv[]) { &Target_Address); if (found) { if (invoke_id == 0) { - invoke_id = Send_Read_Property_Multiple_Request( - &buffer[0], - sizeof(buffer), - Target_Device_Object_Instance, + invoke_id = + Send_Read_Property_Multiple_Request(&buffer[0], + sizeof(buffer), Target_Device_Object_Instance, Read_Access_Data); } else if (tsm_invoke_id_free(invoke_id)) break; diff --git a/bacnet-stack/demo/server/main.c b/bacnet-stack/demo/server/main.c index 8a3fa79f..32ffeb31 100644 --- a/bacnet-stack/demo/server/main.c +++ b/bacnet-stack/demo/server/main.c @@ -87,7 +87,7 @@ static void Init_Service_Handlers( handler_timesync); apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe); - apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, + apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, handler_ucov_notification); /* handle communication so we can shutup when asked */ apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, diff --git a/bacnet-stack/demo/ucov/main.c b/bacnet-stack/demo/ucov/main.c index f32d3cd4..3bf3b5ba 100644 --- a/bacnet-stack/demo/ucov/main.c +++ b/bacnet-stack/demo/ucov/main.c @@ -212,8 +212,8 @@ int main(int argc, char *argv[]) { filename_remove_path(argv[0]), filename_remove_path(argv[0])); return 0; } - /* decode the command line parameters */ - cov_data.subscriberProcessIdentifier = strtol(argv[1], NULL, 0); + /* decode the command line parameters */ cov_data. + subscriberProcessIdentifier = strtol(argv[1], NULL, 0); cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0); cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0); cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0); diff --git a/bacnet-stack/demo/whois/main.c b/bacnet-stack/demo/whois/main.c index 5283df86..52aa8557 100644 --- a/bacnet-stack/demo/whois/main.c +++ b/bacnet-stack/demo/whois/main.c @@ -87,7 +87,7 @@ static void Init_Service_Handlers( void) { /* Note: this applications doesn't need to handle who-is - it is confusing for the user! */ + it is confusing for the user! */ /* set the handler for all the services we don't implement It is required to send the proper reject message... */ apdu_set_unrecognized_service_handler_handler diff --git a/bacnet-stack/demo/whoisrouter/main.c b/bacnet-stack/demo/whoisrouter/main.c index 8afe1469..f4aed0c1 100644 --- a/bacnet-stack/demo/whoisrouter/main.c +++ b/bacnet-stack/demo/whoisrouter/main.c @@ -86,9 +86,9 @@ static void MyRejectHandler( } static void My_Router_Handler( - BACNET_ADDRESS *src, - BACNET_NPDU_DATA *npdu_data, - uint8_t * npdu, /* PDU data */ + BACNET_ADDRESS * src, + BACNET_NPDU_DATA * npdu_data, + uint8_t * npdu, /* PDU data */ uint16_t npdu_len) { uint16_t npdu_offset = 0; @@ -109,7 +109,7 @@ static void My_Router_Handler( printf("\nNetworks: "); while (npdu_len) { len = decode_unsigned16(&npdu[npdu_offset], &dnet); - printf("%hu",dnet); + printf("%hu", dnet); npdu_len -= len; if (npdu_len) { printf(", "); @@ -141,7 +141,7 @@ void My_NPDU_Handler( apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data); if (npdu_data.network_layer_message) { - My_Router_Handler(src,&npdu_data,&pdu[apdu_offset], + My_Router_Handler(src, &npdu_data, &pdu[apdu_offset], (uint16_t) (pdu_len - apdu_offset)); } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && diff --git a/bacnet-stack/include/bacdcode.h b/bacnet-stack/include/bacdcode.h index 374d2e05..2b88e01f 100644 --- a/bacnet-stack/include/bacdcode.h +++ b/bacnet-stack/include/bacdcode.h @@ -112,10 +112,10 @@ extern "C" { bool decode_context_boolean( uint8_t * apdu); - int decode_context_boolean2( - uint8_t * apdu, - uint8_t tag_number, - bool *boolean_value); + int decode_context_boolean2( + uint8_t * apdu, + uint8_t tag_number, + bool * boolean_value); /* from clause 20.2.10 Encoding of a Bit String Value */ /* returns the number of apdu bytes consumed */ @@ -126,7 +126,7 @@ extern "C" { int decode_context_bitstring( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_BIT_STRING * bit_string); /* returns the number of apdu bytes consumed */ int encode_bitstring( @@ -154,15 +154,15 @@ extern "C" { /* from clause 20.2.7 Encoding of a Double Precision Real Number Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ -int encode_application_double( - uint8_t * apdu, - double value); - -int encode_context_double( - uint8_t * apdu, - int tag_number, - double value); - + int encode_application_double( + uint8_t * apdu, + double value); + + int encode_context_double( + uint8_t * apdu, + int tag_number, + double value); + /* from clause 20.2.14 Encoding of an Object Identifier Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ /* returns the number of apdu bytes consumed */ @@ -171,11 +171,11 @@ int encode_context_double( uint16_t * object_type, uint32_t * instance); - int decode_context_object_id( - uint8_t * apdu, - uint8_t tag_number, - uint16_t *object_type, - uint32_t * instance); + int decode_context_object_id( + uint8_t * apdu, + uint8_t tag_number, + uint16_t * object_type, + uint32_t * instance); int encode_bacnet_object_id( uint8_t * apdu, @@ -210,7 +210,7 @@ int encode_context_double( BACNET_OCTET_STRING * octet_string); int decode_context_octet_string( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_OCTET_STRING * octet_string); @@ -231,10 +231,10 @@ int encode_context_double( uint8_t * apdu, uint32_t len_value, BACNET_CHARACTER_STRING * char_string); - int decode_context_character_string( - uint8_t * apdu, - uint8_t tag_number, - BACNET_CHARACTER_STRING * char_string); + int decode_context_character_string( + uint8_t * apdu, + uint8_t tag_number, + BACNET_CHARACTER_STRING * char_string); /* from clause 20.2.4 Encoding of an Unsigned Integer Value */ @@ -254,10 +254,10 @@ int encode_context_double( uint8_t * apdu, uint32_t len_value, uint32_t * value); - int decode_context_unsigned( - uint8_t * apdu, - uint8_t tag_number, - uint32_t * value); + int decode_context_unsigned( + uint8_t * apdu, + uint8_t tag_number, + uint32_t * value); /* from clause 20.2.5 Encoding of a Signed Integer Value */ /* and 20.2.1 General Rules for Encoding BACnet Tags */ @@ -276,10 +276,10 @@ int encode_context_double( uint8_t * apdu, uint32_t len_value, int32_t * value); - int decode_context_signed( - uint8_t * apdu, - uint8_t tag_number, - int32_t * value); + int decode_context_signed( + uint8_t * apdu, + uint8_t tag_number, + int32_t * value); /* from clause 20.2.11 Encoding of an Enumerated Value */ @@ -289,10 +289,10 @@ int encode_context_double( uint8_t * apdu, uint32_t len_value, int *value); - int decode_context_enumerated( - uint8_t * apdu, - uint8_t tag_value, - int *value); + int decode_context_enumerated( + uint8_t * apdu, + uint8_t tag_value, + int *value); int encode_bacnet_enumerated( uint8_t * apdu, int value); @@ -320,13 +320,13 @@ int encode_context_double( uint8_t * apdu, int tag_number, BACNET_TIME * btime); - int decode_application_time( - uint8_t * apdu, - BACNET_TIME * btime); - int decode_context_bacnet_time( - uint8_t * apdu, - uint8_t tag_number, - BACNET_TIME * btime); + int decode_application_time( + uint8_t * apdu, + BACNET_TIME * btime); + int decode_context_bacnet_time( + uint8_t * apdu, + uint8_t tag_number, + BACNET_TIME * btime); /* BACnet Date */ @@ -354,10 +354,10 @@ int encode_context_double( int decode_application_date( uint8_t * apdu, BACNET_DATE * bdate); - int decode_context_date( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DATE * bdate); + int decode_context_date( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DATE * bdate); /* from clause 20.1.2.4 max-segments-accepted */ /* and clause 20.1.2.5 max-APDU-length-accepted */ diff --git a/bacnet-stack/include/bacdevobjpropref.h b/bacnet-stack/include/bacdevobjpropref.h index 4ad2bb7c..f0e49441 100644 --- a/bacnet-stack/include/bacdevobjpropref.h +++ b/bacnet-stack/include/bacdevobjpropref.h @@ -1,75 +1,72 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef _BAC_DEV_PROP_REF_H_ -#define _BAC_DEV_PROP_REF_H_ - - -typedef struct { - BACNET_OBJECT_ID objectIdentifier; - BACNET_PROPERTY_ID propertyIdentifier; - uint32_t arrayIndex; - BACNET_OBJECT_ID deviceIndentifier; -} BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -int bacapp_encode_device_obj_property_ref( - uint8_t * apdu, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); - -int bacapp_encode_context_device_obj_property_ref( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); - -int bacapp_decode_device_obj_property_ref( - uint8_t * apdu, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); - -int bacapp_decode_context_device_obj_property_ref( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif //_BAC_DEV_PROP_REF_H_ - +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#ifndef _BAC_DEV_PROP_REF_H_ +#define _BAC_DEV_PROP_REF_H_ + + +typedef struct { + BACNET_OBJECT_ID objectIdentifier; + BACNET_PROPERTY_ID propertyIdentifier; + uint32_t arrayIndex; + BACNET_OBJECT_ID deviceIndentifier; +} BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE; + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int bacapp_encode_device_obj_property_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); + + int bacapp_encode_context_device_obj_property_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); + + int bacapp_decode_device_obj_property_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); + + int bacapp_decode_context_device_obj_property_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif //_BAC_DEV_PROP_REF_H_ diff --git a/bacnet-stack/include/bacpropstates.h b/bacnet-stack/include/bacpropstates.h index 38fb1abe..b5d4057c 100644 --- a/bacnet-stack/include/bacpropstates.h +++ b/bacnet-stack/include/bacpropstates.h @@ -1,104 +1,102 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef _BAC_PROP_STATES_H_ -#define _BAC_PROP_STATES_H_ - -#include "bacenum.h" -#include -#include -#include "bacapp.h" -#include -#include "timestamp.h" - -typedef enum { - BOOLEAN_VALUE, - BINARY_VALUE, - EVENT_TYPE, - POLARITY, - PROGRAM_CHANGE, - PROGRAM_STATE, - REASON_FOR_HALT, - RELIABILITY, - STATE, - SYSTEM_STATUS, - UNITS, - UNSIGNED_VALUE, - LIFE_SAFETY_MODE, - LIFE_SAFETY_STATE, -} BACNET_PROPERTY_STATE_TYPE; - -typedef struct { - BACNET_PROPERTY_STATE_TYPE tag; - union { - bool booleanValue; - BACNET_BINARY_PV binaryValue; - BACNET_EVENT_TYPE eventType; - BACNET_POLARITY polarity; - BACNET_PROGRAM_REQUEST programChange; - BACNET_PROGRAM_STATE programState; - BACNET_PROGRAM_ERROR programError; - BACNET_RELIABILITY reliability; - BACNET_EVENT_STATE state; - BACNET_DEVICE_STATUS systemStatus; - BACNET_ENGINEERING_UNITS units; - uint32_t unsignedValue; - BACNET_LIFE_SAFETY_MODE lifeSafetyMode; - BACNET_LIFE_SAFETY_STATE lifeSafetyState; - } state; -} BACNET_PROPERTY_STATE; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -int bacapp_decode_property_state( - uint8_t * apdu, - BACNET_PROPERTY_STATE * value); - -int bacapp_decode_context_property_state( - uint8_t * apdu, - uint8_t tag_number, - BACNET_PROPERTY_STATE * value); - -int bacapp_encode_property_state( - uint8_t * apdu, - BACNET_PROPERTY_STATE * value); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif // _BAC_PROP_STATES_H_ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#ifndef _BAC_PROP_STATES_H_ +#define _BAC_PROP_STATES_H_ + +#include "bacenum.h" +#include +#include +#include "bacapp.h" +#include +#include "timestamp.h" + +typedef enum { + BOOLEAN_VALUE, + BINARY_VALUE, + EVENT_TYPE, + POLARITY, + PROGRAM_CHANGE, + PROGRAM_STATE, + REASON_FOR_HALT, + RELIABILITY, + STATE, + SYSTEM_STATUS, + UNITS, + UNSIGNED_VALUE, + LIFE_SAFETY_MODE, + LIFE_SAFETY_STATE, +} BACNET_PROPERTY_STATE_TYPE; + +typedef struct { + BACNET_PROPERTY_STATE_TYPE tag; + union { + bool booleanValue; + BACNET_BINARY_PV binaryValue; + BACNET_EVENT_TYPE eventType; + BACNET_POLARITY polarity; + BACNET_PROGRAM_REQUEST programChange; + BACNET_PROGRAM_STATE programState; + BACNET_PROGRAM_ERROR programError; + BACNET_RELIABILITY reliability; + BACNET_EVENT_STATE state; + BACNET_DEVICE_STATUS systemStatus; + BACNET_ENGINEERING_UNITS units; + uint32_t unsignedValue; + BACNET_LIFE_SAFETY_MODE lifeSafetyMode; + BACNET_LIFE_SAFETY_STATE lifeSafetyState; + } state; +} BACNET_PROPERTY_STATE; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + int bacapp_decode_property_state( + uint8_t * apdu, + BACNET_PROPERTY_STATE * value); + + int bacapp_decode_context_property_state( + uint8_t * apdu, + uint8_t tag_number, + BACNET_PROPERTY_STATE * value); + + int bacapp_encode_property_state( + uint8_t * apdu, + BACNET_PROPERTY_STATE * value); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif // _BAC_PROP_STATES_H_ diff --git a/bacnet-stack/include/bacreal.h b/bacnet-stack/include/bacreal.h index a0081685..9323f61a 100644 --- a/bacnet-stack/include/bacreal.h +++ b/bacnet-stack/include/bacreal.h @@ -48,7 +48,7 @@ extern "C" { int decode_context_real( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, float *real_value); int encode_bacnet_real( float value, diff --git a/bacnet-stack/include/client.h b/bacnet-stack/include/client.h index 613e8db8..1b539531 100644 --- a/bacnet-stack/include/client.h +++ b/bacnet-stack/include/client.h @@ -78,8 +78,8 @@ extern "C" { uint8_t Send_Read_Property_Multiple_Request( uint8_t * pdu, size_t max_pdu, - uint32_t device_id, /* destination device */ - BACNET_READ_ACCESS_DATA *read_access_data); + uint32_t device_id, /* destination device */ + BACNET_READ_ACCESS_DATA * read_access_data); /* returns the invoke ID for confirmed request, or 0 if failed */ uint8_t Send_Write_Property_Request( diff --git a/bacnet-stack/include/datetime.h b/bacnet-stack/include/datetime.h index 491eb064..4f9d7311 100644 --- a/bacnet-stack/include/datetime.h +++ b/bacnet-stack/include/datetime.h @@ -138,19 +138,19 @@ extern "C" { void datetime_time_wildcard_set( BACNET_TIME * btime); - int bacapp_encode_context_datetime( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DATE_TIME * value); + int bacapp_encode_context_datetime( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DATE_TIME * value); - int bacapp_decode_datetime( - uint8_t * apdu, - BACNET_DATE_TIME * value); + int bacapp_decode_datetime( + uint8_t * apdu, + BACNET_DATE_TIME * value); - int bacapp_decode_context_datetime( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DATE_TIME * value); + int bacapp_decode_context_datetime( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DATE_TIME * value); #ifdef __cplusplus } diff --git a/bacnet-stack/include/debug.h b/bacnet-stack/include/debug.h index 2a7126f5..1362bb8f 100644 --- a/bacnet-stack/include/debug.h +++ b/bacnet-stack/include/debug.h @@ -38,26 +38,23 @@ #include #include #include "bacdef.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ #if DEBUG_ENABLED -void debug_printf( - const char *format, - ...); + void debug_printf( + const char *format, + ...); #else -static void debug_printf( - const char *format, - ...) -{ - format = format; + static void debug_printf( + const char *format, + ...) { + format = format; + } +#endif +#ifdef __cplusplus } -#endif - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +#endif /* __cplusplus */ #endif diff --git a/bacnet-stack/include/event.h b/bacnet-stack/include/event.h index 94cb1949..644a5856 100644 --- a/bacnet-stack/include/event.h +++ b/bacnet-stack/include/event.h @@ -1,212 +1,212 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef BACNET_EVENT_H_ -#define BACNET_EVENT_H_ - -#include "bacenum.h" -#include -#include -#include "bacapp.h" -#include "timestamp.h" -#include "bacpropstates.h" -#include "bacdevobjpropref.h" - -typedef enum { - CHANGE_OF_VALUE_BITS, - CHANGE_OF_VALUE_REAL -} CHANGE_OF_VALUE_TYPE; - -/* -** Based on UnconfirmedEventNotification-Request -*/ - -typedef struct BACnet_Event_Notification_Data { - uint32_t processIdentifier; - BACNET_OBJECT_ID initiatingObjectIdentifier; - BACNET_OBJECT_ID eventObjectIdentifier; - BACNET_TIMESTAMP timeStamp; - uint32_t notificationClass; - uint8_t priority; - BACNET_EVENT_TYPE eventType; - BACNET_CHARACTER_STRING* messageText; /* OPTIONAL - Set to NULL if not being used */ - BACNET_NOTIFY_TYPE notifyType; - bool ackRequired; - BACNET_EVENT_STATE fromState; - BACNET_EVENT_STATE toState; - /* - ** Each of these structures in the union maps to a particular eventtype - ** Based on BACnetNotificationParameters - */ - - union { - /* - ** EVENT_CHANGE_OF_BITSTRING - */ - struct { - BACNET_BIT_STRING referencedBitString; - BACNET_BIT_STRING statusFlags; - } changeOfBitstring; - /* - ** EVENT_CHANGE_OF_STATE - */ - struct { - BACNET_PROPERTY_STATE newState; - BACNET_BIT_STRING statusFlags; - } changeOfState; - /* - ** EVENT_CHANGE_OF_VALUE - */ - struct { - union { - BACNET_BIT_STRING changedBits; - float changeValue; - } newValue; - CHANGE_OF_VALUE_TYPE tag; - BACNET_BIT_STRING statusFlags; - } changeOfValue; - /* - ** EVENT_COMMAND_FAILURE - ** - ** Not Supported! - */ - /* - ** EVENT_FLOATING_LIMIT - */ - struct { - float referenceValue; - BACNET_BIT_STRING statusFlags; - float setPointValue; - float errorLimit; - } floatingLimit; - /* - ** EVENT_OUT_OF_RANGE - */ - struct { - float exceedingValue; - BACNET_BIT_STRING statusFlags; - float deadband; - float exceededLimit; - } outOfRange; - /* - ** EVENT_CHANGE_OF_LIFE_SAFETY - */ - struct { - BACNET_LIFE_SAFETY_STATE newState; - BACNET_LIFE_SAFETY_MODE newMode; - BACNET_BIT_STRING statusFlags; - BACNET_LIFE_SAFETY_OPERATION operationExpected; - } changeOfLifeSafety; - /* - ** EVENT_EXTENDED - ** - ** Not Supported! - */ - /* - ** EVENT_BUFFER_READY - */ - struct { - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE bufferProperty; - uint32_t previousNotification; - uint32_t currentNotification; - } bufferReady; - /* - ** EVENT_UNSIGNED_RANGE - */ - struct { - uint32_t exceedingValue; - BACNET_BIT_STRING statusFlags; - uint32_t exceededLimit; - } unsignedRange; - } notificationParams; -} BACNET_EVENT_NOTIFICATION_DATA; - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/*************************************************** -** -** Creates a Confirmed Event Notification APDU -** -****************************************************/ -int cevent_notify_encode_apdu( - uint8_t * apdu, - uint8_t invoke_id, - BACNET_EVENT_NOTIFICATION_DATA * data); - -/*************************************************** -** -** Creates an Unconfirmed Event Notification APDU -** -****************************************************/ -int uevent_notify_encode_apdu( - uint8_t * apdu, - BACNET_EVENT_NOTIFICATION_DATA * data); - -/*************************************************** -** -** Encodes the service data part of Event Notification -** -****************************************************/ -int event_notify_encode_service_request( - uint8_t * apdu, - BACNET_EVENT_NOTIFICATION_DATA * data); - -/*************************************************** -** -** Decodes the service data part of Event Notification -** -****************************************************/ -int event_notify_decode_service_request( - uint8_t * apdu, - unsigned apdu_len, - BACNET_EVENT_NOTIFICATION_DATA * data); - -/*************************************************** -** -** Sends an Unconfirmed Event Notifcation to a dest -** -****************************************************/ -int uevent_notify_send( - uint8_t * buffer, - BACNET_EVENT_NOTIFICATION_DATA * data, - BACNET_ADDRESS *dest); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* BACNET_EVENT_H_ */ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#ifndef BACNET_EVENT_H_ +#define BACNET_EVENT_H_ + +#include "bacenum.h" +#include +#include +#include "bacapp.h" +#include "timestamp.h" +#include "bacpropstates.h" +#include "bacdevobjpropref.h" + +typedef enum { + CHANGE_OF_VALUE_BITS, + CHANGE_OF_VALUE_REAL +} CHANGE_OF_VALUE_TYPE; + +/* +** Based on UnconfirmedEventNotification-Request +*/ + +typedef struct BACnet_Event_Notification_Data { + uint32_t processIdentifier; + BACNET_OBJECT_ID initiatingObjectIdentifier; + BACNET_OBJECT_ID eventObjectIdentifier; + BACNET_TIMESTAMP timeStamp; + uint32_t notificationClass; + uint8_t priority; + BACNET_EVENT_TYPE eventType; + BACNET_CHARACTER_STRING *messageText; /* OPTIONAL - Set to NULL if not being used */ + BACNET_NOTIFY_TYPE notifyType; + bool ackRequired; + BACNET_EVENT_STATE fromState; + BACNET_EVENT_STATE toState; + /* + ** Each of these structures in the union maps to a particular eventtype + ** Based on BACnetNotificationParameters + */ + + union { + /* + ** EVENT_CHANGE_OF_BITSTRING + */ + struct { + BACNET_BIT_STRING referencedBitString; + BACNET_BIT_STRING statusFlags; + } changeOfBitstring; + /* + ** EVENT_CHANGE_OF_STATE + */ + struct { + BACNET_PROPERTY_STATE newState; + BACNET_BIT_STRING statusFlags; + } changeOfState; + /* + ** EVENT_CHANGE_OF_VALUE + */ + struct { + union { + BACNET_BIT_STRING changedBits; + float changeValue; + } newValue; + CHANGE_OF_VALUE_TYPE tag; + BACNET_BIT_STRING statusFlags; + } changeOfValue; + /* + ** EVENT_COMMAND_FAILURE + ** + ** Not Supported! + */ + /* + ** EVENT_FLOATING_LIMIT + */ + struct { + float referenceValue; + BACNET_BIT_STRING statusFlags; + float setPointValue; + float errorLimit; + } floatingLimit; + /* + ** EVENT_OUT_OF_RANGE + */ + struct { + float exceedingValue; + BACNET_BIT_STRING statusFlags; + float deadband; + float exceededLimit; + } outOfRange; + /* + ** EVENT_CHANGE_OF_LIFE_SAFETY + */ + struct { + BACNET_LIFE_SAFETY_STATE newState; + BACNET_LIFE_SAFETY_MODE newMode; + BACNET_BIT_STRING statusFlags; + BACNET_LIFE_SAFETY_OPERATION operationExpected; + } changeOfLifeSafety; + /* + ** EVENT_EXTENDED + ** + ** Not Supported! + */ + /* + ** EVENT_BUFFER_READY + */ + struct { + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE bufferProperty; + uint32_t previousNotification; + uint32_t currentNotification; + } bufferReady; + /* + ** EVENT_UNSIGNED_RANGE + */ + struct { + uint32_t exceedingValue; + BACNET_BIT_STRING statusFlags; + uint32_t exceededLimit; + } unsignedRange; + } notificationParams; +} BACNET_EVENT_NOTIFICATION_DATA; + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/*************************************************** +** +** Creates a Confirmed Event Notification APDU +** +****************************************************/ + int cevent_notify_encode_apdu( + uint8_t * apdu, + uint8_t invoke_id, + BACNET_EVENT_NOTIFICATION_DATA * data); + +/*************************************************** +** +** Creates an Unconfirmed Event Notification APDU +** +****************************************************/ + int uevent_notify_encode_apdu( + uint8_t * apdu, + BACNET_EVENT_NOTIFICATION_DATA * data); + +/*************************************************** +** +** Encodes the service data part of Event Notification +** +****************************************************/ + int event_notify_encode_service_request( + uint8_t * apdu, + BACNET_EVENT_NOTIFICATION_DATA * data); + +/*************************************************** +** +** Decodes the service data part of Event Notification +** +****************************************************/ + int event_notify_decode_service_request( + uint8_t * apdu, + unsigned apdu_len, + BACNET_EVENT_NOTIFICATION_DATA * data); + +/*************************************************** +** +** Sends an Unconfirmed Event Notifcation to a dest +** +****************************************************/ + int uevent_notify_send( + uint8_t * buffer, + BACNET_EVENT_NOTIFICATION_DATA * data, + BACNET_ADDRESS * dest); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* BACNET_EVENT_H_ */ diff --git a/bacnet-stack/include/memcopy.h b/bacnet-stack/include/memcopy.h index 00690e40..8a4335bd 100644 --- a/bacnet-stack/include/memcopy.h +++ b/bacnet-stack/include/memcopy.h @@ -47,12 +47,12 @@ extern "C" { /* copy len bytes from src to offset of dest if there is enough space. */ /* returns 0 if there is not enough space, or the number of bytes copied. */ -size_t memcopy( - void * dest, - void * src, - size_t offset, /* where in dest to put the data */ - size_t len, /* amount of data to copy */ - size_t max); /* total size of destination */ + size_t memcopy( + void *dest, + void *src, + size_t offset, /* where in dest to put the data */ + size_t len, /* amount of data to copy */ + size_t max); /* total size of destination */ #ifdef __cplusplus } diff --git a/bacnet-stack/include/rpm.h b/bacnet-stack/include/rpm.h index 553d7d84..de09547c 100644 --- a/bacnet-stack/include/rpm.h +++ b/bacnet-stack/include/rpm.h @@ -82,7 +82,7 @@ extern "C" { uint8_t * apdu, size_t max_apdu, uint8_t invoke_id, - BACNET_READ_ACCESS_DATA *read_access_data); + BACNET_READ_ACCESS_DATA * read_access_data); /* decode the object portion of the service request only */ int rpm_decode_object_id( diff --git a/bacnet-stack/include/timestamp.h b/bacnet-stack/include/timestamp.h index 5894d85d..3e29bdcf 100644 --- a/bacnet-stack/include/timestamp.h +++ b/bacnet-stack/include/timestamp.h @@ -1,78 +1,76 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef _TIMESTAMP_H_ -#define _TIMESTAMP_H_ - -#include "bacdcode.h" - -typedef enum { - TIME_STAMP_TIME = 0, - TIME_STAMP_SEQUENCE = 1, - TIME_STAMP_DATETIME = 2, -} BACNET_TIMESTAMP_TAG; - -typedef uint8_t TYPE_BACNET_TIMESTAMP_TYPE; - -typedef struct { - TYPE_BACNET_TIMESTAMP_TYPE tag; - union { - BACNET_TIME time; - uint16_t sequenceNum; - BACNET_DATE_TIME dateTime; - } value; -} BACNET_TIMESTAMP; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - - -int bacapp_encode_context_timestamp( - uint8_t * apdu, - uint8_t tag_number, - BACNET_TIMESTAMP * value); - -int bacapp_decode_context_timestamp( - uint8_t * apdu, - uint8_t tag_number, - BACNET_TIMESTAMP * value); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#ifndef _TIMESTAMP_H_ +#define _TIMESTAMP_H_ + +#include "bacdcode.h" + +typedef enum { + TIME_STAMP_TIME = 0, + TIME_STAMP_SEQUENCE = 1, + TIME_STAMP_DATETIME = 2, +} BACNET_TIMESTAMP_TAG; + +typedef uint8_t TYPE_BACNET_TIMESTAMP_TYPE; + +typedef struct { + TYPE_BACNET_TIMESTAMP_TYPE tag; + union { + BACNET_TIME time; + uint16_t sequenceNum; + BACNET_DATE_TIME dateTime; + } value; +} BACNET_TIMESTAMP; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + + + int bacapp_encode_context_timestamp( + uint8_t * apdu, + uint8_t tag_number, + BACNET_TIMESTAMP * value); + + int bacapp_decode_context_timestamp( + uint8_t * apdu, + uint8_t tag_number, + BACNET_TIMESTAMP * value); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/lib/main.h b/bacnet-stack/lib/main.h index dfa3690f..672f6e09 100644 --- a/bacnet-stack/lib/main.h +++ b/bacnet-stack/lib/main.h @@ -1,18 +1,19 @@ -#ifndef __MAIN_H__ -#define __MAIN_H__ - -#include - -/* To use this exported function of dll, include this header - * in your project. - */ - -#ifdef BUILD_DLL - #define DLL_EXPORT __declspec(dllexport) -#else - #define DLL_EXPORT __declspec(dllimport) -#endif - -void DLL_EXPORT SomeFunction(const LPCSTR sometext); - -#endif // __MAIN_H__ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#include + +/* To use this exported function of dll, include this header + * in your project. + */ + +#ifdef BUILD_DLL +#define DLL_EXPORT __declspec(dllexport) +#else +#define DLL_EXPORT __declspec(dllimport) +#endif + +void DLL_EXPORT SomeFunction( + const LPCSTR sometext); + +#endif // __MAIN_H__ diff --git a/bacnet-stack/ports/atmega8/ai.c b/bacnet-stack/ports/atmega8/ai.c index 00d0933f..b32e3099 100644 --- a/bacnet-stack/ports/atmega8/ai.c +++ b/bacnet-stack/ports/atmega8/ai.c @@ -1,159 +1,159 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -/* Analog Input Objects customize for your use */ - -#include -#include -#include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "config.h" - -/* Analog Input = Photocell */ -#define MAX_ANALOG_INPUTS 9 -#if (MAX_ANALOG_INPUTS > 9) -#error Modify the Analog_Input_Name to handle multiple digits -#endif - -float Present_Value[MAX_ANALOG_INPUTS]; - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need validate that the */ -/* given instance exists */ -bool Analog_Input_Valid_Instance( - uint32_t object_instance) -{ - if (object_instance < MAX_ANALOG_INPUTS) - return true; - - return false; -} - -/* we simply have 0-n object instances. */ -unsigned Analog_Input_Count( - void) -{ - return MAX_ANALOG_INPUTS; -} - -/* we simply have 0-n object instances. */ -uint32_t Analog_Input_Index_To_Instance( - unsigned index) -{ - return index; -} - -/* we simply have 0-n object instances. */ -unsigned Analog_Input_Instance_To_Index( - uint32_t object_instance) -{ - return object_instance; -} - - -char *Analog_Input_Name( - uint32_t object_instance) -{ - static char text_string[5] = "AI-0"; /* okay for single thread */ - - if (object_instance < MAX_ANALOG_INPUTS) { - text_string[3] = '0' + (uint8_t) object_instance; - return text_string; - } - - return NULL; -} - -/* return apdu length, or -1 on error */ -/* assumption - object has already exists */ -int Analog_Input_Encode_Property_APDU( - uint8_t * apdu, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - int32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) -{ - int apdu_len = 0; /* return value */ - BACNET_BIT_STRING bit_string; - BACNET_CHARACTER_STRING char_string; - unsigned object_index; - - - (void) array_index; - switch (property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = - encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, - object_instance); - break; - /* note: Name and Description don't have to be the same. - You could make Description writable and different. - Note that Object-Name must be unique in this device */ - case PROP_OBJECT_NAME: - case PROP_DESCRIPTION: - characterstring_init_ansi(&char_string, - Analog_Input_Name(object_instance)); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_OBJECT_TYPE: - apdu_len = - encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); - break; - case PROP_PRESENT_VALUE: - object_index = Analog_Input_Instance_To_Index(object_instance); - apdu_len = - encode_application_real(&apdu[0], Present_Value[object_index]); - break; - case PROP_STATUS_FLAGS: - bitstring_init(&bit_string); - bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_EVENT_STATE: - apdu_len = - encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); - break; - case PROP_OUT_OF_SERVICE: - apdu_len = encode_application_boolean(&apdu[0], false); - break; - case PROP_UNITS: - apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); - break; - default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = -1; - break; - } - - return apdu_len; -} +/************************************************************************** +* +* Copyright (C) 2005 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* Analog Input Objects customize for your use */ + +#include +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "config.h" + +/* Analog Input = Photocell */ +#define MAX_ANALOG_INPUTS 9 +#if (MAX_ANALOG_INPUTS > 9) +#error Modify the Analog_Input_Name to handle multiple digits +#endif + +float Present_Value[MAX_ANALOG_INPUTS]; + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need validate that the */ +/* given instance exists */ +bool Analog_Input_Valid_Instance( + uint32_t object_instance) +{ + if (object_instance < MAX_ANALOG_INPUTS) + return true; + + return false; +} + +/* we simply have 0-n object instances. */ +unsigned Analog_Input_Count( + void) +{ + return MAX_ANALOG_INPUTS; +} + +/* we simply have 0-n object instances. */ +uint32_t Analog_Input_Index_To_Instance( + unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. */ +unsigned Analog_Input_Instance_To_Index( + uint32_t object_instance) +{ + return object_instance; +} + + +char *Analog_Input_Name( + uint32_t object_instance) +{ + static char text_string[5] = "AI-0"; /* okay for single thread */ + + if (object_instance < MAX_ANALOG_INPUTS) { + text_string[3] = '0' + (uint8_t) object_instance; + return text_string; + } + + return NULL; +} + +/* return apdu length, or -1 on error */ +/* assumption - object has already exists */ +int Analog_Input_Encode_Property_APDU( + uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + unsigned object_index; + + + (void) array_index; + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = + encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, + object_instance); + break; + /* note: Name and Description don't have to be the same. + You could make Description writable and different. + Note that Object-Name must be unique in this device */ + case PROP_OBJECT_NAME: + case PROP_DESCRIPTION: + characterstring_init_ansi(&char_string, + Analog_Input_Name(object_instance)); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = + encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); + break; + case PROP_PRESENT_VALUE: + object_index = Analog_Input_Instance_To_Index(object_instance); + apdu_len = + encode_application_real(&apdu[0], Present_Value[object_index]); + break; + case PROP_STATUS_FLAGS: + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = + encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_application_boolean(&apdu[0], false); + break; + case PROP_UNITS: + apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} diff --git a/bacnet-stack/ports/atmega8/apdu.c b/bacnet-stack/ports/atmega8/apdu.c index e0e2e5b6..5f31d046 100644 --- a/bacnet-stack/ports/atmega8/apdu.c +++ b/bacnet-stack/ports/atmega8/apdu.c @@ -1,123 +1,123 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2007 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include -#include -#include "bits.h" -#include "apdu.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "handlers.h" - -bool apdu_service_supported( - BACNET_SERVICES_SUPPORTED service_supported) -{ - bool status = false; - - if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) { - status = true; - } - - return status; -} - -uint16_t apdu_decode_confirmed_service_request( - uint8_t * apdu, /* APDU data */ - uint16_t apdu_len, - BACNET_CONFIRMED_SERVICE_DATA * service_data, - uint8_t * service_choice, - uint8_t ** service_request, - uint16_t * service_request_len) -{ - uint16_t len = 0; /* counts where we are in PDU */ - - service_data->segmented_message = (apdu[0] & BIT3) ? true : false; - service_data->more_follows = (apdu[0] & BIT2) ? true : false; - service_data->segmented_response_accepted = - (apdu[0] & BIT1) ? true : false; - service_data->max_segs = decode_max_segs(apdu[1]); - service_data->max_resp = decode_max_apdu(apdu[1]); - service_data->invoke_id = apdu[2]; - len = 3; - if (service_data->segmented_message) { - service_data->sequence_number = apdu[len++]; - service_data->proposed_window_number = apdu[len++]; - } - *service_choice = apdu[len++]; - *service_request = &apdu[len]; - *service_request_len = apdu_len - len; - - return len; -} - -void apdu_handler( - BACNET_ADDRESS * src, - uint8_t * apdu, /* APDU data */ - uint16_t apdu_len) -{ - BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; - uint8_t service_choice = 0; - uint8_t *service_request = NULL; - uint16_t service_request_len = 0; - uint16_t len = 0; /* counts where we are in PDU */ - - if (apdu) { - /* PDU Type */ - switch (apdu[0] & 0xF0) { - case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: - len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ - apdu_len, &service_data, &service_choice, &service_request, - &service_request_len); - if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { - handler_read_property(service_request, service_request_len, - src, &service_data); - } else { - handler_unrecognized_service(service_request, - service_request_len, src, &service_data); - } - break; - case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: - case PDU_TYPE_SIMPLE_ACK: - case PDU_TYPE_COMPLEX_ACK: - case PDU_TYPE_SEGMENT_ACK: - case PDU_TYPE_ERROR: - case PDU_TYPE_REJECT: - case PDU_TYPE_ABORT: - default: - break; - } - } - return; -} +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2007 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include +#include +#include "bits.h" +#include "apdu.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "handlers.h" + +bool apdu_service_supported( + BACNET_SERVICES_SUPPORTED service_supported) +{ + bool status = false; + + if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) { + status = true; + } + + return status; +} + +uint16_t apdu_decode_confirmed_service_request( + uint8_t * apdu, /* APDU data */ + uint16_t apdu_len, + BACNET_CONFIRMED_SERVICE_DATA * service_data, + uint8_t * service_choice, + uint8_t ** service_request, + uint16_t * service_request_len) +{ + uint16_t len = 0; /* counts where we are in PDU */ + + service_data->segmented_message = (apdu[0] & BIT3) ? true : false; + service_data->more_follows = (apdu[0] & BIT2) ? true : false; + service_data->segmented_response_accepted = + (apdu[0] & BIT1) ? true : false; + service_data->max_segs = decode_max_segs(apdu[1]); + service_data->max_resp = decode_max_apdu(apdu[1]); + service_data->invoke_id = apdu[2]; + len = 3; + if (service_data->segmented_message) { + service_data->sequence_number = apdu[len++]; + service_data->proposed_window_number = apdu[len++]; + } + *service_choice = apdu[len++]; + *service_request = &apdu[len]; + *service_request_len = apdu_len - len; + + return len; +} + +void apdu_handler( + BACNET_ADDRESS * src, + uint8_t * apdu, /* APDU data */ + uint16_t apdu_len) +{ + BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; + uint8_t service_choice = 0; + uint8_t *service_request = NULL; + uint16_t service_request_len = 0; + uint16_t len = 0; /* counts where we are in PDU */ + + if (apdu) { + /* PDU Type */ + switch (apdu[0] & 0xF0) { + case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: + len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ + apdu_len, &service_data, &service_choice, &service_request, + &service_request_len); + if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { + handler_read_property(service_request, service_request_len, + src, &service_data); + } else { + handler_unrecognized_service(service_request, + service_request_len, src, &service_data); + } + break; + case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: + case PDU_TYPE_SIMPLE_ACK: + case PDU_TYPE_COMPLEX_ACK: + case PDU_TYPE_SEGMENT_ACK: + case PDU_TYPE_ERROR: + case PDU_TYPE_REJECT: + case PDU_TYPE_ABORT: + default: + break; + } + } + return; +} diff --git a/bacnet-stack/ports/atmega8/av.c b/bacnet-stack/ports/atmega8/av.c index 14b3dc7a..ea088c58 100644 --- a/bacnet-stack/ports/atmega8/av.c +++ b/bacnet-stack/ports/atmega8/av.c @@ -1,253 +1,253 @@ -/************************************************************************** -* -* Copyright (C) 2006 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -/* Analog Value Objects - customize for your use */ - -#include -#include -#include "hardware.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacenum.h" -#include "bacapp.h" -#include "config.h" /* the custom stuff */ -#include "wp.h" -#include "av.h" - -#if (MAX_ANALOG_VALUES > 10) -#error Modify the Analog_Value_Name to handle multiple digits -#endif - -float AV_Present_Value[MAX_ANALOG_VALUES]; - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need validate that the */ -/* given instance exists */ -bool Analog_Value_Valid_Instance( - uint32_t object_instance) -{ - if (object_instance < MAX_ANALOG_VALUES) - return true; - - return false; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then count how many you have */ -unsigned Analog_Value_Count( - void) -{ - return MAX_ANALOG_VALUES; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need to return the instance */ -/* that correlates to the correct index */ -uint32_t Analog_Value_Index_To_Instance( - unsigned index) -{ - return index; -} - -/* we simply have 0-n object instances. Yours might be */ -/* more complex, and then you need to return the index */ -/* that correlates to the correct instance number */ -unsigned Analog_Value_Instance_To_Index( - uint32_t object_instance) -{ - return object_instance; -} - -/* note: the object name must be unique within this device */ -char *Analog_Value_Name( - uint32_t object_instance) -{ - static char text_string[5] = "AV-"; /* okay for single thread */ - - text_string[3] = '0' + (uint8_t) object_instance; - - return text_string; -} - -/* return apdu len, or -1 on error */ -int Analog_Value_Encode_Property_APDU( - uint8_t * apdu, - uint32_t object_instance, - BACNET_PROPERTY_ID property, - int32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) -{ - int apdu_len = 0; /* return value */ - BACNET_BIT_STRING bit_string; - BACNET_CHARACTER_STRING char_string; - unsigned object_index; - - switch (property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = - encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, - object_instance); - break; - case PROP_OBJECT_NAME: - characterstring_init_ansi(&char_string, - Analog_Value_Name(object_instance)); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_OBJECT_TYPE: - apdu_len = - encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); - break; - case PROP_PRESENT_VALUE: - object_index = Analog_Value_Instance_To_Index(object_instance); - apdu_len = - encode_application_real(&apdu[0], - AV_Present_Value[object_index]); - break; - case PROP_STATUS_FLAGS: - bitstring_init(&bit_string); - bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_EVENT_STATE: - apdu_len = - encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); - break; - case PROP_OUT_OF_SERVICE: - apdu_len = encode_application_boolean(&apdu[0], false); - break; - case PROP_UNITS: - apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); - break; - default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = -1; - break; - } - - return apdu_len; -} - -/* returns true if successful */ -bool Analog_Value_Write_Property( - BACNET_WRITE_PROPERTY_DATA * wp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) -{ - bool status = false; /* return value */ - unsigned int object_index = 0; - int len = 0; - BACNET_APPLICATION_DATA_VALUE value; - - if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNKNOWN_OBJECT; - return false; - } - /* decode the some of the request */ - len = - bacapp_decode_application_data(wp_data->application_data, - wp_data->application_data_len, &value); - /* FIXME: len < application_data_len: more data? */ - /* FIXME: len == 0: unable to decode? */ - switch (wp_data->object_property) { - case PROP_PRESENT_VALUE: - if (value.tag == BACNET_APPLICATION_TAG_REAL) { - object_index = - Analog_Value_Instance_To_Index(wp_data->object_instance); - AV_Present_Value[object_index] = value.type.Real; - status = true; - } else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_DATA_TYPE; - } - break; - default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - break; - } - - return status; -} - -#ifdef TEST -#include -#include -#include "ctest.h" - -void testAnalog_Value( - Test * pTest) -{ - uint8_t apdu[MAX_APDU] = { 0 }; - int len = 0; - uint32_t len_value = 0; - uint8_t tag_number = 0; - BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE; - uint32_t decoded_instance = 0; - uint32_t instance = 123; - BACNET_ERROR_CLASS error_class; - BACNET_ERROR_CODE error_code; - - len = - Analog_Value_Encode_Property_APDU(&apdu[0], instance, - PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); - ct_test(pTest, len != 0); - len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); - ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); - len = - decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance); - ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); - ct_test(pTest, decoded_instance == instance); - - return; -} - -#ifdef TEST_ANALOG_VALUE -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Analog Value", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testAnalog_Value); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} -#endif /* TEST_ANALOG_VALUE */ -#endif /* TEST */ +/************************************************************************** +* +* Copyright (C) 2006 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* Analog Value Objects - customize for your use */ + +#include +#include +#include "hardware.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacenum.h" +#include "bacapp.h" +#include "config.h" /* the custom stuff */ +#include "wp.h" +#include "av.h" + +#if (MAX_ANALOG_VALUES > 10) +#error Modify the Analog_Value_Name to handle multiple digits +#endif + +float AV_Present_Value[MAX_ANALOG_VALUES]; + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need validate that the */ +/* given instance exists */ +bool Analog_Value_Valid_Instance( + uint32_t object_instance) +{ + if (object_instance < MAX_ANALOG_VALUES) + return true; + + return false; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then count how many you have */ +unsigned Analog_Value_Count( + void) +{ + return MAX_ANALOG_VALUES; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the instance */ +/* that correlates to the correct index */ +uint32_t Analog_Value_Index_To_Instance( + unsigned index) +{ + return index; +} + +/* we simply have 0-n object instances. Yours might be */ +/* more complex, and then you need to return the index */ +/* that correlates to the correct instance number */ +unsigned Analog_Value_Instance_To_Index( + uint32_t object_instance) +{ + return object_instance; +} + +/* note: the object name must be unique within this device */ +char *Analog_Value_Name( + uint32_t object_instance) +{ + static char text_string[5] = "AV-"; /* okay for single thread */ + + text_string[3] = '0' + (uint8_t) object_instance; + + return text_string; +} + +/* return apdu len, or -1 on error */ +int Analog_Value_Encode_Property_APDU( + uint8_t * apdu, + uint32_t object_instance, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + int apdu_len = 0; /* return value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + unsigned object_index; + + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = + encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, + object_instance); + break; + case PROP_OBJECT_NAME: + characterstring_init_ansi(&char_string, + Analog_Value_Name(object_instance)); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = + encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); + break; + case PROP_PRESENT_VALUE: + object_index = Analog_Value_Instance_To_Index(object_instance); + apdu_len = + encode_application_real(&apdu[0], + AV_Present_Value[object_index]); + break; + case PROP_STATUS_FLAGS: + bitstring_init(&bit_string); + bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); + apdu_len = encode_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_EVENT_STATE: + apdu_len = + encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); + break; + case PROP_OUT_OF_SERVICE: + apdu_len = encode_application_boolean(&apdu[0], false); + break; + case PROP_UNITS: + apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} + +/* returns true if successful */ +bool Analog_Value_Write_Property( + BACNET_WRITE_PROPERTY_DATA * wp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + bool status = false; /* return value */ + unsigned int object_index = 0; + int len = 0; + BACNET_APPLICATION_DATA_VALUE value; + + if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNKNOWN_OBJECT; + return false; + } + /* decode the some of the request */ + len = + bacapp_decode_application_data(wp_data->application_data, + wp_data->application_data_len, &value); + /* FIXME: len < application_data_len: more data? */ + /* FIXME: len == 0: unable to decode? */ + switch (wp_data->object_property) { + case PROP_PRESENT_VALUE: + if (value.tag == BACNET_APPLICATION_TAG_REAL) { + object_index = + Analog_Value_Instance_To_Index(wp_data->object_instance); + AV_Present_Value[object_index] = value.type.Real; + status = true; + } else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_DATA_TYPE; + } + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_WRITE_ACCESS_DENIED; + break; + } + + return status; +} + +#ifdef TEST +#include +#include +#include "ctest.h" + +void testAnalog_Value( + Test * pTest) +{ + uint8_t apdu[MAX_APDU] = { 0 }; + int len = 0; + uint32_t len_value = 0; + uint8_t tag_number = 0; + BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE; + uint32_t decoded_instance = 0; + uint32_t instance = 123; + BACNET_ERROR_CLASS error_class; + BACNET_ERROR_CODE error_code; + + len = + Analog_Value_Encode_Property_APDU(&apdu[0], instance, + PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); + ct_test(pTest, len != 0); + len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); + ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); + len = + decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance); + ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); + ct_test(pTest, decoded_instance == instance); + + return; +} + +#ifdef TEST_ANALOG_VALUE +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Analog Value", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testAnalog_Value); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} +#endif /* TEST_ANALOG_VALUE */ +#endif /* TEST */ diff --git a/bacnet-stack/ports/atmega8/avr035.h b/bacnet-stack/ports/atmega8/avr035.h index 3e287aec..d53db995 100644 --- a/bacnet-stack/ports/atmega8/avr035.h +++ b/bacnet-stack/ports/atmega8/avr035.h @@ -1,18 +1,18 @@ -#ifndef AVR035_H -#define AVR035_H - -/* from AVR035: Efficient C Coding for AVR */ - -/* a=register, b=bit number to act upon */ -#define BIT_SET(a,b) ((a) |= (1<<(b))) -#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b))) -#define BIT_FLIP(a,b) ((a) ^= (1<<(b))) -#define BIT_CHECK(a,b) ((a) & (1<<(b))) - -/* x=target variable, y=mask */ -#define BITMASK_SET(x,y) ((x) |= (y)) -#define BITMASK_CLEAR(x,y) ((x) &= (~(y))) -#define BITMASK_FLIP(x,y) ((x) ^= (y)) -#define BITMASK_CHECK(x,y) ((x) & (y)) - -#endif +#ifndef AVR035_H +#define AVR035_H + +/* from AVR035: Efficient C Coding for AVR */ + +/* a=register, b=bit number to act upon */ +#define BIT_SET(a,b) ((a) |= (1<<(b))) +#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b))) +#define BIT_FLIP(a,b) ((a) ^= (1<<(b))) +#define BIT_CHECK(a,b) ((a) & (1<<(b))) + +/* x=target variable, y=mask */ +#define BITMASK_SET(x,y) ((x) |= (y)) +#define BITMASK_CLEAR(x,y) ((x) &= (~(y))) +#define BITMASK_FLIP(x,y) ((x) ^= (y)) +#define BITMASK_CHECK(x,y) ((x) & (y)) + +#endif diff --git a/bacnet-stack/ports/atmega8/device.c b/bacnet-stack/ports/atmega8/device.c index 28246d85..bbf7272b 100644 --- a/bacnet-stack/ports/atmega8/device.c +++ b/bacnet-stack/ports/atmega8/device.c @@ -1,331 +1,330 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#include -#include -#include "bacdef.h" -#include "bacdcode.h" -#include "bacstr.h" -#include "bacenum.h" -#include "apdu.h" -#include "dcc.h" -#include "dlmstp.h" -#include "rs485.h" -#include "version.h" -/* objects */ -#include "device.h" -#include "av.h" - -/* note: you really only need to define variables for - properties that are writable or that may change. - The properties that are constant can be hard coded - into the read-property encoding. */ -static uint32_t Object_Instance_Number = 260001; -static char *Object_Name = "My Device"; -static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; - -void Device_Init( - void) -{ - /* Reinitialize_State = REINITIALIZED_STATE_IDLE; */ - /* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */ - /* FIXME: Get the data from the eeprom */ - /* I2C_Read_Block(EEPROM_DEVICE_ADDRESS, - (char *)&Object_Instance_Number, - sizeof(Object_Instance_Number), - EEPROM_BACNET_ID_ADDR); */ -} - -/* methods to manipulate the data */ -uint32_t Device_Object_Instance_Number( - void) -{ - return Object_Instance_Number; -} - -bool Device_Set_Object_Instance_Number( - uint32_t object_id) -{ - bool status = true; /* return value */ - - if (object_id <= BACNET_MAX_INSTANCE) { - Object_Instance_Number = object_id; - /* FIXME: Write the data to the eeprom */ - /* I2C_Write_Block( - EEPROM_DEVICE_ADDRESS, - (char *)&Object_Instance_Number, - sizeof(Object_Instance_Number), - EEPROM_BACNET_ID_ADDR); */ - } else - status = false; - - return status; -} - -bool Device_Valid_Object_Instance_Number( - uint32_t object_id) -{ - /* BACnet allows for a wildcard instance number */ - return ((Object_Instance_Number == object_id) || - (object_id == BACNET_MAX_INSTANCE)); -} - -uint16_t Device_Vendor_Identifier( - void) -{ - return BACNET_VENDOR_ID; -} - -unsigned Device_Object_List_Count( - void) -{ - unsigned count = 1; /* at least 1 for device object */ - -#if MAX_ANALOG_VALUES - /* FIXME: add objects as needed */ - count += Analog_Value_Count(); -#endif -#if MAX_BINARY_VALUES - /* FIXME: add objects as needed */ - count += Binary_Value_Count(); -#endif - - return count; -} - -bool Device_Object_List_Identifier( - unsigned array_index, - int *object_type, - uint32_t * instance) -{ - bool status = false; - unsigned object_index = 0; - unsigned object_count = 0; - - /* device object */ - if (array_index == 1) { - *object_type = OBJECT_DEVICE; - *instance = Object_Instance_Number; - status = true; - } - /* normalize the index since - we know it is not the previous objects */ - /* array index starts at 1 */ - object_index = array_index - 1; - /* 1 for the device object */ - object_count = 1; - /* FIXME: add objects as needed */ -#if MAX_ANALOG_VALUES - /* analog value objects */ - if (!status) { - /* array index starts at 1, and 1 for the device object */ - object_index -= object_count; - object_count = Analog_Value_Count(); - if (object_index < object_count) { - *object_type = OBJECT_ANALOG_VALUE; - *instance = Analog_Value_Index_To_Instance(object_index); - status = true; - } - } -#endif -#if MAX_BINARY_VALUES - /* binary value objects */ - if (!status) { - object_index -= object_count; - object_count = Binary_Value_Count(); - /* is it a valid index for this object? */ - if (object_index < object_count) { - *object_type = OBJECT_BINARY_VALUE; - *instance = Binary_Value_Index_To_Instance(object_index); - status = true; - } - } -#endif - - return status; -} - -/* return the length of the apdu encoded or -1 for error */ -int Device_Encode_Property_APDU( - uint8_t * apdu, - BACNET_PROPERTY_ID property, - int32_t array_index, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) -{ - int apdu_len = 0; /* return value */ - int len = 0; /* apdu len intermediate value */ - BACNET_BIT_STRING bit_string; - BACNET_CHARACTER_STRING char_string; - unsigned i = 0; - int object_type = 0; - uint32_t instance = 0; - unsigned count = 0; - - /* FIXME: change the hardcoded names to suit your application */ - switch (property) { - case PROP_OBJECT_IDENTIFIER: - apdu_len = - encode_application_object_id(&apdu[0], OBJECT_DEVICE, - Object_Instance_Number); - break; - case PROP_OBJECT_NAME: - characterstring_init_ansi(&char_string, Object_Name); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_OBJECT_TYPE: - apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE); - break; - case PROP_SYSTEM_STATUS: - apdu_len = encode_application_enumerated(&apdu[0], System_Status); - break; - case PROP_VENDOR_NAME: - characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_VENDOR_IDENTIFIER: - apdu_len = - encode_application_unsigned(&apdu[0], - Device_Vendor_Identifier()); - break; - case PROP_MODEL_NAME: - characterstring_init_ansi(&char_string, "GNU Demo"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_FIRMWARE_REVISION: - characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_APPLICATION_SOFTWARE_VERSION: - characterstring_init_ansi(&char_string, "1.0"); - apdu_len = - encode_application_character_string(&apdu[0], &char_string); - break; - case PROP_PROTOCOL_VERSION: - apdu_len = encode_application_unsigned(&apdu[0], 1); - break; - case PROP_PROTOCOL_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], 5); - break; - case PROP_PROTOCOL_SERVICES_SUPPORTED: - /* Note: list of services that are executed, not initiated. */ - bitstring_init(&bit_string); - for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { - /* automatic lookup based on handlers set */ - bitstring_set_bit(&bit_string, (uint8_t) i, - apdu_service_supported((BACNET_SERVICES_SUPPORTED) i)); - } - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: - /* Note: this is the list of objects that can be in this device, - not a list of objects that this device can access */ - bitstring_init(&bit_string); - /* must have the bit string as big as it can be */ - for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { - /* initialize all the object types to not-supported */ - bitstring_set_bit(&bit_string, (uint8_t) i, false); - } - /* FIXME: indicate the objects that YOU support */ - bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); -#if MAX_ANALOG_VALUES - bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); -#endif -#if MAX_BINARY_VALUES - bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); -#endif - apdu_len = encode_application_bitstring(&apdu[0], &bit_string); - break; - case PROP_OBJECT_LIST: - count = Device_Object_List_Count(); - /* Array element zero is the number of objects in the list */ - if (array_index == 0) - apdu_len = encode_application_unsigned(&apdu[0], count); - /* if no index was specified, then try to encode the entire list */ - /* into one packet. Note that more than likely you will have */ - /* to return an error if the number of encoded objects exceeds */ - /* your maximum APDU size. */ - else if (array_index == BACNET_ARRAY_ALL) { - for (i = 1; i <= count; i++) { - Device_Object_List_Identifier(i, &object_type, &instance); - len = - encode_application_object_id(&apdu[apdu_len], - object_type, instance); - apdu_len += len; - /* assume next one is the same size as this one */ - /* can we all fit into the APDU? */ - if ((apdu_len + len) >= MAX_APDU) { - *error_class = ERROR_CLASS_SERVICES; - *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; - apdu_len = -1; - break; - } - } - } else { - if (Device_Object_List_Identifier(array_index, &object_type, - &instance)) - apdu_len = - encode_application_object_id(&apdu[0], object_type, - instance); - else { - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; - apdu_len = -1; - } - } - break; - case PROP_MAX_APDU_LENGTH_ACCEPTED: - apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); - break; - case PROP_SEGMENTATION_SUPPORTED: - apdu_len = - encode_application_enumerated(&apdu[0], SEGMENTATION_NONE); - break; - case PROP_APDU_TIMEOUT: - apdu_len = encode_application_unsigned(&apdu[0], 60000); - break; - case PROP_NUMBER_OF_APDU_RETRIES: - apdu_len = encode_application_unsigned(&apdu[0], 0); - break; - case PROP_DEVICE_ADDRESS_BINDING: - /* FIXME: encode the list here, if it exists */ - break; - case PROP_DATABASE_REVISION: - apdu_len = encode_application_unsigned(&apdu[0], 0); - break; - default: - *error_class = ERROR_CLASS_PROPERTY; - *error_code = ERROR_CODE_UNKNOWN_PROPERTY; - apdu_len = -1; - break; - } - - return apdu_len; -} - +/************************************************************************** +* +* Copyright (C) 2007 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +#include +#include +#include "bacdef.h" +#include "bacdcode.h" +#include "bacstr.h" +#include "bacenum.h" +#include "apdu.h" +#include "dcc.h" +#include "dlmstp.h" +#include "rs485.h" +#include "version.h" +/* objects */ +#include "device.h" +#include "av.h" + +/* note: you really only need to define variables for + properties that are writable or that may change. + The properties that are constant can be hard coded + into the read-property encoding. */ +static uint32_t Object_Instance_Number = 260001; +static char *Object_Name = "My Device"; +static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; + +void Device_Init( + void) +{ + /* Reinitialize_State = REINITIALIZED_STATE_IDLE; */ + /* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */ + /* FIXME: Get the data from the eeprom */ + /* I2C_Read_Block(EEPROM_DEVICE_ADDRESS, + (char *)&Object_Instance_Number, + sizeof(Object_Instance_Number), + EEPROM_BACNET_ID_ADDR); */ +} + +/* methods to manipulate the data */ +uint32_t Device_Object_Instance_Number( + void) +{ + return Object_Instance_Number; +} + +bool Device_Set_Object_Instance_Number( + uint32_t object_id) +{ + bool status = true; /* return value */ + + if (object_id <= BACNET_MAX_INSTANCE) { + Object_Instance_Number = object_id; + /* FIXME: Write the data to the eeprom */ + /* I2C_Write_Block( + EEPROM_DEVICE_ADDRESS, + (char *)&Object_Instance_Number, + sizeof(Object_Instance_Number), + EEPROM_BACNET_ID_ADDR); */ + } else + status = false; + + return status; +} + +bool Device_Valid_Object_Instance_Number( + uint32_t object_id) +{ + /* BACnet allows for a wildcard instance number */ + return ((Object_Instance_Number == object_id) || + (object_id == BACNET_MAX_INSTANCE)); +} + +uint16_t Device_Vendor_Identifier( + void) +{ + return BACNET_VENDOR_ID; +} + +unsigned Device_Object_List_Count( + void) +{ + unsigned count = 1; /* at least 1 for device object */ + +#if MAX_ANALOG_VALUES + /* FIXME: add objects as needed */ + count += Analog_Value_Count(); +#endif +#if MAX_BINARY_VALUES + /* FIXME: add objects as needed */ + count += Binary_Value_Count(); +#endif + + return count; +} + +bool Device_Object_List_Identifier( + unsigned array_index, + int *object_type, + uint32_t * instance) +{ + bool status = false; + unsigned object_index = 0; + unsigned object_count = 0; + + /* device object */ + if (array_index == 1) { + *object_type = OBJECT_DEVICE; + *instance = Object_Instance_Number; + status = true; + } + /* normalize the index since + we know it is not the previous objects */ + /* array index starts at 1 */ + object_index = array_index - 1; + /* 1 for the device object */ + object_count = 1; + /* FIXME: add objects as needed */ +#if MAX_ANALOG_VALUES + /* analog value objects */ + if (!status) { + /* array index starts at 1, and 1 for the device object */ + object_index -= object_count; + object_count = Analog_Value_Count(); + if (object_index < object_count) { + *object_type = OBJECT_ANALOG_VALUE; + *instance = Analog_Value_Index_To_Instance(object_index); + status = true; + } + } +#endif +#if MAX_BINARY_VALUES + /* binary value objects */ + if (!status) { + object_index -= object_count; + object_count = Binary_Value_Count(); + /* is it a valid index for this object? */ + if (object_index < object_count) { + *object_type = OBJECT_BINARY_VALUE; + *instance = Binary_Value_Index_To_Instance(object_index); + status = true; + } + } +#endif + + return status; +} + +/* return the length of the apdu encoded or -1 for error */ +int Device_Encode_Property_APDU( + uint8_t * apdu, + BACNET_PROPERTY_ID property, + int32_t array_index, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + int apdu_len = 0; /* return value */ + int len = 0; /* apdu len intermediate value */ + BACNET_BIT_STRING bit_string; + BACNET_CHARACTER_STRING char_string; + unsigned i = 0; + int object_type = 0; + uint32_t instance = 0; + unsigned count = 0; + + /* FIXME: change the hardcoded names to suit your application */ + switch (property) { + case PROP_OBJECT_IDENTIFIER: + apdu_len = + encode_application_object_id(&apdu[0], OBJECT_DEVICE, + Object_Instance_Number); + break; + case PROP_OBJECT_NAME: + characterstring_init_ansi(&char_string, Object_Name); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_OBJECT_TYPE: + apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE); + break; + case PROP_SYSTEM_STATUS: + apdu_len = encode_application_enumerated(&apdu[0], System_Status); + break; + case PROP_VENDOR_NAME: + characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_VENDOR_IDENTIFIER: + apdu_len = + encode_application_unsigned(&apdu[0], + Device_Vendor_Identifier()); + break; + case PROP_MODEL_NAME: + characterstring_init_ansi(&char_string, "GNU Demo"); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_FIRMWARE_REVISION: + characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_APPLICATION_SOFTWARE_VERSION: + characterstring_init_ansi(&char_string, "1.0"); + apdu_len = + encode_application_character_string(&apdu[0], &char_string); + break; + case PROP_PROTOCOL_VERSION: + apdu_len = encode_application_unsigned(&apdu[0], 1); + break; + case PROP_PROTOCOL_REVISION: + apdu_len = encode_application_unsigned(&apdu[0], 5); + break; + case PROP_PROTOCOL_SERVICES_SUPPORTED: + /* Note: list of services that are executed, not initiated. */ + bitstring_init(&bit_string); + for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { + /* automatic lookup based on handlers set */ + bitstring_set_bit(&bit_string, (uint8_t) i, + apdu_service_supported((BACNET_SERVICES_SUPPORTED) i)); + } + apdu_len = encode_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: + /* Note: this is the list of objects that can be in this device, + not a list of objects that this device can access */ + bitstring_init(&bit_string); + /* must have the bit string as big as it can be */ + for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { + /* initialize all the object types to not-supported */ + bitstring_set_bit(&bit_string, (uint8_t) i, false); + } + /* FIXME: indicate the objects that YOU support */ + bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); +#if MAX_ANALOG_VALUES + bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); +#endif +#if MAX_BINARY_VALUES + bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); +#endif + apdu_len = encode_application_bitstring(&apdu[0], &bit_string); + break; + case PROP_OBJECT_LIST: + count = Device_Object_List_Count(); + /* Array element zero is the number of objects in the list */ + if (array_index == 0) + apdu_len = encode_application_unsigned(&apdu[0], count); + /* if no index was specified, then try to encode the entire list */ + /* into one packet. Note that more than likely you will have */ + /* to return an error if the number of encoded objects exceeds */ + /* your maximum APDU size. */ + else if (array_index == BACNET_ARRAY_ALL) { + for (i = 1; i <= count; i++) { + Device_Object_List_Identifier(i, &object_type, &instance); + len = + encode_application_object_id(&apdu[apdu_len], + object_type, instance); + apdu_len += len; + /* assume next one is the same size as this one */ + /* can we all fit into the APDU? */ + if ((apdu_len + len) >= MAX_APDU) { + *error_class = ERROR_CLASS_SERVICES; + *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; + apdu_len = -1; + break; + } + } + } else { + if (Device_Object_List_Identifier(array_index, &object_type, + &instance)) + apdu_len = + encode_application_object_id(&apdu[0], object_type, + instance); + else { + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_INVALID_ARRAY_INDEX; + apdu_len = -1; + } + } + break; + case PROP_MAX_APDU_LENGTH_ACCEPTED: + apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); + break; + case PROP_SEGMENTATION_SUPPORTED: + apdu_len = + encode_application_enumerated(&apdu[0], SEGMENTATION_NONE); + break; + case PROP_APDU_TIMEOUT: + apdu_len = encode_application_unsigned(&apdu[0], 60000); + break; + case PROP_NUMBER_OF_APDU_RETRIES: + apdu_len = encode_application_unsigned(&apdu[0], 0); + break; + case PROP_DEVICE_ADDRESS_BINDING: + /* FIXME: encode the list here, if it exists */ + break; + case PROP_DATABASE_REVISION: + apdu_len = encode_application_unsigned(&apdu[0], 0); + break; + default: + *error_class = ERROR_CLASS_PROPERTY; + *error_code = ERROR_CODE_UNKNOWN_PROPERTY; + apdu_len = -1; + break; + } + + return apdu_len; +} diff --git a/bacnet-stack/ports/atmega8/dlmstp.c b/bacnet-stack/ports/atmega8/dlmstp.c index c3a19f62..d2fd094f 100644 --- a/bacnet-stack/ports/atmega8/dlmstp.c +++ b/bacnet-stack/ports/atmega8/dlmstp.c @@ -1,765 +1,770 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include -#include -#include -#include "bacdef.h" -#include "dlmstp.h" -#include "rs485.h" -#include "crc.h" -#include "npdu.h" -#include "bits.h" -#include "bacaddr.h" -#include "txbuf.h" - -/* This file has been customized for use with small microprocessors */ -/* Assumptions: - Only one slave node MS/TP datalink layer -*/ -#include "hardware.h" -#include "timer.h" - -/* The value 255 is used to denote broadcast when used as a */ -/* destination address but is not allowed as a value for a station. */ -/* Station addresses for master nodes can be 0-127. */ -/* Station addresses for slave nodes can be 127-254. */ -#define MSTP_BROADCAST_ADDRESS 255 - -/* MS/TP Frame Type */ -/* Frame Types 8 through 127 are reserved by ASHRAE. */ -#define FRAME_TYPE_TOKEN 0 -#define FRAME_TYPE_POLL_FOR_MASTER 1 -#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2 -#define FRAME_TYPE_TEST_REQUEST 3 -#define FRAME_TYPE_TEST_RESPONSE 4 -#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5 -#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6 -#define FRAME_TYPE_REPLY_POSTPONED 7 -/* Frame Types 128 through 255: Proprietary Frames */ -/* These frames are available to vendors as proprietary (non-BACnet) frames. */ -/* The first two octets of the Data field shall specify the unique vendor */ -/* identification code, most significant octet first, for the type of */ -/* vendor-proprietary frame to be conveyed. The length of the data portion */ -/* of a Proprietary frame shall be in the range of 2 to 501 octets. */ -#define FRAME_TYPE_PROPRIETARY_MIN 128 -#define FRAME_TYPE_PROPRIETARY_MAX 255 - -/* receive FSM states */ -typedef enum { - MSTP_RECEIVE_STATE_IDLE = 0, - MSTP_RECEIVE_STATE_PREAMBLE = 1, - MSTP_RECEIVE_STATE_HEADER = 2, - MSTP_RECEIVE_STATE_DATA = 3 -} MSTP_RECEIVE_STATE; - -/* The state of the Receive State Machine */ -static MSTP_RECEIVE_STATE Receive_State; -static struct mstp_flag_t { - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if an invalid or valid frame is received. */ - /* Set to FALSE by the main state machine. */ - unsigned ReceivedInvalidFrame:1; - unsigned ReceivedValidFrame:1; - /* A Boolean flag set TRUE by the datalink transmit if a - frame is pending */ - unsigned TransmitPacketPending:1; - /* A Boolean flag set TRUE by the datalink transmit if a - pending packet is DataExpectingReply */ - unsigned TransmitPacketDER:1; - /* A Boolean flag set TRUE by the datalink if a - packet has been received, but not processed. */ - unsigned ReceivePacketPending:1; -} MSTP_Flag; - -/* data passed to receive handler */ -struct mstp_packet_info_t -{ - /* A Boolean flag set to TRUE by the Receive State Machine */ - /* if a valid frame is received. */ - unsigned valid_frame:1; - /* preamble flags */ - unsigned preamble1:1; - unsigned preamble2:1; - uint8_t header[6]; /* buffer to put the header bytes */ - uint8_t *buffer; /* buffer to put the data */ - uint8_t buffer_len; /* buffer to put the data */ - uint8_t index; /* index into receive buffer */ -}; -static struct nitoo_packet_info_t MSTP_Receive_Packet; - -/* Used to store the data length of a received frame. */ -static uint16_t DataLength; -/* Used to store the destination address of a received frame. */ -static uint8_t DestinationAddress; -/* Used to store the frame type of a received frame. */ -static uint8_t FrameType; -/* An array of octets, used to store octets as they are received. */ -/* InputBuffer is indexed from 0 to InputBufferSize-1. */ -/* FIXME: assign this to an actual array of bytes! */ -/* Note: the buffer is designed as a pointer since some compilers - and microcontroller architectures have limits as to places to - hold contiguous memory. */ -static uint8_t *InputBuffer; -static uint16_t InputBufferSize; -/* Used to store the Source Address of a received frame. */ -static uint8_t SourceAddress; -/* "This Station," the MAC address of this node. TS is generally read from a */ -/* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */ -/* 0 to 254. The value 255 is used to denote broadcast when used as a */ -/* destination address but is not allowed as a value for TS. */ -static uint8_t This_Station; -/* An array of octets, used to store octets for transmitting */ -/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */ -/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */ -/* FIXME: assign this to an actual array of bytes! */ -/* Note: the buffer is designed as a pointer since some compilers - and microcontroller architectures have limits as to places to - hold contiguous memory. */ -static uint8_t *TransmitPacket; -static uint16_t TransmitPacketLen; -static uint8_t TransmitPacketDest; - -/* The minimum time without a DataAvailable or ReceiveError event within */ -/* a frame before a receiving node may discard the frame: 60 bit times. */ -/* (Implementations may use larger values for this timeout, */ -/* not to exceed 100 milliseconds.) */ -/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */ -/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */ -#define Tframe_abort 30 - -/* The maximum idle time a sending node may allow to elapse between octets */ -/* of a frame the node is transmitting: 20 bit times. */ -#define Tframe_gap 20 - -/* The maximum time a node may wait after reception of a frame that expects */ -/* a reply before sending the first octet of a reply or Reply Postponed */ -/* frame: 250 milliseconds. */ -#define Treply_delay 250 - -/* The width of the time slot within which a node may generate a token: */ -/* 10 milliseconds. */ -#define Tslot 10 - -/* The maximum time a node may wait after reception of the token or */ -/* a Poll For Master frame before sending the first octet of a frame: */ -/* 15 milliseconds. */ -#define Tusage_delay 15 - -/* we need to be able to increment without rolling over */ -#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} - -bool dlmstp_init( - char *ifname) -{ - ifname = ifname; - /* initialize hardware */ - RS485_Initialize(); - - return true; -} - -void dlmstp_cleanup( - void) -{ - /* nothing to do for static buffers */ -} - -void dlmstp_fill_bacnet_address( - BACNET_ADDRESS * src, - uint8_t mstp_address) -{ - int i = 0; - - if (mstp_address == MSTP_BROADCAST_ADDRESS) { - /* mac_len = 0 if broadcast address */ - src->mac_len = 0; - src->mac[0] = 0; - } else { - src->mac_len = 1; - src->mac[0] = mstp_address; - } - /* fill with 0's starting with index 1; index 0 filled above */ - for (i = 1; i < MAX_MAC_LEN; i++) { - src->mac[i] = 0; - } - src->net = 0; - src->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - src->adr[i] = 0; - } -} - -/* MS/TP Frame Format */ -/* All frames are of the following format: */ -/* */ -/* Preamble: two octet preamble: X`55', X`FF' */ -/* Frame Type: one octet */ -/* Destination Address: one octet address */ -/* Source Address: one octet address */ -/* Length: two octets, most significant octet first, of the Data field */ -/* Header CRC: one octet */ -/* Data: (present only if Length is non-zero) */ -/* Data CRC: (present only if Length is non-zero) two octets, */ -/* least significant octet first */ -/* (pad): (optional) at most one octet of padding: X'FF' */ -static void MSTP_Send_Frame( - uint8_t frame_type, /* type of frame to send - see defines */ - uint8_t destination, /* destination address */ - uint8_t source, /* source address */ - uint8_t * pdu, /* any data to be sent - may be null */ - uint16_t pdu_len) -{ /* number of bytes of data (up to 501) */ - uint8_t crc8 = 0xFF; /* used to calculate the crc value */ - uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */ - uint8_t buffer[8]; /* stores the header and crc */ - uint8_t datacrc[2]; /* stores the data crc */ - uint16_t i = 0; /* used to calculate CRC for data */ - - /* create the MS/TP header */ - buffer[0] = 0x55; - buffer[1] = 0xFF; - buffer[2] = frame_type; - crc8 = CRC_Calc_Header(buffer[2], crc8); - buffer[3] = destination; - crc8 = CRC_Calc_Header(buffer[3], crc8); - buffer[4] = source; - crc8 = CRC_Calc_Header(buffer[4], crc8); - buffer[5] = pdu_len / 256; - crc8 = CRC_Calc_Header(buffer[5], crc8); - buffer[6] = pdu_len % 256; - crc8 = CRC_Calc_Header(buffer[6], crc8); - buffer[7] = ~crc8; - if (pdu_len) { - /* calculate CRC for any data */ - for (i = 0; i < pdu_len; i++) { - crc16 = CRC_Calc_Data(pdu[i], crc16); - } - crc16 = ~crc16; - datacrc[0] = (crc16 & 0x00FF); - datacrc[1] = ((crc16 & 0xFF00) >> 8); - } - /* now transmit the frame */ - RS485_Turnaround_Delay(); - RS485_Transmitter_Enable(true); - RS485_Send_Data(buffer, 8); - /* send any data */ - if (pdu_len) { - RS485_Send_Data(pdu, pdu_len); - RS485_Send_Data(datacrc, 2); - } - RS485_Transmitter_Enable(false); -} - -#if 0 -/* return true if the packet is good. */ -/* note: buffer should include the CRC as the last byte */ -static bool crc_header_good(uint8_t *buffer, uint8_t len) -{ - uint8_t i; /* loop counter */ - uint8_t crc8 = 0xFF; /* loop counter */ - - for (i = 0; i < len; i++) { - crc8 = CRC_Calc_Header(buffer[i], crc8); - } - - return (crc8 == 0x55); -} - - -static void mstp_receive_handler(void) -{ - uint8_t data_register = 0; /* data from UART */ - - if (RS485_ReceiveError()) { - timer_silence_reset(); - } else if (RS485_DataAvailable(&data_register)) { - timer_silence_reset(); - if ((MSTP_Receive_Packet.preamble1 == false) && - (data_register == 0x55)) { - MSTP_Receive_Packet.preamble1 = true; - return; - } - if ((MSTP_Receive_Packet.preamble2 == false) && - (MSTP_Receive_Packet.preamble1 == true)) { - if (data_register == 0xFF) { - MSTP_Receive_Packet.preamble2 = true; - MSTP_Receive_Packet.index = 0; - MSTP_Receive_Packet.data_len = 0; - } else if (data_register == 0x55) { - /* repeated preamble1 */ - return; - } else { - MSTP_Receive_Packet.preamble1 = false; - } - return; - } - if (DataLength == 0) { - MSTP_Receive_Packet.header[MSTP_Receive_Packet.index] = data_register; - if (MSTP_Receive_Packet.index == 5) { - if (crc_header_good(MSTP_Receive_Packet.header, 6)) { - FrameType = MSTP_Receive_Packet.header[0]; - DestinationAddress = MSTP_Receive_Packet.header[1]; - SourceAddress = MSTP_Receive_Packet.header[2]; - DataLength = (MSTP_Receive_Packet.header[3] * 256) + - MSTP_Receive_Packet.header[4]; - if (DataLength == 0) { - MSTP_Receive_Packet.valid_frame = true; - } else { - MSTP_Receive_Packet.index = 0; - } - } else { - MSTP_Receive_Packet.preamble2 = false; - MSTP_Receive_Packet.preamble2 = false; - MSTP_Receive_Packet.index = 0; - } - } - } else { - MSTP_Receive_Packet.buffer[MSTP_Receive_Packet.index] = data_register; - if (packet_info->index == packet_info->len) { - /* PDU length ended */ - packet_info->ready = true; - } else if (packet_info->index >= sizeof(packet_info->buffer)){ - /* exceeded the size of the storage */ - packet_info->len = packet_info->index; - packet_info->ready = true; - } else { - packet_info->index++; - } - MSTP_Receive_Packet.index++; - if (packet_info->ready) { - /* validate the CRC */ - if (!lrc_packet_good(packet_info->buffer,packet_info->len+1)) { - packet_info->ready = false; - } - /* pull off the CRC */ - packet_info->crc = packet_info->buffer[packet_info->len]; - /* get ready for the next packet */ - packet_info->index = 0; - packet_info->preamble1 = false; - packet_info->preamble2 = false; - led_setup_off(); - } - } - } else { - if (ReceivePreamble1 == true) { - if (timer_silence_elapsed(Tframe_abort)) { - /* we've been busy too long! Abort packet! */ - Index = 0; - ReceivePreamble1 = false; - ReceivePreamble2 = false; - } - } - } -} -#endif - -static void MSTP_Receive_Frame_FSM( - void) -{ - /* stores the latest received data octet */ - uint8_t DataRegister = 0; - /* Used to accumulate the CRC on the data field of a frame. */ - static uint16_t DataCRC = 0; - /* Used to accumulate the CRC on the header of a frame. */ - static uint8_t HeaderCRC = 0; - /* Used as an index by the Receive State Machine, - up to a maximum value of the MPDU */ - static uint8_t Index = 0; - - switch (Receive_State) { - case MSTP_RECEIVE_STATE_IDLE: - /* In the IDLE state, the node waits for the beginning of a frame. */ - if (RS485_ReceiveError()) { - /* EatAnError */ - timer_silence_reset(); - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (DataRegister == 0x55) { - /* Preamble1 */ - /* receive the remainder of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; - } - } - break; - case MSTP_RECEIVE_STATE_PREAMBLE: - /* In the PREAMBLE state, the node waits for the - second octet of the preamble. */ - if (timer_silence_elapsed(Tframe_abort)) { - /* Timeout */ - /* a correct preamble has not been received */ - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - timer_silence_reset(); - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (DataRegister == 0xFF) { - /* Preamble2 */ - Index = 0; - HeaderCRC = 0xFF; - /* receive the remainder of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_HEADER; - } else if (DataRegister == 0x55) { - /* ignore RepeatedPreamble1 */ - /* wait for the second preamble octet. */ - Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; - } else { - /* NotPreamble */ - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - case MSTP_RECEIVE_STATE_HEADER: - /* In the HEADER state, the node waits for the fixed message header. */ - if (timer_silence_elapsed(Tframe_abort)) { - /* Timeout */ - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - timer_silence_reset(); - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (Index == 0) { - /* FrameType */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - FrameType = DataRegister; - Index = 1; - } else if (Index == 1) { - /* Destination */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DestinationAddress = DataRegister; - Index = 2; - } else if (Index == 2) { - /* Source */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - SourceAddress = DataRegister; - Index = 3; - } else if (Index == 3) { - /* Length1 */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DataLength = DataRegister * 256; - Index = 4; - } else if (Index == 4) { - /* Length2 */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - DataLength += DataRegister; - Index = 5; - } else if (Index == 5) { - /* HeaderCRC */ - HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); - /* In the HEADER_CRC state, the node validates the CRC - on the fixed message header. */ - if (HeaderCRC != 0x55) { - /* BadCRC */ - /* indicate that an error has occurred during - the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else { - /* Note: proposed change to BACnet MSTP state machine! - If we don't decode data that is not for us, we could - get confused about the start if the Preamble 55 FF - is part of the data. */ - if ((DataLength) && (DataLength <= InputBufferSize)) { - /* Data */ - Index = 0; - DataCRC = 0xFFFF; - /* receive the data portion of the frame. */ - Receive_State = MSTP_RECEIVE_STATE_DATA; - } else { - if (DataLength == 0) { - /* NoData */ - if ((DestinationAddress == This_Station) || - (DestinationAddress == - MSTP_BROADCAST_ADDRESS)) { - /* ForUs */ - /* indicate that a frame with - no data has been received */ - MSTP_Flag.ReceivedValidFrame = true; - } else { - /* NotForUs - drop */ - } - } else { - /* FrameTooLong */ - /* indicate that a frame with an illegal or */ - /* unacceptable data length has been received */ - MSTP_Flag.ReceivedInvalidFrame = true; - } - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - } else { - /* indicate that an error has occurred during */ - /* the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of a frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - case MSTP_RECEIVE_STATE_DATA: - /* In the DATA state, the node waits for the data portion of a frame. */ - if (timer_silence_elapsed(Tframe_abort)) { - /* Timeout */ - /* indicate that an error has occurred during the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_ReceiveError()) { - /* Error */ - timer_silence_reset(); - /* indicate that an error has occurred during - the reception of a frame */ - MSTP_Flag.ReceivedInvalidFrame = true; - /* wait for the start of the next frame. */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } else if (RS485_DataAvailable(&DataRegister)) { - timer_silence_reset(); - if (Index < DataLength) { - /* DataOctet */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - InputBuffer[Index] = DataRegister; - Index++; - } else if (Index == DataLength) { - /* CRC1 */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - Index++; - } else if (Index == (DataLength + 1)) { - /* CRC2 */ - DataCRC = CRC_Calc_Data(DataRegister, DataCRC); - /* STATE DATA CRC - no need for new state */ - /* indicate the complete reception of a valid frame */ - if (DataCRC == 0xF0B8) { - if ((DestinationAddress == This_Station) || - (DestinationAddress == MSTP_BROADCAST_ADDRESS)) { - /* ForUs */ - /* indicate that a frame with no data - has been received */ - MSTP_Flag.ReceivedValidFrame = true; - } - } else { - MSTP_Flag.ReceivedInvalidFrame = true; - } - Receive_State = MSTP_RECEIVE_STATE_IDLE; - } - } - break; - default: - /* shouldn't get here - but if we do... */ - Receive_State = MSTP_RECEIVE_STATE_IDLE; - break; - } - - return; -} - -static void MSTP_Slave_Node_FSM( - void) -{ - if (MSTP_Flag.ReceivedValidFrame) { - MSTP_Flag.ReceivedValidFrame = false; - switch (FrameType) { - case FRAME_TYPE_TOKEN: - break; - case FRAME_TYPE_POLL_FOR_MASTER: - break; - case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: - break; - case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: - /* indicate successful reception to the higher layers */ - MSTP_Flag.ReceivePacketPending = true; - break; - case FRAME_TYPE_TEST_REQUEST: - MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, - SourceAddress, This_Station, &InputBuffer[0], - DataLength); - break; - case FRAME_TYPE_TEST_RESPONSE: - default: - break; - } - } else if (MSTP_Flag.TransmitPacketPending) { - /* Reply */ - /* If a reply is available from the higher layers */ - /* within Treply_delay after the reception of the */ - /* final octet of the requesting frame */ - /* (the mechanism used to determine this is a local matter), */ - /* then call MSTP_Send_Frame to transmit the reply frame */ - /* and enter the IDLE state to wait for the next frame. */ - /* Note: optimized such that we are never a client */ - MSTP_Send_Frame(FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY, - TransmitPacketDest, This_Station, - (uint8_t *) & TransmitPacket[0], TransmitPacketLen); - MSTP_Flag.TransmitPacketPending = false; - MSTP_Flag.ReceivePacketPending = false; - } -} - -/* returns number of bytes sent on success, zero on failure */ -int dlmstp_send_pdu( - BACNET_ADDRESS * dest, /* destination address */ - BACNET_NPDU_DATA * npdu_data, /* network information */ - uint8_t * pdu, /* any data to be sent - may be null */ - unsigned pdu_len) -{ /* number of bytes of data */ - int bytes_sent = 0; - - if (MSTP_Flag.TransmitPacketPending == false) { - MSTP_Flag.TransmitPacketDER = npdu_data->data_expecting_reply; - TransmitPacket = pdu; - TransmitPacketLen = pdu_len; - bytes_sent = pdu_len; - TransmitPacketDest = dest->mac[0]; - MSTP_Flag.TransmitPacketPending = true; - } - - return bytes_sent; -} - -/* Return the length of the packet */ -uint16_t dlmstp_receive( - BACNET_ADDRESS * src, /* source address */ - uint8_t * pdu, /* PDU data */ - uint16_t max_pdu, /* amount of space available in the PDU */ - unsigned timeout) -{ /* milliseconds to wait for a packet */ - uint16_t pdu_len = 0; /* return value */ - - /* dummy - unused parameter */ - timeout = timeout; - /* set the input buffer to the same data storage for zero copy */ - if (!InputBuffer) { - InputBuffer = pdu; - InputBufferSize = max_pdu; - } - /* only do receive state machine while we don't have a frame */ - if ((MSTP_Flag.ReceivedValidFrame == false) && - (MSTP_Flag.ReceivedInvalidFrame == false) && - (MSTP_Flag.ReceivePacketPending == false)) { - for (;;) { - MSTP_Receive_Frame_FSM(); - if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame) - break; - /* if we are not idle, then we are - receiving a frame or timing out */ - if (Receive_State == MSTP_RECEIVE_STATE_IDLE) - break; - } - } - /* only do master state machine while rx is idle */ - if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { - MSTP_Slave_Node_FSM(); - } - /* if there is a packet that needs processed, do it now. */ - if (MSTP_Flag.ReceivePacketPending) { - MSTP_Flag.ReceivePacketPending = false; - pdu_len = DataLength; - src->mac_len = 1; - src->mac[0] = SourceAddress; - /* data is already in the pdu pointer */ - } - - return pdu_len; -} - -void dlmstp_set_mac_address( - uint8_t mac_address) -{ - /* Master Nodes can only have address 0-127 */ - if (mac_address <= 127) { - This_Station = mac_address; - /* FIXME: implement your data storage */ - /* I2C_Write_Byte( - EEPROM_DEVICE_ADDRESS, - mac_address, - EEPROM_MSTP_MAC_ADDR); */ - } - - return; -} - -uint8_t dlmstp_mac_address( - void) -{ - return This_Station; -} - -void dlmstp_get_my_address( - BACNET_ADDRESS * my_address) -{ - int i = 0; /* counter */ - - my_address->mac_len = 1; - my_address->mac[0] = This_Station; - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; - for (i = 0; i < MAX_MAC_LEN; i++) { - my_address->adr[i] = 0; - } - - return; -} - -void dlmstp_get_broadcast_address( - BACNET_ADDRESS * dest) -{ /* destination address */ - int i = 0; /* counter */ - - if (dest) { - dest->mac_len = 1; - dest->mac[0] = MSTP_BROADCAST_ADDRESS; - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* always zero when DNET is broadcast */ - for (i = 0; i < MAX_MAC_LEN; i++) { - dest->adr[i] = 0; - } - } - - return; -} +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307 + USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include +#include +#include +#include "bacdef.h" +#include "dlmstp.h" +#include "rs485.h" +#include "crc.h" +#include "npdu.h" +#include "bits.h" +#include "bacaddr.h" +#include "txbuf.h" + +/* This file has been customized for use with small microprocessors */ +/* Assumptions: + Only one slave node MS/TP datalink layer +*/ +#include "hardware.h" +#include "timer.h" + +/* The value 255 is used to denote broadcast when used as a */ +/* destination address but is not allowed as a value for a station. */ +/* Station addresses for master nodes can be 0-127. */ +/* Station addresses for slave nodes can be 127-254. */ +#define MSTP_BROADCAST_ADDRESS 255 + +/* MS/TP Frame Type */ +/* Frame Types 8 through 127 are reserved by ASHRAE. */ +#define FRAME_TYPE_TOKEN 0 +#define FRAME_TYPE_POLL_FOR_MASTER 1 +#define FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER 2 +#define FRAME_TYPE_TEST_REQUEST 3 +#define FRAME_TYPE_TEST_RESPONSE 4 +#define FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY 5 +#define FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY 6 +#define FRAME_TYPE_REPLY_POSTPONED 7 +/* Frame Types 128 through 255: Proprietary Frames */ +/* These frames are available to vendors as proprietary (non-BACnet) frames. */ +/* The first two octets of the Data field shall specify the unique vendor */ +/* identification code, most significant octet first, for the type of */ +/* vendor-proprietary frame to be conveyed. The length of the data portion */ +/* of a Proprietary frame shall be in the range of 2 to 501 octets. */ +#define FRAME_TYPE_PROPRIETARY_MIN 128 +#define FRAME_TYPE_PROPRIETARY_MAX 255 + +/* receive FSM states */ +typedef enum { + MSTP_RECEIVE_STATE_IDLE = 0, + MSTP_RECEIVE_STATE_PREAMBLE = 1, + MSTP_RECEIVE_STATE_HEADER = 2, + MSTP_RECEIVE_STATE_DATA = 3 +} MSTP_RECEIVE_STATE; + +/* The state of the Receive State Machine */ +static MSTP_RECEIVE_STATE Receive_State; +static struct mstp_flag_t { + /* A Boolean flag set to TRUE by the Receive State Machine */ + /* if an invalid or valid frame is received. */ + /* Set to FALSE by the main state machine. */ + unsigned ReceivedInvalidFrame:1; + unsigned ReceivedValidFrame:1; + /* A Boolean flag set TRUE by the datalink transmit if a + frame is pending */ + unsigned TransmitPacketPending:1; + /* A Boolean flag set TRUE by the datalink transmit if a + pending packet is DataExpectingReply */ + unsigned TransmitPacketDER:1; + /* A Boolean flag set TRUE by the datalink if a + packet has been received, but not processed. */ + unsigned ReceivePacketPending:1; +} MSTP_Flag; + +/* data passed to receive handler */ +struct mstp_packet_info_t { + /* A Boolean flag set to TRUE by the Receive State Machine */ + /* if a valid frame is received. */ + unsigned valid_frame:1; + /* preamble flags */ + unsigned preamble1:1; + unsigned preamble2:1; + uint8_t header[6]; /* buffer to put the header bytes */ + uint8_t *buffer; /* buffer to put the data */ + uint8_t buffer_len; /* buffer to put the data */ + uint8_t index; /* index into receive buffer */ +}; +static struct nitoo_packet_info_t MSTP_Receive_Packet; + +/* Used to store the data length of a received frame. */ +static uint16_t DataLength; +/* Used to store the destination address of a received frame. */ +static uint8_t DestinationAddress; +/* Used to store the frame type of a received frame. */ +static uint8_t FrameType; +/* An array of octets, used to store octets as they are received. */ +/* InputBuffer is indexed from 0 to InputBufferSize-1. */ +/* FIXME: assign this to an actual array of bytes! */ +/* Note: the buffer is designed as a pointer since some compilers + and microcontroller architectures have limits as to places to + hold contiguous memory. */ +static uint8_t *InputBuffer; +static uint16_t InputBufferSize; +/* Used to store the Source Address of a received frame. */ +static uint8_t SourceAddress; +/* "This Station," the MAC address of this node. TS is generally read from a */ +/* hardware DIP switch, or from nonvolatile memory. Valid values for TS are */ +/* 0 to 254. The value 255 is used to denote broadcast when used as a */ +/* destination address but is not allowed as a value for TS. */ +static uint8_t This_Station; +/* An array of octets, used to store octets for transmitting */ +/* OutputBuffer is indexed from 0 to OutputBufferSize-1. */ +/* The MAX_PDU size of a frame is MAX_APDU + MAX_NPDU octets. */ +/* FIXME: assign this to an actual array of bytes! */ +/* Note: the buffer is designed as a pointer since some compilers + and microcontroller architectures have limits as to places to + hold contiguous memory. */ +static uint8_t *TransmitPacket; +static uint16_t TransmitPacketLen; +static uint8_t TransmitPacketDest; + +/* The minimum time without a DataAvailable or ReceiveError event within */ +/* a frame before a receiving node may discard the frame: 60 bit times. */ +/* (Implementations may use larger values for this timeout, */ +/* not to exceed 100 milliseconds.) */ +/* At 9600 baud, 60 bit times would be about 6.25 milliseconds */ +/* const uint16_t Tframe_abort = 1 + ((1000 * 60) / 9600); */ +#define Tframe_abort 30 + +/* The maximum idle time a sending node may allow to elapse between octets */ +/* of a frame the node is transmitting: 20 bit times. */ +#define Tframe_gap 20 + +/* The maximum time a node may wait after reception of a frame that expects */ +/* a reply before sending the first octet of a reply or Reply Postponed */ +/* frame: 250 milliseconds. */ +#define Treply_delay 250 + +/* The width of the time slot within which a node may generate a token: */ +/* 10 milliseconds. */ +#define Tslot 10 + +/* The maximum time a node may wait after reception of the token or */ +/* a Poll For Master frame before sending the first octet of a frame: */ +/* 15 milliseconds. */ +#define Tusage_delay 15 + +/* we need to be able to increment without rolling over */ +#define INCREMENT_AND_LIMIT_UINT8(x) {if (x < 0xFF) x++;} + +bool dlmstp_init( + char *ifname) +{ + ifname = ifname; + /* initialize hardware */ + RS485_Initialize(); + + return true; +} + +void dlmstp_cleanup( + void) +{ + /* nothing to do for static buffers */ +} + +void dlmstp_fill_bacnet_address( + BACNET_ADDRESS * src, + uint8_t mstp_address) +{ + int i = 0; + + if (mstp_address == MSTP_BROADCAST_ADDRESS) { + /* mac_len = 0 if broadcast address */ + src->mac_len = 0; + src->mac[0] = 0; + } else { + src->mac_len = 1; + src->mac[0] = mstp_address; + } + /* fill with 0's starting with index 1; index 0 filled above */ + for (i = 1; i < MAX_MAC_LEN; i++) { + src->mac[i] = 0; + } + src->net = 0; + src->len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + src->adr[i] = 0; + } +} + +/* MS/TP Frame Format */ +/* All frames are of the following format: */ +/* */ +/* Preamble: two octet preamble: X`55', X`FF' */ +/* Frame Type: one octet */ +/* Destination Address: one octet address */ +/* Source Address: one octet address */ +/* Length: two octets, most significant octet first, of the Data field */ +/* Header CRC: one octet */ +/* Data: (present only if Length is non-zero) */ +/* Data CRC: (present only if Length is non-zero) two octets, */ +/* least significant octet first */ +/* (pad): (optional) at most one octet of padding: X'FF' */ +static void MSTP_Send_Frame( + uint8_t frame_type, /* type of frame to send - see defines */ + uint8_t destination, /* destination address */ + uint8_t source, /* source address */ + uint8_t * pdu, /* any data to be sent - may be null */ + uint16_t pdu_len) +{ /* number of bytes of data (up to 501) */ + uint8_t crc8 = 0xFF; /* used to calculate the crc value */ + uint16_t crc16 = 0xFFFF; /* used to calculate the crc value */ + uint8_t buffer[8]; /* stores the header and crc */ + uint8_t datacrc[2]; /* stores the data crc */ + uint16_t i = 0; /* used to calculate CRC for data */ + + /* create the MS/TP header */ + buffer[0] = 0x55; + buffer[1] = 0xFF; + buffer[2] = frame_type; + crc8 = CRC_Calc_Header(buffer[2], crc8); + buffer[3] = destination; + crc8 = CRC_Calc_Header(buffer[3], crc8); + buffer[4] = source; + crc8 = CRC_Calc_Header(buffer[4], crc8); + buffer[5] = pdu_len / 256; + crc8 = CRC_Calc_Header(buffer[5], crc8); + buffer[6] = pdu_len % 256; + crc8 = CRC_Calc_Header(buffer[6], crc8); + buffer[7] = ~crc8; + if (pdu_len) { + /* calculate CRC for any data */ + for (i = 0; i < pdu_len; i++) { + crc16 = CRC_Calc_Data(pdu[i], crc16); + } + crc16 = ~crc16; + datacrc[0] = (crc16 & 0x00FF); + datacrc[1] = ((crc16 & 0xFF00) >> 8); + } + /* now transmit the frame */ + RS485_Turnaround_Delay(); + RS485_Transmitter_Enable(true); + RS485_Send_Data(buffer, 8); + /* send any data */ + if (pdu_len) { + RS485_Send_Data(pdu, pdu_len); + RS485_Send_Data(datacrc, 2); + } + RS485_Transmitter_Enable(false); +} + +#if 0 +/* return true if the packet is good. */ +/* note: buffer should include the CRC as the last byte */ +static bool crc_header_good( + uint8_t * buffer, + uint8_t len) +{ + uint8_t i; /* loop counter */ + uint8_t crc8 = 0xFF; /* loop counter */ + + for (i = 0; i < len; i++) { + crc8 = CRC_Calc_Header(buffer[i], crc8); + } + + return (crc8 == 0x55); +} + + +static void mstp_receive_handler( + void) +{ + uint8_t data_register = 0; /* data from UART */ + + if (RS485_ReceiveError()) { + timer_silence_reset(); + } else if (RS485_DataAvailable(&data_register)) { + timer_silence_reset(); + if ((MSTP_Receive_Packet.preamble1 == false) && + (data_register == 0x55)) { + MSTP_Receive_Packet.preamble1 = true; + return; + } + if ((MSTP_Receive_Packet.preamble2 == false) && + (MSTP_Receive_Packet.preamble1 == true)) { + if (data_register == 0xFF) { + MSTP_Receive_Packet.preamble2 = true; + MSTP_Receive_Packet.index = 0; + MSTP_Receive_Packet.data_len = 0; + } else if (data_register == 0x55) { + /* repeated preamble1 */ + return; + } else { + MSTP_Receive_Packet.preamble1 = false; + } + return; + } + if (DataLength == 0) { + MSTP_Receive_Packet.header[MSTP_Receive_Packet.index] = + data_register; + if (MSTP_Receive_Packet.index == 5) { + if (crc_header_good(MSTP_Receive_Packet.header, 6)) { + FrameType = MSTP_Receive_Packet.header[0]; + DestinationAddress = MSTP_Receive_Packet.header[1]; + SourceAddress = MSTP_Receive_Packet.header[2]; + DataLength = + (MSTP_Receive_Packet.header[3] * 256) + + MSTP_Receive_Packet.header[4]; + if (DataLength == 0) { + MSTP_Receive_Packet.valid_frame = true; + } else { + MSTP_Receive_Packet.index = 0; + } + } else { + MSTP_Receive_Packet.preamble2 = false; + MSTP_Receive_Packet.preamble2 = false; + MSTP_Receive_Packet.index = 0; + } + } + } else { + MSTP_Receive_Packet.buffer[MSTP_Receive_Packet.index] = + data_register; + if (packet_info->index == packet_info->len) { + /* PDU length ended */ + packet_info->ready = true; + } else if (packet_info->index >= sizeof(packet_info->buffer)) { + /* exceeded the size of the storage */ + packet_info->len = packet_info->index; + packet_info->ready = true; + } else { + packet_info->index++; + } + MSTP_Receive_Packet.index++; + if (packet_info->ready) { + /* validate the CRC */ + if (!lrc_packet_good(packet_info->buffer, + packet_info->len + 1)) { + packet_info->ready = false; + } + /* pull off the CRC */ + packet_info->crc = packet_info->buffer[packet_info->len]; + /* get ready for the next packet */ + packet_info->index = 0; + packet_info->preamble1 = false; + packet_info->preamble2 = false; + led_setup_off(); + } + } + } else { + if (ReceivePreamble1 == true) { + if (timer_silence_elapsed(Tframe_abort)) { + /* we've been busy too long! Abort packet! */ + Index = 0; + ReceivePreamble1 = false; + ReceivePreamble2 = false; + } + } + } +} +#endif + +static void MSTP_Receive_Frame_FSM( + void) +{ + /* stores the latest received data octet */ + uint8_t DataRegister = 0; + /* Used to accumulate the CRC on the data field of a frame. */ + static uint16_t DataCRC = 0; + /* Used to accumulate the CRC on the header of a frame. */ + static uint8_t HeaderCRC = 0; + /* Used as an index by the Receive State Machine, + up to a maximum value of the MPDU */ + static uint8_t Index = 0; + + switch (Receive_State) { + case MSTP_RECEIVE_STATE_IDLE: + /* In the IDLE state, the node waits for the beginning of a frame. */ + if (RS485_ReceiveError()) { + /* EatAnError */ + timer_silence_reset(); + } else if (RS485_DataAvailable(&DataRegister)) { + timer_silence_reset(); + if (DataRegister == 0x55) { + /* Preamble1 */ + /* receive the remainder of the frame. */ + Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; + } + } + break; + case MSTP_RECEIVE_STATE_PREAMBLE: + /* In the PREAMBLE state, the node waits for the + second octet of the preamble. */ + if (timer_silence_elapsed(Tframe_abort)) { + /* Timeout */ + /* a correct preamble has not been received */ + /* wait for the start of a frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else if (RS485_ReceiveError()) { + /* Error */ + timer_silence_reset(); + /* wait for the start of a frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else if (RS485_DataAvailable(&DataRegister)) { + timer_silence_reset(); + if (DataRegister == 0xFF) { + /* Preamble2 */ + Index = 0; + HeaderCRC = 0xFF; + /* receive the remainder of the frame. */ + Receive_State = MSTP_RECEIVE_STATE_HEADER; + } else if (DataRegister == 0x55) { + /* ignore RepeatedPreamble1 */ + /* wait for the second preamble octet. */ + Receive_State = MSTP_RECEIVE_STATE_PREAMBLE; + } else { + /* NotPreamble */ + /* wait for the start of a frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } + } + break; + case MSTP_RECEIVE_STATE_HEADER: + /* In the HEADER state, the node waits for the fixed message header. */ + if (timer_silence_elapsed(Tframe_abort)) { + /* Timeout */ + /* indicate that an error has occurred during the reception of a frame */ + MSTP_Flag.ReceivedInvalidFrame = true; + /* wait for the start of a frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else if (RS485_ReceiveError()) { + /* Error */ + timer_silence_reset(); + /* indicate that an error has occurred during the reception of a frame */ + MSTP_Flag.ReceivedInvalidFrame = true; + /* wait for the start of a frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else if (RS485_DataAvailable(&DataRegister)) { + timer_silence_reset(); + if (Index == 0) { + /* FrameType */ + HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); + FrameType = DataRegister; + Index = 1; + } else if (Index == 1) { + /* Destination */ + HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); + DestinationAddress = DataRegister; + Index = 2; + } else if (Index == 2) { + /* Source */ + HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); + SourceAddress = DataRegister; + Index = 3; + } else if (Index == 3) { + /* Length1 */ + HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); + DataLength = DataRegister * 256; + Index = 4; + } else if (Index == 4) { + /* Length2 */ + HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); + DataLength += DataRegister; + Index = 5; + } else if (Index == 5) { + /* HeaderCRC */ + HeaderCRC = CRC_Calc_Header(DataRegister, HeaderCRC); + /* In the HEADER_CRC state, the node validates the CRC + on the fixed message header. */ + if (HeaderCRC != 0x55) { + /* BadCRC */ + /* indicate that an error has occurred during + the reception of a frame */ + MSTP_Flag.ReceivedInvalidFrame = true; + /* wait for the start of the next frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else { + /* Note: proposed change to BACnet MSTP state machine! + If we don't decode data that is not for us, we could + get confused about the start if the Preamble 55 FF + is part of the data. */ + if ((DataLength) && (DataLength <= InputBufferSize)) { + /* Data */ + Index = 0; + DataCRC = 0xFFFF; + /* receive the data portion of the frame. */ + Receive_State = MSTP_RECEIVE_STATE_DATA; + } else { + if (DataLength == 0) { + /* NoData */ + if ((DestinationAddress == This_Station) || + (DestinationAddress == + MSTP_BROADCAST_ADDRESS)) { + /* ForUs */ + /* indicate that a frame with + no data has been received */ + MSTP_Flag.ReceivedValidFrame = true; + } else { + /* NotForUs - drop */ + } + } else { + /* FrameTooLong */ + /* indicate that a frame with an illegal or */ + /* unacceptable data length has been received */ + MSTP_Flag.ReceivedInvalidFrame = true; + } + /* wait for the start of the next frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } + } + } else { + /* indicate that an error has occurred during */ + /* the reception of a frame */ + MSTP_Flag.ReceivedInvalidFrame = true; + /* wait for the start of a frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } + } + break; + case MSTP_RECEIVE_STATE_DATA: + /* In the DATA state, the node waits for the data portion of a frame. */ + if (timer_silence_elapsed(Tframe_abort)) { + /* Timeout */ + /* indicate that an error has occurred during the reception of a frame */ + MSTP_Flag.ReceivedInvalidFrame = true; + /* wait for the start of the next frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else if (RS485_ReceiveError()) { + /* Error */ + timer_silence_reset(); + /* indicate that an error has occurred during + the reception of a frame */ + MSTP_Flag.ReceivedInvalidFrame = true; + /* wait for the start of the next frame. */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } else if (RS485_DataAvailable(&DataRegister)) { + timer_silence_reset(); + if (Index < DataLength) { + /* DataOctet */ + DataCRC = CRC_Calc_Data(DataRegister, DataCRC); + InputBuffer[Index] = DataRegister; + Index++; + } else if (Index == DataLength) { + /* CRC1 */ + DataCRC = CRC_Calc_Data(DataRegister, DataCRC); + Index++; + } else if (Index == (DataLength + 1)) { + /* CRC2 */ + DataCRC = CRC_Calc_Data(DataRegister, DataCRC); + /* STATE DATA CRC - no need for new state */ + /* indicate the complete reception of a valid frame */ + if (DataCRC == 0xF0B8) { + if ((DestinationAddress == This_Station) || + (DestinationAddress == MSTP_BROADCAST_ADDRESS)) { + /* ForUs */ + /* indicate that a frame with no data + has been received */ + MSTP_Flag.ReceivedValidFrame = true; + } + } else { + MSTP_Flag.ReceivedInvalidFrame = true; + } + Receive_State = MSTP_RECEIVE_STATE_IDLE; + } + } + break; + default: + /* shouldn't get here - but if we do... */ + Receive_State = MSTP_RECEIVE_STATE_IDLE; + break; + } + + return; +} + +static void MSTP_Slave_Node_FSM( + void) +{ + if (MSTP_Flag.ReceivedValidFrame) { + MSTP_Flag.ReceivedValidFrame = false; + switch (FrameType) { + case FRAME_TYPE_TOKEN: + break; + case FRAME_TYPE_POLL_FOR_MASTER: + break; + case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY: + break; + case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY: + /* indicate successful reception to the higher layers */ + MSTP_Flag.ReceivePacketPending = true; + break; + case FRAME_TYPE_TEST_REQUEST: + MSTP_Send_Frame(FRAME_TYPE_TEST_RESPONSE, SourceAddress, + This_Station, &InputBuffer[0], DataLength); + break; + case FRAME_TYPE_TEST_RESPONSE: + default: + break; + } + } else if (MSTP_Flag.TransmitPacketPending) { + /* Reply */ + /* If a reply is available from the higher layers */ + /* within Treply_delay after the reception of the */ + /* final octet of the requesting frame */ + /* (the mechanism used to determine this is a local matter), */ + /* then call MSTP_Send_Frame to transmit the reply frame */ + /* and enter the IDLE state to wait for the next frame. */ + /* Note: optimized such that we are never a client */ + MSTP_Send_Frame(FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY, + TransmitPacketDest, This_Station, (uint8_t *) & TransmitPacket[0], + TransmitPacketLen); + MSTP_Flag.TransmitPacketPending = false; + MSTP_Flag.ReceivePacketPending = false; + } +} + +/* returns number of bytes sent on success, zero on failure */ +int dlmstp_send_pdu( + BACNET_ADDRESS * dest, /* destination address */ + BACNET_NPDU_DATA * npdu_data, /* network information */ + uint8_t * pdu, /* any data to be sent - may be null */ + unsigned pdu_len) +{ /* number of bytes of data */ + int bytes_sent = 0; + + if (MSTP_Flag.TransmitPacketPending == false) { + MSTP_Flag.TransmitPacketDER = npdu_data->data_expecting_reply; + TransmitPacket = pdu; + TransmitPacketLen = pdu_len; + bytes_sent = pdu_len; + TransmitPacketDest = dest->mac[0]; + MSTP_Flag.TransmitPacketPending = true; + } + + return bytes_sent; +} + +/* Return the length of the packet */ +uint16_t dlmstp_receive( + BACNET_ADDRESS * src, /* source address */ + uint8_t * pdu, /* PDU data */ + uint16_t max_pdu, /* amount of space available in the PDU */ + unsigned timeout) +{ /* milliseconds to wait for a packet */ + uint16_t pdu_len = 0; /* return value */ + + /* dummy - unused parameter */ + timeout = timeout; + /* set the input buffer to the same data storage for zero copy */ + if (!InputBuffer) { + InputBuffer = pdu; + InputBufferSize = max_pdu; + } + /* only do receive state machine while we don't have a frame */ + if ((MSTP_Flag.ReceivedValidFrame == false) && + (MSTP_Flag.ReceivedInvalidFrame == false) && + (MSTP_Flag.ReceivePacketPending == false)) { + for (;;) { + MSTP_Receive_Frame_FSM(); + if (MSTP_Flag.ReceivedValidFrame || MSTP_Flag.ReceivedInvalidFrame) + break; + /* if we are not idle, then we are + receiving a frame or timing out */ + if (Receive_State == MSTP_RECEIVE_STATE_IDLE) + break; + } + } + /* only do master state machine while rx is idle */ + if (Receive_State == MSTP_RECEIVE_STATE_IDLE) { + MSTP_Slave_Node_FSM(); + } + /* if there is a packet that needs processed, do it now. */ + if (MSTP_Flag.ReceivePacketPending) { + MSTP_Flag.ReceivePacketPending = false; + pdu_len = DataLength; + src->mac_len = 1; + src->mac[0] = SourceAddress; + /* data is already in the pdu pointer */ + } + + return pdu_len; +} + +void dlmstp_set_mac_address( + uint8_t mac_address) +{ + /* Master Nodes can only have address 0-127 */ + if (mac_address <= 127) { + This_Station = mac_address; + /* FIXME: implement your data storage */ + /* I2C_Write_Byte( + EEPROM_DEVICE_ADDRESS, + mac_address, + EEPROM_MSTP_MAC_ADDR); */ + } + + return; +} + +uint8_t dlmstp_mac_address( + void) +{ + return This_Station; +} + +void dlmstp_get_my_address( + BACNET_ADDRESS * my_address) +{ + int i = 0; /* counter */ + + my_address->mac_len = 1; + my_address->mac[0] = This_Station; + my_address->net = 0; /* local only, no routing */ + my_address->len = 0; + for (i = 0; i < MAX_MAC_LEN; i++) { + my_address->adr[i] = 0; + } + + return; +} + +void dlmstp_get_broadcast_address( + BACNET_ADDRESS * dest) +{ /* destination address */ + int i = 0; /* counter */ + + if (dest) { + dest->mac_len = 1; + dest->mac[0] = MSTP_BROADCAST_ADDRESS; + dest->net = BACNET_BROADCAST_NETWORK; + dest->len = 0; /* always zero when DNET is broadcast */ + for (i = 0; i < MAX_MAC_LEN; i++) { + dest->adr[i] = 0; + } + } + + return; +} diff --git a/bacnet-stack/ports/atmega8/h_rp.c b/bacnet-stack/ports/atmega8/h_rp.c index d34bbb58..94f0f423 100644 --- a/bacnet-stack/ports/atmega8/h_rp.c +++ b/bacnet-stack/ports/atmega8/h_rp.c @@ -1,173 +1,173 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "rp.h" -/* demo objects */ -#include "device.h" -#if MAX_ANALOG_VALUES -#include "av.h" -#endif -#if MAX_BINARY_VALUES -#include "bv.h" -#endif - -/* Encodes the property APDU and returns the length, - or sets the error, and returns -1 */ -int Encode_Property_APDU( - uint8_t * apdu, - BACNET_READ_PROPERTY_DATA * rp_data, - BACNET_ERROR_CLASS * error_class, - BACNET_ERROR_CODE * error_code) -{ - int apdu_len = -1; - - /* handle each object type */ - switch (rp_data->object_type) { - case OBJECT_DEVICE: - if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { - apdu_len = - Device_Encode_Property_APDU(&apdu[0], - rp_data->object_property, rp_data->array_index, - error_class, error_code); - } - break; -#if MAX_ANALOG_VALUES - case OBJECT_ANALOG_VALUE: - if (Analog_Value_Valid_Instance(rp_data->object_instance)) { - apdu_len = - Analog_Value_Encode_Property_APDU(&apdu[0], - rp_data->object_instance, rp_data->object_property, - rp_data->array_index, error_class, error_code); - } - break; -#endif -#if MAX_BINARY_VALUES - case OBJECT_BINARY_VALUE: - if (Binary_Value_Valid_Instance(rp_data->object_instance)) { - apdu_len = - Binary_Value_Encode_Property_APDU(&apdu[0], - rp_data->object_instance, rp_data->object_property, - rp_data->array_index, error_class, error_code); - } - break; -#endif - default: - *error_class = ERROR_CLASS_OBJECT; - *error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; - break; - } - - return apdu_len; -} - -void handler_read_property( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data) -{ - BACNET_READ_PROPERTY_DATA data; - int len = 0; - int ack_len = 0; - int property_len = 0; - int pdu_len = 0; - BACNET_NPDU_DATA npdu_data; - int bytes_sent = 0; - BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; - BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; - BACNET_ADDRESS my_address; - - /* encode the NPDU portion of the packet */ - datalink_get_my_address(&my_address); - npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = - npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); - if (service_data->segmented_message) { - /* we don't support segmentation - send an abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, - true); - goto RP_ABORT; - } - len = rp_decode_service_request(service_request, service_len, &data); - if (len < 0) { - /* bad decoding - send an abort */ - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); - goto RP_ABORT; - } - /* most cases will be error */ - ack_len = - rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, &data); - /* FIXME: add buffer len as passed into function or use smart buffer */ - property_len = - Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], - &data, &error_class, &error_code); - if (property_len >= 0) { - len = - rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer - [pdu_len + property_len + ack_len]); - len += ack_len + property_len; - } else { - switch (property_len) { - /* BACnet APDU too small to fit data, so proper response is Abort */ - case -2: - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); - break; - default: - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, - error_class, error_code); - break; - } - } - RP_ABORT: - pdu_len += len; - bytes_sent = - datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); - - return; -} +/************************************************************************** +* +* Copyright (C) 2005 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacerror.h" +#include "apdu.h" +#include "npdu.h" +#include "abort.h" +#include "rp.h" +/* demo objects */ +#include "device.h" +#if MAX_ANALOG_VALUES +#include "av.h" +#endif +#if MAX_BINARY_VALUES +#include "bv.h" +#endif + +/* Encodes the property APDU and returns the length, + or sets the error, and returns -1 */ +int Encode_Property_APDU( + uint8_t * apdu, + BACNET_READ_PROPERTY_DATA * rp_data, + BACNET_ERROR_CLASS * error_class, + BACNET_ERROR_CODE * error_code) +{ + int apdu_len = -1; + + /* handle each object type */ + switch (rp_data->object_type) { + case OBJECT_DEVICE: + if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { + apdu_len = + Device_Encode_Property_APDU(&apdu[0], + rp_data->object_property, rp_data->array_index, + error_class, error_code); + } + break; +#if MAX_ANALOG_VALUES + case OBJECT_ANALOG_VALUE: + if (Analog_Value_Valid_Instance(rp_data->object_instance)) { + apdu_len = + Analog_Value_Encode_Property_APDU(&apdu[0], + rp_data->object_instance, rp_data->object_property, + rp_data->array_index, error_class, error_code); + } + break; +#endif +#if MAX_BINARY_VALUES + case OBJECT_BINARY_VALUE: + if (Binary_Value_Valid_Instance(rp_data->object_instance)) { + apdu_len = + Binary_Value_Encode_Property_APDU(&apdu[0], + rp_data->object_instance, rp_data->object_property, + rp_data->array_index, error_class, error_code); + } + break; +#endif + default: + *error_class = ERROR_CLASS_OBJECT; + *error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; + break; + } + + return apdu_len; +} + +void handler_read_property( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data) +{ + BACNET_READ_PROPERTY_DATA data; + int len = 0; + int ack_len = 0; + int property_len = 0; + int pdu_len = 0; + BACNET_NPDU_DATA npdu_data; + int bytes_sent = 0; + BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; + BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; + BACNET_ADDRESS my_address; + + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = + npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, + &npdu_data); + if (service_data->segmented_message) { + /* we don't support segmentation - send an abort */ + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); + goto RP_ABORT; + } + len = rp_decode_service_request(service_request, service_len, &data); + if (len < 0) { + /* bad decoding - send an abort */ + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_OTHER, true); + goto RP_ABORT; + } + /* most cases will be error */ + ack_len = + rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, &data); + /* FIXME: add buffer len as passed into function or use smart buffer */ + property_len = + Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], + &data, &error_class, &error_code); + if (property_len >= 0) { + len = + rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer + [pdu_len + property_len + ack_len]); + len += ack_len + property_len; + } else { + switch (property_len) { + /* BACnet APDU too small to fit data, so proper response is Abort */ + case -2: + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); + break; + default: + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, + error_class, error_code); + break; + } + } + RP_ABORT: + pdu_len += len; + bytes_sent = + datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], + pdu_len); + + return; +} diff --git a/bacnet-stack/ports/atmega8/h_whois.c b/bacnet-stack/ports/atmega8/h_whois.c index 3a0d56ec..d273bab4 100644 --- a/bacnet-stack/ports/atmega8/h_whois.c +++ b/bacnet-stack/ports/atmega8/h_whois.c @@ -1,71 +1,71 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "whois.h" -#include "iam.h" -#include "device.h" -#include "client.h" -#include "txbuf.h" - -bool Send_I_Am = true; - -void handler_who_is( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src) -{ - int len = 0; - int32_t low_limit = 0; - int32_t high_limit = 0; - int32_t target_device; - - (void) src; - len = - whois_decode_service_request(service_request, service_len, &low_limit, - &high_limit); - if (len == 0) { - Send_I_Am = true; - } else if (len != -1) { - /* is my device id within the limits? */ - target_device = Device_Object_Instance_Number(); - if (((target_device >= low_limit) && (target_device <= high_limit)) - || - /* BACnet wildcard is the max instance number - everyone responds */ - ((BACNET_MAX_INSTANCE >= (uint32_t) low_limit) && - (BACNET_MAX_INSTANCE <= (uint32_t) high_limit))) { - Send_I_Am = true; - } - } - - return; -} +/************************************************************************** +* +* Copyright (C) 2005 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "whois.h" +#include "iam.h" +#include "device.h" +#include "client.h" +#include "txbuf.h" + +bool Send_I_Am = true; + +void handler_who_is( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src) +{ + int len = 0; + int32_t low_limit = 0; + int32_t high_limit = 0; + int32_t target_device; + + (void) src; + len = + whois_decode_service_request(service_request, service_len, &low_limit, + &high_limit); + if (len == 0) { + Send_I_Am = true; + } else if (len != -1) { + /* is my device id within the limits? */ + target_device = Device_Object_Instance_Number(); + if (((target_device >= low_limit) && (target_device <= high_limit)) + || + /* BACnet wildcard is the max instance number - everyone responds */ + ((BACNET_MAX_INSTANCE >= (uint32_t) low_limit) && + (BACNET_MAX_INSTANCE <= (uint32_t) high_limit))) { + Send_I_Am = true; + } + } + + return; +} diff --git a/bacnet-stack/ports/atmega8/h_wp.c b/bacnet-stack/ports/atmega8/h_wp.c index 7c4daca0..879bcb5c 100644 --- a/bacnet-stack/ports/atmega8/h_wp.c +++ b/bacnet-stack/ports/atmega8/h_wp.c @@ -1,139 +1,139 @@ -/************************************************************************** -* -* Copyright (C) 2005 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include -#include -#include -#include "config.h" -#include "txbuf.h" -#include "bacdef.h" -#include "bacdcode.h" -#include "bacerror.h" -#include "apdu.h" -#include "npdu.h" -#include "abort.h" -#include "wp.h" -/* demo objects */ -#include "device.h" -#include "av.h" -#include "bv.h" - -/* too big to reside on stack frame for PIC */ -static BACNET_WRITE_PROPERTY_DATA wp_data; - -void handler_write_property( - uint8_t * service_request, - uint16_t service_len, - BACNET_ADDRESS * src, - BACNET_CONFIRMED_SERVICE_DATA * service_data) -{ - int len = 0; - int pdu_len = 0; - BACNET_NPDU_DATA npdu_data; - BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; - BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; - int bytes_sent = 0; - BACNET_ADDRESS my_address; - - /* decode the service request only */ - len = wp_decode_service_request(service_request, service_len, &wp_data); - /* encode the NPDU portion of the packet */ - datalink_get_my_address(&my_address); - npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = - npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, - &npdu_data); - /* bad decoding or something we didn't understand - send an abort */ - if (len <= 0) { - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_OTHER, true); - } else if (service_data->segmented_message) { - len = - abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, - true); - } else { - switch (wp_data.object_type) { - case OBJECT_DEVICE: - if (Device_Write_Property(&wp_data, &error_class, &error_code)) { - len = - encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY); - } else { - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, - error_code); - } - break; - case OBJECT_ANALOG_VALUE: - if (Analog_Value_Write_Property(&wp_data, &error_class, - &error_code)) { - len = - encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY); - } else { - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, - error_code); - } - break; - case OBJECT_BINARY_VALUE: - if (Binary_Value_Write_Property(&wp_data, &error_class, - &error_code)) { - len = - encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY); - } else { - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, - SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, - error_code); - } - break; - default: - len = - bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], - service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, - error_class, error_code); - break; - } - } - pdu_len += len; - bytes_sent = - datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], - pdu_len); - - return; -} +/************************************************************************** +* +* Copyright (C) 2005 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include +#include +#include +#include "config.h" +#include "txbuf.h" +#include "bacdef.h" +#include "bacdcode.h" +#include "bacerror.h" +#include "apdu.h" +#include "npdu.h" +#include "abort.h" +#include "wp.h" +/* demo objects */ +#include "device.h" +#include "av.h" +#include "bv.h" + +/* too big to reside on stack frame for PIC */ +static BACNET_WRITE_PROPERTY_DATA wp_data; + +void handler_write_property( + uint8_t * service_request, + uint16_t service_len, + BACNET_ADDRESS * src, + BACNET_CONFIRMED_SERVICE_DATA * service_data) +{ + int len = 0; + int pdu_len = 0; + BACNET_NPDU_DATA npdu_data; + BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; + BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; + int bytes_sent = 0; + BACNET_ADDRESS my_address; + + /* decode the service request only */ + len = wp_decode_service_request(service_request, service_len, &wp_data); + /* encode the NPDU portion of the packet */ + datalink_get_my_address(&my_address); + npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = + npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, + &npdu_data); + /* bad decoding or something we didn't understand - send an abort */ + if (len <= 0) { + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_OTHER, true); + } else if (service_data->segmented_message) { + len = + abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, + true); + } else { + switch (wp_data.object_type) { + case OBJECT_DEVICE: + if (Device_Write_Property(&wp_data, &error_class, &error_code)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + } + break; + case OBJECT_ANALOG_VALUE: + if (Analog_Value_Write_Property(&wp_data, &error_class, + &error_code)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + } + break; + case OBJECT_BINARY_VALUE: + if (Binary_Value_Write_Property(&wp_data, &error_class, + &error_code)) { + len = + encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY); + } else { + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, + SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, + error_code); + } + break; + default: + len = + bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], + service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, + error_class, error_code); + break; + } + } + pdu_len += len; + bytes_sent = + datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], + pdu_len); + + return; +} diff --git a/bacnet-stack/ports/atmega8/hardware.h b/bacnet-stack/ports/atmega8/hardware.h index b2fa9008..19bf3364 100644 --- a/bacnet-stack/ports/atmega8/hardware.h +++ b/bacnet-stack/ports/atmega8/hardware.h @@ -1,54 +1,54 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef HARDWARE_H -#define HARDWARE_H - -#if !defined(F_CPU) - /* The processor clock frequency */ -#define F_CPU 7372800UL -#endif - -#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) -#include -#else -#if !defined(__AVR_ATmega168__) -#error Firmware is configured for ATmega168 only (-mmcu=atmega168) -#endif -#endif -#include "iar2gcc.h" -#include "avr035.h" - -#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5) -#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5) -#define LED_NPDU_OFF() BIT_SET(PORTD, PD5) -/* #define LED_NPDU PORTD_Bit5 */ -/* #define LED_NPDU_OFF() {LED_NPDU = false;} */ -/* #define LED_NPDU_ON() {LED_NPDU = true;} */ - -#define LED_GREEN_INIT() BIT_SET(DDRD, DDD4) -#define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4) -#define LED_GREEN_OFF() BIT_SET(PORTD, PD4) - -#endif +/************************************************************************** +* +* Copyright (C) 2007 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#ifndef HARDWARE_H +#define HARDWARE_H + +#if !defined(F_CPU) + /* The processor clock frequency */ +#define F_CPU 7372800UL +#endif + +#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) +#include +#else +#if !defined(__AVR_ATmega168__) +#error Firmware is configured for ATmega168 only (-mmcu=atmega168) +#endif +#endif +#include "iar2gcc.h" +#include "avr035.h" + +#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5) +#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5) +#define LED_NPDU_OFF() BIT_SET(PORTD, PD5) +/* #define LED_NPDU PORTD_Bit5 */ +/* #define LED_NPDU_OFF() {LED_NPDU = false;} */ +/* #define LED_NPDU_ON() {LED_NPDU = true;} */ + +#define LED_GREEN_INIT() BIT_SET(DDRD, DDD4) +#define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4) +#define LED_GREEN_OFF() BIT_SET(PORTD, PD4) + +#endif diff --git a/bacnet-stack/ports/atmega8/iar2gcc.h b/bacnet-stack/ports/atmega8/iar2gcc.h index f80d7fc8..98e9968d 100644 --- a/bacnet-stack/ports/atmega8/iar2gcc.h +++ b/bacnet-stack/ports/atmega8/iar2gcc.h @@ -1,226 +1,226 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2007 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#ifndef IAR2GCC_H -#define IAR2GCC_H - -#if !defined(F_CPU) -#define F_CPU (7372800) -#endif - -/* IAR */ -#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) -#include -#include -/* BitValue is used alot in GCC examples */ -#define _BV(bit_num) (1 << (bit_num)) - -/* inline function */ -static inline void _delay_us( - uint8_t microseconds) -{ - do { - __delay_cycles(F_CPU / 1000000UL); - } while (microseconds--); -} -#endif - -/* Input/Output Registers */ -#if defined(__GNUC__) -#include - -typedef struct { - unsigned char bit0:1; - unsigned char bit1:1; - unsigned char bit2:1; - unsigned char bit3:1; - unsigned char bit4:1; - unsigned char bit5:1; - unsigned char bit6:1; - unsigned char bit7:1; -} BitRegisterType; - -#ifndef true -#define true 1 -#endif - -#ifndef false -#define false 0 -#endif - -#define GPIO_BITREG(port,bitnum) \ - ((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \ - )->bit ## bitnum - -#define PINA_Bit0 GPIO_BITREG(PINA,0) -#define PINA_Bit1 GPIO_BITREG(PINA,1) -#define PINA_Bit2 GPIO_BITREG(PINA,2) -#define PINA_Bit3 GPIO_BITREG(PINA,3) -#define PINA_Bit4 GPIO_BITREG(PINA,4) -#define PINA_Bit5 GPIO_BITREG(PINA,5) -#define PINA_Bit6 GPIO_BITREG(PINA,6) -#define PINA_Bit7 GPIO_BITREG(PINA,7) - -#define PORTA_Bit0 GPIO_BITREG(PORTA,0) -#define PORTA_Bit1 GPIO_BITREG(PORTA,1) -#define PORTA_Bit2 GPIO_BITREG(PORTA,2) -#define PORTA_Bit3 GPIO_BITREG(PORTA,3) -#define PORTA_Bit4 GPIO_BITREG(PORTA,4) -#define PORTA_Bit5 GPIO_BITREG(PORTA,5) -#define PORTA_Bit6 GPIO_BITREG(PORTA,6) -#define PORTA_Bit7 GPIO_BITREG(PORTA,7) - -#define PINB_Bit0 GPIO_BITREG(PINB,0) -#define PINB_Bit1 GPIO_BITREG(PINB,1) -#define PINB_Bit2 GPIO_BITREG(PINB,2) -#define PINB_Bit3 GPIO_BITREG(PINB,3) -#define PINB_Bit4 GPIO_BITREG(PINB,4) -#define PINB_Bit5 GPIO_BITREG(PINB,5) -#define PINB_Bit6 GPIO_BITREG(PINB,6) -#define PINB_Bit7 GPIO_BITREG(PINB,7) - -#define PORTB_Bit0 GPIO_BITREG(PORTB,0) -#define PORTB_Bit1 GPIO_BITREG(PORTB,1) -#define PORTB_Bit2 GPIO_BITREG(PORTB,2) -#define PORTB_Bit3 GPIO_BITREG(PORTB,3) -#define PORTB_Bit4 GPIO_BITREG(PORTB,4) -#define PORTB_Bit5 GPIO_BITREG(PORTB,5) -#define PORTB_Bit6 GPIO_BITREG(PORTB,6) -#define PORTB_Bit7 GPIO_BITREG(PORTB,7) - -#define PINC_Bit0 GPIO_BITREG(PINC,0) -#define PINC_Bit1 GPIO_BITREG(PINC,1) -#define PINC_Bit2 GPIO_BITREG(PINC,2) -#define PINC_Bit3 GPIO_BITREG(PINC,3) -#define PINC_Bit4 GPIO_BITREG(PINC,4) -#define PINC_Bit5 GPIO_BITREG(PINC,5) -#define PINC_Bit6 GPIO_BITREG(PINC,6) -#define PINC_Bit7 GPIO_BITREG(PINC,7) - -#define PORTC_Bit0 GPIO_BITREG(PORTC,0) -#define PORTC_Bit1 GPIO_BITREG(PORTC,1) -#define PORTC_Bit2 GPIO_BITREG(PORTC,2) -#define PORTC_Bit3 GPIO_BITREG(PORTC,3) -#define PORTC_Bit4 GPIO_BITREG(PORTC,4) -#define PORTC_Bit5 GPIO_BITREG(PORTC,5) -#define PORTC_Bit6 GPIO_BITREG(PORTC,6) -#define PORTC_Bit7 GPIO_BITREG(PORTC,7) - -#define PIND_Bit0 GPIO_BITREG(PIND,0) -#define PIND_Bit1 GPIO_BITREG(PIND,1) -#define PIND_Bit2 GPIO_BITREG(PIND,2) -#define PIND_Bit3 GPIO_BITREG(PIND,3) -#define PIND_Bit4 GPIO_BITREG(PIND,4) -#define PIND_Bit5 GPIO_BITREG(PIND,5) -#define PIND_Bit6 GPIO_BITREG(PIND,6) -#define PIND_Bit7 GPIO_BITREG(PIND,7) - -#define PORTD_Bit0 GPIO_BITREG(PORTD,0) -#define PORTD_Bit1 GPIO_BITREG(PORTD,1) -#define PORTD_Bit2 GPIO_BITREG(PORTD,2) -#define PORTD_Bit3 GPIO_BITREG(PORTD,3) -#define PORTD_Bit4 GPIO_BITREG(PORTD,4) -#define PORTD_Bit5 GPIO_BITREG(PORTD,5) -#define PORTD_Bit6 GPIO_BITREG(PORTD,6) -#define PORTD_Bit7 GPIO_BITREG(PORTD,7) - -#define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0) -#define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1) -#define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2) -#define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3) -#define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4) -#define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5) -#define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6) -#define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7) - -#define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0) -#define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1) -#define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2) -#define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3) -#define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4) -#define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5) -#define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6) -#define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7) - -#define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0) -#define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1) -#define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2) -#define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3) -#define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4) -#define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5) -#define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6) -#define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7) - -#endif - -/* Global Interrupts */ -#if defined(__GNUC__) -#define __enable_interrupt() sei() -#define __disable_interrupt() cli() -#endif - -/* Interrupts */ -#if defined(__ICCAVR__) -#define PRAGMA(x) _Pragma( #x ) -#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void) -#endif -#if defined(__GNUC__) -#include -#endif - -/* Flash */ -#if defined(__ICCAVR__) -#define FLASH_DECLARE(x) __flash x -#endif -#if defined(__GNUC__) -#define FLASH_DECLARE(x) x __attribute__((__progmem__)) -#endif - -/* EEPROM */ -#if defined(__ICCAVR__) -#define EEPROM_DECLARE(x) __eeprom x -#endif -#if defined(__GNUC__) -#include -#define EEPROM_DECLARE(x) x __attribute__((section (".eeprom"))) -#endif - -/* IAR intrinsic routines */ -#if defined(__GNUC__) - /* FIXME: intrinsic routines: map to assembler for size/speed */ -#define __multiply_unsigned(x,y) ((x)*(y)) - /* FIXME: __root means to not optimize or strip */ -#define __root -#endif - -#endif +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2007 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#ifndef IAR2GCC_H +#define IAR2GCC_H + +#if !defined(F_CPU) +#define F_CPU (7372800) +#endif + +/* IAR */ +#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) +#include +#include +/* BitValue is used alot in GCC examples */ +#define _BV(bit_num) (1 << (bit_num)) + +/* inline function */ +static inline void _delay_us( + uint8_t microseconds) +{ + do { + __delay_cycles(F_CPU / 1000000UL); + } while (microseconds--); +} +#endif + +/* Input/Output Registers */ +#if defined(__GNUC__) +#include + +typedef struct { + unsigned char bit0:1; + unsigned char bit1:1; + unsigned char bit2:1; + unsigned char bit3:1; + unsigned char bit4:1; + unsigned char bit5:1; + unsigned char bit6:1; + unsigned char bit7:1; +} BitRegisterType; + +#ifndef true +#define true 1 +#endif + +#ifndef false +#define false 0 +#endif + +#define GPIO_BITREG(port,bitnum) \ + ((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \ + )->bit ## bitnum + +#define PINA_Bit0 GPIO_BITREG(PINA,0) +#define PINA_Bit1 GPIO_BITREG(PINA,1) +#define PINA_Bit2 GPIO_BITREG(PINA,2) +#define PINA_Bit3 GPIO_BITREG(PINA,3) +#define PINA_Bit4 GPIO_BITREG(PINA,4) +#define PINA_Bit5 GPIO_BITREG(PINA,5) +#define PINA_Bit6 GPIO_BITREG(PINA,6) +#define PINA_Bit7 GPIO_BITREG(PINA,7) + +#define PORTA_Bit0 GPIO_BITREG(PORTA,0) +#define PORTA_Bit1 GPIO_BITREG(PORTA,1) +#define PORTA_Bit2 GPIO_BITREG(PORTA,2) +#define PORTA_Bit3 GPIO_BITREG(PORTA,3) +#define PORTA_Bit4 GPIO_BITREG(PORTA,4) +#define PORTA_Bit5 GPIO_BITREG(PORTA,5) +#define PORTA_Bit6 GPIO_BITREG(PORTA,6) +#define PORTA_Bit7 GPIO_BITREG(PORTA,7) + +#define PINB_Bit0 GPIO_BITREG(PINB,0) +#define PINB_Bit1 GPIO_BITREG(PINB,1) +#define PINB_Bit2 GPIO_BITREG(PINB,2) +#define PINB_Bit3 GPIO_BITREG(PINB,3) +#define PINB_Bit4 GPIO_BITREG(PINB,4) +#define PINB_Bit5 GPIO_BITREG(PINB,5) +#define PINB_Bit6 GPIO_BITREG(PINB,6) +#define PINB_Bit7 GPIO_BITREG(PINB,7) + +#define PORTB_Bit0 GPIO_BITREG(PORTB,0) +#define PORTB_Bit1 GPIO_BITREG(PORTB,1) +#define PORTB_Bit2 GPIO_BITREG(PORTB,2) +#define PORTB_Bit3 GPIO_BITREG(PORTB,3) +#define PORTB_Bit4 GPIO_BITREG(PORTB,4) +#define PORTB_Bit5 GPIO_BITREG(PORTB,5) +#define PORTB_Bit6 GPIO_BITREG(PORTB,6) +#define PORTB_Bit7 GPIO_BITREG(PORTB,7) + +#define PINC_Bit0 GPIO_BITREG(PINC,0) +#define PINC_Bit1 GPIO_BITREG(PINC,1) +#define PINC_Bit2 GPIO_BITREG(PINC,2) +#define PINC_Bit3 GPIO_BITREG(PINC,3) +#define PINC_Bit4 GPIO_BITREG(PINC,4) +#define PINC_Bit5 GPIO_BITREG(PINC,5) +#define PINC_Bit6 GPIO_BITREG(PINC,6) +#define PINC_Bit7 GPIO_BITREG(PINC,7) + +#define PORTC_Bit0 GPIO_BITREG(PORTC,0) +#define PORTC_Bit1 GPIO_BITREG(PORTC,1) +#define PORTC_Bit2 GPIO_BITREG(PORTC,2) +#define PORTC_Bit3 GPIO_BITREG(PORTC,3) +#define PORTC_Bit4 GPIO_BITREG(PORTC,4) +#define PORTC_Bit5 GPIO_BITREG(PORTC,5) +#define PORTC_Bit6 GPIO_BITREG(PORTC,6) +#define PORTC_Bit7 GPIO_BITREG(PORTC,7) + +#define PIND_Bit0 GPIO_BITREG(PIND,0) +#define PIND_Bit1 GPIO_BITREG(PIND,1) +#define PIND_Bit2 GPIO_BITREG(PIND,2) +#define PIND_Bit3 GPIO_BITREG(PIND,3) +#define PIND_Bit4 GPIO_BITREG(PIND,4) +#define PIND_Bit5 GPIO_BITREG(PIND,5) +#define PIND_Bit6 GPIO_BITREG(PIND,6) +#define PIND_Bit7 GPIO_BITREG(PIND,7) + +#define PORTD_Bit0 GPIO_BITREG(PORTD,0) +#define PORTD_Bit1 GPIO_BITREG(PORTD,1) +#define PORTD_Bit2 GPIO_BITREG(PORTD,2) +#define PORTD_Bit3 GPIO_BITREG(PORTD,3) +#define PORTD_Bit4 GPIO_BITREG(PORTD,4) +#define PORTD_Bit5 GPIO_BITREG(PORTD,5) +#define PORTD_Bit6 GPIO_BITREG(PORTD,6) +#define PORTD_Bit7 GPIO_BITREG(PORTD,7) + +#define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0) +#define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1) +#define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2) +#define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3) +#define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4) +#define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5) +#define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6) +#define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7) + +#define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0) +#define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1) +#define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2) +#define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3) +#define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4) +#define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5) +#define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6) +#define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7) + +#define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0) +#define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1) +#define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2) +#define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3) +#define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4) +#define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5) +#define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6) +#define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7) + +#endif + +/* Global Interrupts */ +#if defined(__GNUC__) +#define __enable_interrupt() sei() +#define __disable_interrupt() cli() +#endif + +/* Interrupts */ +#if defined(__ICCAVR__) +#define PRAGMA(x) _Pragma( #x ) +#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void) +#endif +#if defined(__GNUC__) +#include +#endif + +/* Flash */ +#if defined(__ICCAVR__) +#define FLASH_DECLARE(x) __flash x +#endif +#if defined(__GNUC__) +#define FLASH_DECLARE(x) x __attribute__((__progmem__)) +#endif + +/* EEPROM */ +#if defined(__ICCAVR__) +#define EEPROM_DECLARE(x) __eeprom x +#endif +#if defined(__GNUC__) +#include +#define EEPROM_DECLARE(x) x __attribute__((section (".eeprom"))) +#endif + +/* IAR intrinsic routines */ +#if defined(__GNUC__) + /* FIXME: intrinsic routines: map to assembler for size/speed */ +#define __multiply_unsigned(x,y) ((x)*(y)) + /* FIXME: __root means to not optimize or strip */ +#define __root +#endif + +#endif diff --git a/bacnet-stack/ports/atmega8/main.c b/bacnet-stack/ports/atmega8/main.c index a3ddb262..82e5de1b 100644 --- a/bacnet-stack/ports/atmega8/main.c +++ b/bacnet-stack/ports/atmega8/main.c @@ -1,122 +1,122 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -#include -#include -#include "hardware.h" -#include "timer.h" -#include "rs485.h" -#include "datalink.h" -#include "npdu.h" -#include "txbuf.h" -#include "iam.h" -#include "device.h" -#include "av.h" -#include "handlers.h" - -/* local version override */ -const char *BACnet_Version = "1.0"; - -/* For porting to IAR, see: - http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ - -/* dummy function - so we can use default demo handlers */ -bool dcc_communication_enabled( - void) -{ - return true; -} - -static void init( - void) -{ - /* FIXME: Initialize the Clock Prescaler for ATmega8 */ -#if defined(__AVR_ATmega168__) - /* The default CLKPSx bits are factory set to 0011 */ - /* Enbable the Clock Prescaler */ - CLKPR = _BV(CLKPCE); - /* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor - ------ ------ ------ ------ --------------------- - 0 0 0 0 1 - 0 0 0 1 2 - 0 0 1 0 4 - 0 0 1 1 8 - 0 1 0 0 16 - 0 1 0 1 32 - 0 1 1 0 64 - 0 1 1 1 128 - 1 0 0 0 256 - 1 x x x Reserved - */ - /* Set the CLKPS3..0 bits to Prescaler of 1 */ - CLKPR = 0; -#endif - /* Initialize I/O ports */ - /* For Port DDRx (Data Direction) Input=0, Output=1 */ - /* For Port PORTx (Bit Value) TriState=0, High=1 */ - DDRB = 0; - PORTB = 0; - DDRC = 0; - PORTC = 0; - DDRD = 0; - PORTD = 0; - - /* Configure the watchdog timer - Disabled for testing */ -#if defined(__AVR_ATmega168__) - BIT_CLEAR(MCUSR, WDRF); - WDTCSR = 0; -#else - BIT_CLEAR(MCUCSR, WDRF); - WDTCR = 0; -#endif - - /* Configure Specialized Hardware */ - RS485_Initialize(); - RS485_Set_Baud_Rate(38400); - /* Configure Timer0 for millisecond timer */ - timer_init(); - /* Enable global interrupts */ - __enable_interrupt(); -} - -static uint8_t PDUBuffer[MAX_MPDU]; - -int main( - void) -{ - uint16_t pdu_len = 0; - BACNET_ADDRESS src; /* source address */ - - init(); - datalink_init(NULL); - for (;;) { - /* other tasks */ - /* BACnet handling */ - pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); - if (pdu_len) { - npdu_handler(&src, &PDUBuffer[0], pdu_len); - } - } -} +/************************************************************************** +* +* Copyright (C) 2007 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +#include +#include +#include "hardware.h" +#include "timer.h" +#include "rs485.h" +#include "datalink.h" +#include "npdu.h" +#include "txbuf.h" +#include "iam.h" +#include "device.h" +#include "av.h" +#include "handlers.h" + +/* local version override */ +const char *BACnet_Version = "1.0"; + +/* For porting to IAR, see: + http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ + +/* dummy function - so we can use default demo handlers */ +bool dcc_communication_enabled( + void) +{ + return true; +} + +static void init( + void) +{ + /* FIXME: Initialize the Clock Prescaler for ATmega8 */ +#if defined(__AVR_ATmega168__) + /* The default CLKPSx bits are factory set to 0011 */ + /* Enbable the Clock Prescaler */ + CLKPR = _BV(CLKPCE); + /* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor + ------ ------ ------ ------ --------------------- + 0 0 0 0 1 + 0 0 0 1 2 + 0 0 1 0 4 + 0 0 1 1 8 + 0 1 0 0 16 + 0 1 0 1 32 + 0 1 1 0 64 + 0 1 1 1 128 + 1 0 0 0 256 + 1 x x x Reserved + */ + /* Set the CLKPS3..0 bits to Prescaler of 1 */ + CLKPR = 0; +#endif + /* Initialize I/O ports */ + /* For Port DDRx (Data Direction) Input=0, Output=1 */ + /* For Port PORTx (Bit Value) TriState=0, High=1 */ + DDRB = 0; + PORTB = 0; + DDRC = 0; + PORTC = 0; + DDRD = 0; + PORTD = 0; + + /* Configure the watchdog timer - Disabled for testing */ +#if defined(__AVR_ATmega168__) + BIT_CLEAR(MCUSR, WDRF); + WDTCSR = 0; +#else + BIT_CLEAR(MCUCSR, WDRF); + WDTCR = 0; +#endif + + /* Configure Specialized Hardware */ + RS485_Initialize(); + RS485_Set_Baud_Rate(38400); + /* Configure Timer0 for millisecond timer */ + timer_init(); + /* Enable global interrupts */ + __enable_interrupt(); +} + +static uint8_t PDUBuffer[MAX_MPDU]; + +int main( + void) +{ + uint16_t pdu_len = 0; + BACNET_ADDRESS src; /* source address */ + + init(); + datalink_init(NULL); + for (;;) { + /* other tasks */ + /* BACnet handling */ + pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); + if (pdu_len) { + npdu_handler(&src, &PDUBuffer[0], pdu_len); + } + } +} diff --git a/bacnet-stack/ports/atmega8/rs485.c b/bacnet-stack/ports/atmega8/rs485.c index 3c57b72f..40eada2e 100644 --- a/bacnet-stack/ports/atmega8/rs485.c +++ b/bacnet-stack/ports/atmega8/rs485.c @@ -1,292 +1,292 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ - -/* The module handles sending data out the RS-485 port */ -/* and handles receiving data from the RS-485 port. */ -/* Customize this file for your specific hardware */ -#include -#include -#include -#include -#include -/*#include "mstp.h" */ - -/* This file has been customized for use with ATMEGA168 */ -#if defined(__AVR_ATmega168__) - /* USART defines for RS-485 port */ - #define UCSRB UCSR0B - #define TXEN TXEN0 - #define RXEN RXEN0 - #define UCSRC UCSR0C - #define UCSZ1 UCSZ01 - #define UCSZ0 UCSZ00 - #define UCSRA UCSR0A - #define U2X U2X0 - #define UBRRL UBRR0 - #define UCSRA UCSR0A - #define UDRE UDRE0 - #define UDR UDR0 - #define TXC TXC0 - #define FE FE0 - #define DOR DOR0 - #define UPE UPE0 - #define DOR DOR0 - #define RXC RXC0 -#endif - -#include "hardware.h" -#include "timer.h" - -/* baud rate */ -static uint32_t RS485_Baud; - -/* The minimum time after the end of the stop bit of the final octet of a */ -/* received frame before a node may enable its EIA-485 driver: 40 bit times. */ -/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */ -/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */ -/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */ -/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */ -/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */ -/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */ -/* 40 bits is 4 octets including a start and stop bit with each octet */ -#define Tturnaround (40UL) -/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */ - -/**************************************************************************** -* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in -* receive mode. -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Initialize( - void) -{ - /* enable Transmit and Receive */ - UCSRB = _BV(TXEN) | _BV(RXEN); - - /* Set USART Control and Status Register n C */ - /* Asynchronous USART 8-bit data, No parity, 1 stop */ - /* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */ - /* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */ - /* Set Stop Bit Select: USBSn = 0 for 1 stop bit */ - /* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */ - /* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */ - UCSRC = _BV(UCSZ1) | _BV(UCSZ0); -#if defined(__AVR_ATmega168__) - /* Clear Power Reduction USART0 */ - BIT_CLEAR(PRR, PRUSART0); -#endif - /* Use port PD2 for RTS - enable and disable of Transceiver Tx/Rx */ - /* Set port bit as Output - initially receiving */ - BIT_CLEAR(PORTD, PD2); - BIT_SET(DDRD, DDD2); - - return; -} - -/**************************************************************************** -* DESCRIPTION: Returns the baud rate that we are currently running at -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -uint32_t RS485_Get_Baud_Rate( - void) -{ - return RS485_Baud; -} - -/**************************************************************************** -* DESCRIPTION: Sets the baud rate for the chip USART -* RETURN: true if valid baud rate -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool RS485_Set_Baud_Rate( - uint32_t baud) -{ - bool valid = true; - - switch (baud) { - case 9600: - case 19200: - case 38400: - case 57600: - case 76800: - case 115200: - RS485_Baud = baud; - /* 2x speed mode */ - BIT_SET(UCSRA, U2X); - /* configure baud rate */ - UBRRL = (F_CPU / (8UL * RS485_Baud)) - 1; - /* FIXME: store the baud rate */ - break; - default: - valid = false; - break; - } - - return valid; -} - -/**************************************************************************** -* DESCRIPTION: Waits on the SilenceTimer for 40 bits. -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Turnaround_Delay( - void) -{ - uint16_t turnaround_time; - - /* delay after reception before trasmitting - per MS/TP spec */ - /* wait a minimum 40 bit times since reception */ - /* at least 1 ms for errors: rounding, clock tick */ - turnaround_time = 1 + ((Tturnaround * 1000UL) / RS485_Baud); - while (!timer_silence_elapsed(turnaround_time)) { - /* do nothing - wait for timer to increment */ - }; -} - -/**************************************************************************** -* DESCRIPTION: Enable or disable the transmitter -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Transmitter_Enable( - bool enable) -{ - if (enable) { - BIT_SET(PORTD, PD2); - } else { - BIT_CLEAR(PORTD, PD2); - } -} - -/**************************************************************************** -* DESCRIPTION: Send some data and wait until it is sent -* RETURN: none -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -void RS485_Send_Data( - uint8_t * buffer, /* data to send */ - uint16_t nbytes) -{ /* number of bytes of data */ - while (nbytes) { - while (!BIT_CHECK(UCSRA, UDRE)) { - /* do nothing - wait until Tx buffer is empty */ - } - /* Send the data byte */ - UDR = *buffer; - buffer++; - nbytes--; - } - /* was the frame sent? */ - while (!BIT_CHECK(UCSRA, TXC)) { - /* do nothing - wait until the entire frame in the - Transmit Shift Register has been shifted out */ - } - /* Clear the Transmit Complete flag by writing a one to it. */ - BIT_SET(UCSRA, TXC); - /* per MSTP spec, sort of */ - timer_silence_reset(); -} - - -/**************************************************************************** -* DESCRIPTION: Return true if a framing or overrun error is present -* RETURN: true if error -* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate -* NOTES: Clears any error flags. -*****************************************************************************/ -bool RS485_ReceiveError( - void) -{ - bool ReceiveError = false; - uint8_t dummy_data; - - /* check for framing error */ -#if 0 - if (BIT_CHECK(UCSRA, FE0)) { - /* FIXME: how do I clear the error flags? */ - BITMASK_CLEAR(UCSRA, (_BV(FE) | _BV(DOR) | _BV(UPE))); - ReceiveError = true; - } -#endif - /* check for overrun error */ - if (BIT_CHECK(UCSRA, DOR)) { - /* flush the receive buffer */ - do { - dummy_data = UDR; - } while (BIT_CHECK(UCSRA, RXC)); - ReceiveError = true; - } - - return ReceiveError; -} - -/**************************************************************************** -* DESCRIPTION: Return true if data is available -* RETURN: true if data is available, with the data in the parameter set -* ALGORITHM: none -* NOTES: none -*****************************************************************************/ -bool RS485_DataAvailable( - uint8_t * data) -{ - bool DataAvailable = false; - - /* check for data */ - if (BIT_CHECK(UCSRA, RXC)) { - *data = UDR; - DataAvailable = true; - } - - return DataAvailable; -} - -#ifdef TEST_RS485 -int main( - void) -{ - unsigned i = 0; - uint8_t DataRegister; - - RS485_Set_Baud_Rate(38400); - RS485_Initialize(); - /* receive task */ - for (;;) { - if (RS485_ReceiveError()) { - fprintf(stderr, "ERROR "); - } else if (RS485_DataAvailable(&DataRegister)) { - fprintf(stderr, "%02X ", DataRegister); - } - } -} -#endif /* TEST_RS485 */ +/************************************************************************** +* +* Copyright (C) 2007 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ + +/* The module handles sending data out the RS-485 port */ +/* and handles receiving data from the RS-485 port. */ +/* Customize this file for your specific hardware */ +#include +#include +#include +#include +#include +/*#include "mstp.h" */ + +/* This file has been customized for use with ATMEGA168 */ +#if defined(__AVR_ATmega168__) + /* USART defines for RS-485 port */ +#define UCSRB UCSR0B +#define TXEN TXEN0 +#define RXEN RXEN0 +#define UCSRC UCSR0C +#define UCSZ1 UCSZ01 +#define UCSZ0 UCSZ00 +#define UCSRA UCSR0A +#define U2X U2X0 +#define UBRRL UBRR0 +#define UCSRA UCSR0A +#define UDRE UDRE0 +#define UDR UDR0 +#define TXC TXC0 +#define FE FE0 +#define DOR DOR0 +#define UPE UPE0 +#define DOR DOR0 +#define RXC RXC0 +#endif + +#include "hardware.h" +#include "timer.h" + +/* baud rate */ +static uint32_t RS485_Baud; + +/* The minimum time after the end of the stop bit of the final octet of a */ +/* received frame before a node may enable its EIA-485 driver: 40 bit times. */ +/* At 9600 baud, 40 bit times would be about 4.166 milliseconds */ +/* At 19200 baud, 40 bit times would be about 2.083 milliseconds */ +/* At 38400 baud, 40 bit times would be about 1.041 milliseconds */ +/* At 57600 baud, 40 bit times would be about 0.694 milliseconds */ +/* At 76800 baud, 40 bit times would be about 0.520 milliseconds */ +/* At 115200 baud, 40 bit times would be about 0.347 milliseconds */ +/* 40 bits is 4 octets including a start and stop bit with each octet */ +#define Tturnaround (40UL) +/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */ + +/**************************************************************************** +* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in +* receive mode. +* RETURN: none +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +void RS485_Initialize( + void) +{ + /* enable Transmit and Receive */ + UCSRB = _BV(TXEN) | _BV(RXEN); + + /* Set USART Control and Status Register n C */ + /* Asynchronous USART 8-bit data, No parity, 1 stop */ + /* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */ + /* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */ + /* Set Stop Bit Select: USBSn = 0 for 1 stop bit */ + /* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */ + /* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */ + UCSRC = _BV(UCSZ1) | _BV(UCSZ0); +#if defined(__AVR_ATmega168__) + /* Clear Power Reduction USART0 */ + BIT_CLEAR(PRR, PRUSART0); +#endif + /* Use port PD2 for RTS - enable and disable of Transceiver Tx/Rx */ + /* Set port bit as Output - initially receiving */ + BIT_CLEAR(PORTD, PD2); + BIT_SET(DDRD, DDD2); + + return; +} + +/**************************************************************************** +* DESCRIPTION: Returns the baud rate that we are currently running at +* RETURN: none +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +uint32_t RS485_Get_Baud_Rate( + void) +{ + return RS485_Baud; +} + +/**************************************************************************** +* DESCRIPTION: Sets the baud rate for the chip USART +* RETURN: true if valid baud rate +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +bool RS485_Set_Baud_Rate( + uint32_t baud) +{ + bool valid = true; + + switch (baud) { + case 9600: + case 19200: + case 38400: + case 57600: + case 76800: + case 115200: + RS485_Baud = baud; + /* 2x speed mode */ + BIT_SET(UCSRA, U2X); + /* configure baud rate */ + UBRRL = (F_CPU / (8UL * RS485_Baud)) - 1; + /* FIXME: store the baud rate */ + break; + default: + valid = false; + break; + } + + return valid; +} + +/**************************************************************************** +* DESCRIPTION: Waits on the SilenceTimer for 40 bits. +* RETURN: none +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +void RS485_Turnaround_Delay( + void) +{ + uint16_t turnaround_time; + + /* delay after reception before trasmitting - per MS/TP spec */ + /* wait a minimum 40 bit times since reception */ + /* at least 1 ms for errors: rounding, clock tick */ + turnaround_time = 1 + ((Tturnaround * 1000UL) / RS485_Baud); + while (!timer_silence_elapsed(turnaround_time)) { + /* do nothing - wait for timer to increment */ + }; +} + +/**************************************************************************** +* DESCRIPTION: Enable or disable the transmitter +* RETURN: none +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +void RS485_Transmitter_Enable( + bool enable) +{ + if (enable) { + BIT_SET(PORTD, PD2); + } else { + BIT_CLEAR(PORTD, PD2); + } +} + +/**************************************************************************** +* DESCRIPTION: Send some data and wait until it is sent +* RETURN: none +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +void RS485_Send_Data( + uint8_t * buffer, /* data to send */ + uint16_t nbytes) +{ /* number of bytes of data */ + while (nbytes) { + while (!BIT_CHECK(UCSRA, UDRE)) { + /* do nothing - wait until Tx buffer is empty */ + } + /* Send the data byte */ + UDR = *buffer; + buffer++; + nbytes--; + } + /* was the frame sent? */ + while (!BIT_CHECK(UCSRA, TXC)) { + /* do nothing - wait until the entire frame in the + Transmit Shift Register has been shifted out */ + } + /* Clear the Transmit Complete flag by writing a one to it. */ + BIT_SET(UCSRA, TXC); + /* per MSTP spec, sort of */ + timer_silence_reset(); +} + + +/**************************************************************************** +* DESCRIPTION: Return true if a framing or overrun error is present +* RETURN: true if error +* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate +* NOTES: Clears any error flags. +*****************************************************************************/ +bool RS485_ReceiveError( + void) +{ + bool ReceiveError = false; + uint8_t dummy_data; + + /* check for framing error */ +#if 0 + if (BIT_CHECK(UCSRA, FE0)) { + /* FIXME: how do I clear the error flags? */ + BITMASK_CLEAR(UCSRA, (_BV(FE) | _BV(DOR) | _BV(UPE))); + ReceiveError = true; + } +#endif + /* check for overrun error */ + if (BIT_CHECK(UCSRA, DOR)) { + /* flush the receive buffer */ + do { + dummy_data = UDR; + } while (BIT_CHECK(UCSRA, RXC)); + ReceiveError = true; + } + + return ReceiveError; +} + +/**************************************************************************** +* DESCRIPTION: Return true if data is available +* RETURN: true if data is available, with the data in the parameter set +* ALGORITHM: none +* NOTES: none +*****************************************************************************/ +bool RS485_DataAvailable( + uint8_t * data) +{ + bool DataAvailable = false; + + /* check for data */ + if (BIT_CHECK(UCSRA, RXC)) { + *data = UDR; + DataAvailable = true; + } + + return DataAvailable; +} + +#ifdef TEST_RS485 +int main( + void) +{ + unsigned i = 0; + uint8_t DataRegister; + + RS485_Set_Baud_Rate(38400); + RS485_Initialize(); + /* receive task */ + for (;;) { + if (RS485_ReceiveError()) { + fprintf(stderr, "ERROR "); + } else if (RS485_DataAvailable(&DataRegister)) { + fprintf(stderr, "%02X ", DataRegister); + } + } +} +#endif /* TEST_RS485 */ diff --git a/bacnet-stack/ports/atmega8/rs485.h b/bacnet-stack/ports/atmega8/rs485.h index fe0dd706..9657c01d 100644 --- a/bacnet-stack/ports/atmega8/rs485.h +++ b/bacnet-stack/ports/atmega8/rs485.h @@ -1,70 +1,70 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2004 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#ifndef RS485_H -#define RS485_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void RS485_Initialize( - void); - - void RS485_Transmitter_Enable( - bool enable); - - void RS485_Send_Data( - uint8_t * buffer, /* data to send */ - uint16_t nbytes); /* number of bytes of data */ - - bool RS485_ReceiveError( - void); - bool RS485_DataAvailable( - uint8_t * data); - - void RS485_Turnaround_Delay( - void); - uint32_t RS485_Get_Baud_Rate( - void); - bool RS485_Set_Baud_Rate( - uint32_t baud); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2004 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307 + USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#ifndef RS485_H +#define RS485_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void RS485_Initialize( + void); + + void RS485_Transmitter_Enable( + bool enable); + + void RS485_Send_Data( + uint8_t * buffer, /* data to send */ + uint16_t nbytes); /* number of bytes of data */ + + bool RS485_ReceiveError( + void); + bool RS485_DataAvailable( + uint8_t * data); + + void RS485_Turnaround_Delay( + void); + uint32_t RS485_Get_Baud_Rate( + void); + bool RS485_Set_Baud_Rate( + uint32_t baud); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/atmega8/stdbool.h b/bacnet-stack/ports/atmega8/stdbool.h index 80e1ee96..39c1c286 100644 --- a/bacnet-stack/ports/atmega8/stdbool.h +++ b/bacnet-stack/ports/atmega8/stdbool.h @@ -1,28 +1,28 @@ -#ifndef STDBOOL_H -#define STDBOOL_H - -/* C99 Boolean types for compilers without C99 support */ - -#ifndef __cplusplus -/* typedef char _Bool; */ -#ifndef bool -#define bool _Bool -#endif -#ifndef true -#define true 1 -#endif -#ifndef false -#define false 0 -#endif -#define __bool_true_false_are_defined 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#endif +#ifndef STDBOOL_H +#define STDBOOL_H + +/* C99 Boolean types for compilers without C99 support */ + +#ifndef __cplusplus +/* typedef char _Bool; */ +#ifndef bool +#define bool _Bool +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif +#define __bool_true_false_are_defined 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#endif diff --git a/bacnet-stack/ports/atmega8/stdint.h b/bacnet-stack/ports/atmega8/stdint.h index 93556b05..874f309d 100644 --- a/bacnet-stack/ports/atmega8/stdint.h +++ b/bacnet-stack/ports/atmega8/stdint.h @@ -1,15 +1,15 @@ -/* Defines the standard integer types that are used in code */ - -#ifndef STDINT_H -#define STDINT_H 1 - -#include - -typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ -typedef signed char int8_t; /* 1 byte -127 to 127 */ -typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ -typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ -typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ -typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ - -#endif /* STDINT_H */ +/* Defines the standard integer types that are used in code */ + +#ifndef STDINT_H +#define STDINT_H 1 + +#include + +typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ +typedef signed char int8_t; /* 1 byte -127 to 127 */ +typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ +typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ +typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ +typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ + +#endif /* STDINT_H */ diff --git a/bacnet-stack/ports/atmega8/timer.c b/bacnet-stack/ports/atmega8/timer.c index 49d1190d..26ea10b3 100644 --- a/bacnet-stack/ports/atmega8/timer.c +++ b/bacnet-stack/ports/atmega8/timer.c @@ -1,109 +1,110 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#include -#include -#include "hardware.h" - -/* This module is a 1 millisecond timer */ - -/* Prescaling: 1, 8, 64, 256, 1024 */ -#define TIMER_PRESCALER 64 -/* Count: Timer0 counts up to 0xFF and then signals overflow */ -#define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000) -#if (TIMER_TICKS > 0xFF) -#error Timer Prescaler value is too small -#endif -#define TIMER_COUNT (0xFF-TIMER_TICKS) -/* millisecond timer count */ -static volatile uint16_t Timer_Silence; - -/* FIXME: Configure the Timer */ -void timer_init( - void) -{ - /* Normal Operation */ - TCCR1A = 0; - /* CSn2 CSn1 CSn0 Description - ---- ---- ---- ----------- - 0 0 0 No Clock Source - 0 0 1 No prescaling - 0 1 0 CLKio/8 - 0 1 1 CLKio/64 - 1 0 0 CLKio/256 - 1 0 1 CLKio/1024 - 1 1 0 Falling Edge of T0 (external) - 1 1 1 Rising Edge of T0 (external) - */ -#if defined(__AVR_ATmega168__) - TCCR0B = _BV(CS01) | _BV(CS00); - /* Clear any TOV1 Flag set when the timer overflowed */ - BIT_CLEAR(TIFR0, TOV0); - /* Initial value */ - TCNT0 = TIMER_COUNT; - /* Enable the overflow interrupt */ - BIT_SET(TIMSK0, TOIE0); - /* Clear the Power Reduction Timer/Counter0 */ - BIT_CLEAR(PRR, PRTIM0); -#endif -} - -/* Timer interupt */ -/* note: Global interupts must be enabled - sei() */ -/* Timer Overflowed! Increment the time. */ -ISR(TIMER0_OVF_vect) -{ - /* Set the counter for the next interrupt */ - TCNT0 = TIMER_COUNT; - /* Overflow Flag is automatically cleared */ - /* Update the global timer */ - Timer_Silence++; -} - -/* return true if time has expired */ -bool timer_silence_elapsed( - uint16_t value) -{ - bool status = false; - uint8_t sreg; - - sreg = SREG; - __disable_interrupt(); - if (Timer_Silence >= value) { - status = true; - } - SREG = sreg; - - return status; -} - -void timer_silence_reset(void) -{ - uint8_t sreg; - - sreg = SREG; - __disable_interrupt(); - Timer_Silence = 0; - SREG = sreg; -} +/************************************************************************** +* +* Copyright (C) 2007 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#include +#include +#include "hardware.h" + +/* This module is a 1 millisecond timer */ + +/* Prescaling: 1, 8, 64, 256, 1024 */ +#define TIMER_PRESCALER 64 +/* Count: Timer0 counts up to 0xFF and then signals overflow */ +#define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000) +#if (TIMER_TICKS > 0xFF) +#error Timer Prescaler value is too small +#endif +#define TIMER_COUNT (0xFF-TIMER_TICKS) +/* millisecond timer count */ +static volatile uint16_t Timer_Silence; + +/* FIXME: Configure the Timer */ +void timer_init( + void) +{ + /* Normal Operation */ + TCCR1A = 0; + /* CSn2 CSn1 CSn0 Description + ---- ---- ---- ----------- + 0 0 0 No Clock Source + 0 0 1 No prescaling + 0 1 0 CLKio/8 + 0 1 1 CLKio/64 + 1 0 0 CLKio/256 + 1 0 1 CLKio/1024 + 1 1 0 Falling Edge of T0 (external) + 1 1 1 Rising Edge of T0 (external) + */ +#if defined(__AVR_ATmega168__) + TCCR0B = _BV(CS01) | _BV(CS00); + /* Clear any TOV1 Flag set when the timer overflowed */ + BIT_CLEAR(TIFR0, TOV0); + /* Initial value */ + TCNT0 = TIMER_COUNT; + /* Enable the overflow interrupt */ + BIT_SET(TIMSK0, TOIE0); + /* Clear the Power Reduction Timer/Counter0 */ + BIT_CLEAR(PRR, PRTIM0); +#endif +} + +/* Timer interupt */ +/* note: Global interupts must be enabled - sei() */ +/* Timer Overflowed! Increment the time. */ +ISR(TIMER0_OVF_vect) +{ + /* Set the counter for the next interrupt */ + TCNT0 = TIMER_COUNT; + /* Overflow Flag is automatically cleared */ + /* Update the global timer */ + Timer_Silence++; +} + +/* return true if time has expired */ +bool timer_silence_elapsed( + uint16_t value) +{ + bool status = false; + uint8_t sreg; + + sreg = SREG; + __disable_interrupt(); + if (Timer_Silence >= value) { + status = true; + } + SREG = sreg; + + return status; +} + +void timer_silence_reset( + void) +{ + uint8_t sreg; + + sreg = SREG; + __disable_interrupt(); + Timer_Silence = 0; + SREG = sreg; +} diff --git a/bacnet-stack/ports/atmega8/timer.h b/bacnet-stack/ports/atmega8/timer.h index 9e6d207b..7858ec56 100644 --- a/bacnet-stack/ports/atmega8/timer.h +++ b/bacnet-stack/ports/atmega8/timer.h @@ -1,42 +1,42 @@ -/************************************************************************** -* -* Copyright (C) 2007 Steve Karg -* -* Permission is hereby granted, free of charge, to any person obtaining -* a copy of this software and associated documentation files (the -* "Software"), to deal in the Software without restriction, including -* without limitation the rights to use, copy, modify, merge, publish, -* distribute, sublicense, and/or sell copies of the Software, and to -* permit persons to whom the Software is furnished to do so, subject to -* the following conditions: -* -* The above copyright notice and this permission notice shall be included -* in all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -* -*********************************************************************/ -#ifndef TIMER_H -#define TIMER_H - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - void timer_init( - void); - bool timer_silence_elapsed( - uint16_t value); - void timer_silence_reset( - void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif +/************************************************************************** +* +* Copyright (C) 2007 Steve Karg +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +* +*********************************************************************/ +#ifndef TIMER_H +#define TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + void timer_init( + void); + bool timer_silence_elapsed( + uint16_t value); + void timer_silence_reset( + void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif diff --git a/bacnet-stack/ports/linux/mstpsnap.c b/bacnet-stack/ports/linux/mstpsnap.c index f64d7452..71c011be 100644 --- a/bacnet-stack/ports/linux/mstpsnap.c +++ b/bacnet-stack/ports/linux/mstpsnap.c @@ -170,7 +170,7 @@ static void snap_received_packet( { uint16_t mtu_len = 0; /* number of octets of packet saved in file */ unsigned i = 0; /* counter */ - static uint8_t mtu[1500] = { 0 }; + static uint8_t mtu[1500] = { 0 }; uint16_t max_data = 0; mtu[0] = 0; @@ -204,8 +204,8 @@ static void snap_received_packet( mtu[29] = LO_BYTE(mstp_port->DataLength); mtu[30] = mstp_port->HeaderCRCActual; mtu_len = 31; - if (mstp_port->DataLength) { - max_data = min(mstp_port->InputBufferSize,mstp_port->DataLength); + if (mstp_port->DataLength) { + max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength); for (i = 0; i < max_data; i++) { mtu[31 + i] = mstp_port->InputBuffer[i]; } diff --git a/bacnet-stack/ports/linux/rx_fsm.c b/bacnet-stack/ports/linux/rx_fsm.c index 8262defc..9c46c6ce 100644 --- a/bacnet-stack/ports/linux/rx_fsm.c +++ b/bacnet-stack/ports/linux/rx_fsm.c @@ -217,8 +217,8 @@ static void write_received_packet( fwrite(header, sizeof(header), 1, pFile); if (mstp_port->DataLength) { fwrite(mstp_port->InputBuffer, max_data, 1, pFile); - fwrite((char *)&(mstp_port->DataCRCActualMSB), 1, 1, pFile); - fwrite((char *)&(mstp_port->DataCRCActualLSB), 1, 1, pFile); + fwrite((char *) &(mstp_port->DataCRCActualMSB), 1, 1, pFile); + fwrite((char *) &(mstp_port->DataCRCActualLSB), 1, 1, pFile); } } else { fprintf(stderr, "rx_fsm: failed to open %s: %s\n", Capture_Filename, diff --git a/bacnet-stack/ports/win32/bip-init.c b/bacnet-stack/ports/win32/bip-init.c index f561c0ec..2591ceec 100644 --- a/bacnet-stack/ports/win32/bip-init.c +++ b/bacnet-stack/ports/win32/bip-init.c @@ -381,7 +381,7 @@ bool bip_init( bip_set_socket(-1); return false; } - /* Enables transmission and receipt of broadcast messages on the socket.*/ + /* Enables transmission and receipt of broadcast messages on the socket. */ rv = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, (char *) &value, sizeof(value)); if (rv < 0) { diff --git a/bacnet-stack/ports/win32/main.c b/bacnet-stack/ports/win32/main.c index e5021ebf..9c6a11c7 100644 --- a/bacnet-stack/ports/win32/main.c +++ b/bacnet-stack/ports/win32/main.c @@ -294,14 +294,13 @@ static void Init_DataLink( #endif } -int main( - int argc, - char *argv[]) -{ - BACNET_ADDRESS src = { 0 }; /* address where message came from */ +int main(int argc, char *argv[]) { + BACNET_ADDRESS src = { + 0}; /* address where message came from */ uint16_t pdu_len = 0; unsigned timeout = 100; /* milliseconds */ - BACNET_ADDRESS my_address, broadcast_address; + BACNET_ADDRESS my_address, + broadcast_address; (void) argc; (void) argv; diff --git a/bacnet-stack/ports/win32/rx_fsm.c b/bacnet-stack/ports/win32/rx_fsm.c index cfef59ca..1be2184b 100644 --- a/bacnet-stack/ports/win32/rx_fsm.c +++ b/bacnet-stack/ports/win32/rx_fsm.c @@ -245,7 +245,7 @@ static void write_received_packet( fwrite(&ts_sec, sizeof(ts_sec), 1, pFile); fwrite(&ts_usec, sizeof(ts_usec), 1, pFile); if (mstp_port->DataLength) { - max_data = min(mstp_port->InputBufferSize,mstp_port->DataLength); + max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength); incl_len = orig_len = 8 + max_data + 2; } else { incl_len = orig_len = 8; diff --git a/bacnet-stack/ports/win32/stdbool.h b/bacnet-stack/ports/win32/stdbool.h index c55e9086..725940b3 100644 --- a/bacnet-stack/ports/win32/stdbool.h +++ b/bacnet-stack/ports/win32/stdbool.h @@ -1,7 +1,7 @@ #ifndef _STDBOOL_H #define _STDBOOL_H -#include +#include /* C99 Boolean types for compilers without C99 support */ /* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */ @@ -14,7 +14,7 @@ the values 0 and 1. */ /* We choose 8 bit to match C++ */ /* It must also promote to integer */ -typedef int8_t _Bool; +typedef int8_t _Bool; #endif /* ISO C Standard: 7.16 Boolean type */ diff --git a/bacnet-stack/src/arf.c b/bacnet-stack/src/arf.c index f3d87899..bc885783 100644 --- a/bacnet-stack/src/arf.c +++ b/bacnet-stack/src/arf.c @@ -95,7 +95,7 @@ int arf_decode_service_request( int tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ /* check for value pointers */ if (apdu_len && data) { diff --git a/bacnet-stack/src/awf.c b/bacnet-stack/src/awf.c index cdb4257a..d25c8a28 100644 --- a/bacnet-stack/src/awf.c +++ b/bacnet-stack/src/awf.c @@ -100,7 +100,7 @@ int awf_decode_service_request( uint32_t len_value_type = 0; int32_t signed_value = 0; uint32_t unsigned_value = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ /* check for value pointers */ if (apdu_len && data) { diff --git a/bacnet-stack/src/bacdcode.c b/bacnet-stack/src/bacdcode.c index ea7a64e0..f32b23b4 100644 --- a/bacnet-stack/src/bacdcode.c +++ b/bacnet-stack/src/bacdcode.c @@ -303,7 +303,7 @@ int encode_closing_tag( static bool decode_is_extended_tag_number( uint8_t * apdu) { - return (bool)((apdu[0] & 0xF0) == 0xF0); + return (bool) ((apdu[0] & 0xF0) == 0xF0); } /* from clause 20.2.1.3.2 Constructed Data */ @@ -311,7 +311,7 @@ static bool decode_is_extended_tag_number( static bool decode_is_extended_value( uint8_t * apdu) { - return (bool)((apdu[0] & 0x07) == 5); + return (bool) ((apdu[0] & 0x07) == 5); } /* from clause 20.2.1.3.2 Constructed Data */ @@ -319,7 +319,7 @@ static bool decode_is_extended_value( bool decode_is_context_specific( uint8_t * apdu) { - return (bool)((apdu[0] & BIT3) == BIT3); + return (bool) ((apdu[0] & BIT3) == BIT3); } int decode_tag_number( @@ -337,7 +337,7 @@ int decode_tag_number( len++; } else { if (tag_number) { - *tag_number = (uint8_t)(apdu[0] >> 4); + *tag_number = (uint8_t) (apdu[0] >> 4); } } @@ -347,7 +347,7 @@ int decode_tag_number( bool decode_is_opening_tag( uint8_t * apdu) { - return (bool)((apdu[0] & 0x07) == 6); + return (bool) ((apdu[0] & 0x07) == 6); } /* from clause 20.2.1.3.2 Constructed Data */ @@ -355,7 +355,7 @@ bool decode_is_opening_tag( bool decode_is_closing_tag( uint8_t * apdu) { - return (bool)((apdu[0] & 0x07) == 7); + return (bool) ((apdu[0] & 0x07) == 7); } /* from clause 20.2.1.3.2 Constructed Data */ @@ -420,13 +420,13 @@ bool decode_is_context_tag( context_specific = decode_is_context_specific(apdu); decode_tag_number(apdu, &my_tag_number); - return (bool)(context_specific && (my_tag_number == tag_number)); + return (bool) (context_specific && (my_tag_number == tag_number)); } bool decode_is_context_tag_with_length( uint8_t * apdu, uint8_t tag_number, - int * tag_length) + int *tag_length) { uint8_t my_tag_number = 0; bool context_specific = false; @@ -435,7 +435,7 @@ bool decode_is_context_tag_with_length( context_specific = decode_is_context_specific(apdu); *tag_length = decode_tag_number(apdu, &my_tag_number); - return (bool)(context_specific && (my_tag_number == tag_number)); + return (bool) (context_specific && (my_tag_number == tag_number)); } /* from clause 20.2.1.3.2 Constructed Data */ @@ -447,10 +447,10 @@ bool decode_is_opening_tag_number( uint8_t my_tag_number = 0; bool opening_tag = false; - opening_tag = (bool)((apdu[0] & 0x07) == 6); + opening_tag = (bool) ((apdu[0] & 0x07) == 6); decode_tag_number(apdu, &my_tag_number); - return (bool)(opening_tag && (my_tag_number == tag_number)); + return (bool) (opening_tag && (my_tag_number == tag_number)); } /* from clause 20.2.1.3.2 Constructed Data */ @@ -462,10 +462,10 @@ bool decode_is_closing_tag_number( uint8_t my_tag_number = 0; bool closing_tag = false; - closing_tag = (bool)((apdu[0] & 0x07) == 7); + closing_tag = (bool) ((apdu[0] & 0x07) == 7); decode_tag_number(apdu, &my_tag_number); - return (bool)(closing_tag && (my_tag_number == tag_number)); + return (bool) (closing_tag && (my_tag_number == tag_number)); } /* from clause 20.2.3 Encoding of a Boolean Value */ @@ -496,7 +496,7 @@ int encode_context_boolean( int len = 0; /* return value */ len = encode_tag(&apdu[0], (uint8_t) tag_number, true, 1); - apdu[len] = (bool)(boolean_value ? 1 : 0); + apdu[len] = (bool) (boolean_value ? 1 : 0); len++; return len; @@ -517,24 +517,20 @@ bool decode_context_boolean( int decode_context_boolean2( uint8_t * apdu, uint8_t tag_number, - bool *boolean_value) + bool * boolean_value) { - int len = 0; - if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { - if (apdu[len]) { - *boolean_value = true; - } - else - { - *boolean_value = false; - } - len++; - } - else - { - len = -1; - } - return len; + int len = 0; + if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { + if (apdu[len]) { + *boolean_value = true; + } else { + *boolean_value = false; + } + len++; + } else { + len = -1; + } + return len; } /* from clause 20.2.3 Encoding of a Boolean Value */ @@ -624,7 +620,7 @@ int decode_bitstring( bitstring_set_octet(bit_string, (uint8_t) i, byte_reverse_bits(apdu[len++])); } - unused_bits = (uint8_t)(apdu[0] & 0x07); + unused_bits = (uint8_t) (apdu[0] & 0x07); bitstring_set_bits_used(bit_string, (uint8_t) bytes_used, unused_bits); } @@ -635,22 +631,20 @@ int decode_bitstring( int decode_context_bitstring( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_BIT_STRING * bit_string) { uint32_t len_value; - int len = 0; + int len = 0; - if (decode_is_context_tag(&apdu[len], tag_number)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_bitstring(&apdu[len], len_value, bit_string); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag(&apdu[len], tag_number)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len += decode_bitstring(&apdu[len], len_value, bit_string); + } else { + len = -1; + } + return len; } @@ -671,9 +665,10 @@ int encode_bitstring( } else { used_bytes = bitstring_bytes_used(bit_string); remaining_used_bits = - (uint8_t)(bitstring_bits_used(bit_string) - ((used_bytes - 1) * 8)); + (uint8_t) (bitstring_bits_used(bit_string) - ((used_bytes - + 1) * 8)); /* number of unused bits in the subsequent final octet */ - apdu[len++] = (uint8_t)(8 - remaining_used_bits); + apdu[len++] = (uint8_t) (8 - remaining_used_bits); for (i = 0; i < used_bytes; i++) { apdu[len++] = byte_reverse_bits(bitstring_octet(bit_string, i)); } @@ -721,35 +716,34 @@ int encode_context_bitstring( /* returns the number of apdu bytes consumed */ int decode_object_id( uint8_t * apdu, - uint16_t *object_type, + uint16_t * object_type, uint32_t * instance) { uint32_t value = 0; int len = 0; len = decode_unsigned32(apdu, &value); - *object_type = (uint16_t)(((value >> BACNET_INSTANCE_BITS) & BACNET_MAX_OBJECT)); + *object_type = + (uint16_t) (((value >> BACNET_INSTANCE_BITS) & BACNET_MAX_OBJECT)); *instance = (value & BACNET_MAX_INSTANCE); return len; } int decode_context_object_id( - uint8_t * apdu, - uint8_t tag_number, + uint8_t * apdu, + uint8_t tag_number, uint16_t * object_type, uint32_t * instance) { - int len = 0; + int len = 0; - if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { - len += decode_object_id(&apdu[len], object_type, instance); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { + len += decode_object_id(&apdu[len], object_type, instance); + } else { + len = -1; + } + return len; } /* from clause 20.2.14 Encoding of an Object Identifier Value */ @@ -905,28 +899,25 @@ int decode_octet_string( int decode_context_octet_string( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_OCTET_STRING * octet_string) { int len = 0; /* return value */ bool status = false; uint32_t len_value = 0; - if (decode_is_context_tag(&apdu[len], tag_number)) - { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + if (decode_is_context_tag(&apdu[len], tag_number)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - status = octetstring_init(octet_string, &apdu[len], len_value); + status = octetstring_init(octet_string, &apdu[len], len_value); - if (status) { - len += len_value; - } - } - else - { - len = -1; - } + if (status) { + len += len_value; + } + } else { + len = -1; + } return len; } @@ -1015,29 +1006,26 @@ int decode_character_string( int decode_context_character_string( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_CHARACTER_STRING * char_string) { int len = 0; /* return value */ bool status = false; uint32_t len_value = 0; - if (decode_is_context_tag(&apdu[len], tag_number)) - { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); + if (decode_is_context_tag(&apdu[len], tag_number)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); - status = - characterstring_init(char_string, apdu[len], (char *) &apdu[len+1], - len_value - 1); - if (status) { - len += len_value; - } - } - else - { - len = -1; - } + status = + characterstring_init(char_string, apdu[len], + (char *) &apdu[len + 1], len_value - 1); + if (status) { + len += len_value; + } + } else { + len = -1; + } return len; } @@ -1078,22 +1066,20 @@ int decode_unsigned( int decode_context_unsigned( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, uint32_t * value) { uint32_t len_value; - int len = 0; + int len = 0; - if (decode_is_context_tag(&apdu[len], tag_number)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_unsigned(&apdu[len], len_value, value); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag(&apdu[len], tag_number)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len += decode_unsigned(&apdu[len], len_value, value); + } else { + len = -1; + } + return len; } @@ -1178,23 +1164,21 @@ int decode_enumerated( int decode_context_enumerated( uint8_t * apdu, - uint8_t tag_value, + uint8_t tag_value, int *value) { - int len = 0; - uint8_t tag_number; - uint32_t len_value; + int len = 0; + uint8_t tag_number; + uint32_t len_value; - if (decode_is_context_tag(&apdu[len], tag_value)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_enumerated(&apdu[len], len_value, value); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag(&apdu[len], tag_value)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len += decode_enumerated(&apdu[len], len_value, value); + } else { + len = -1; + } + return len; } /* from clause 20.2.11 Encoding of an Enumerated Value */ @@ -1278,22 +1262,20 @@ int decode_signed( int decode_context_signed( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, int32_t * value) { uint32_t len_value; - int len = 0; + int len = 0; - if (decode_is_context_tag(&apdu[len], tag_number)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_signed(&apdu[len], len_value, value); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag(&apdu[len], tag_number)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len += decode_signed(&apdu[len], len_value, value); + } else { + len = -1; + } + return len; } /* from clause 20.2.5 Encoding of a Signed Integer Value */ @@ -1500,38 +1482,33 @@ int decode_application_time( uint8_t * apdu, BACNET_TIME * btime) { - int len = 0; - uint8_t tag_number; - decode_tag_number(&apdu[len], &tag_number); + int len = 0; + uint8_t tag_number; + decode_tag_number(&apdu[len], &tag_number); - if ( tag_number == BACNET_APPLICATION_TAG_TIME ) - { - len++; - len += decode_bacnet_time(&apdu[len], btime); - } - else - { - len = -1; - } - return len; + if (tag_number == BACNET_APPLICATION_TAG_TIME) { + len++; + len += decode_bacnet_time(&apdu[len], btime); + } else { + len = -1; + } + return len; } int decode_context_bacnet_time( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_TIME * btime) { - int len = 0; + int len = 0; - if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { - len += decode_bacnet_time(&apdu[len], btime); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { + len += decode_bacnet_time(&apdu[len], btime); + } else { + len = -1; + } + return len; } @@ -1550,20 +1527,16 @@ int encode_bacnet_date( { /* allow 2 digit years */ if (bdate->year >= 1900) { - apdu[0] = (uint8_t)(bdate->year - 1900); - } - else if ( bdate->year < 0x100 ) - { - apdu[0] = (uint8_t)bdate->year; + apdu[0] = (uint8_t) (bdate->year - 1900); + } else if (bdate->year < 0x100) { + apdu[0] = (uint8_t) bdate->year; - } - else - { - /* - ** Don't try and guess what the user meant here. Just fail - */ - return -1; - } + } else { + /* + ** Don't try and guess what the user meant here. Just fail + */ + return -1; + } apdu[1] = bdate->month; @@ -1617,7 +1590,7 @@ int decode_date( uint8_t * apdu, BACNET_DATE * bdate) { - bdate->year = (uint16_t)(apdu[0] + 1900); + bdate->year = (uint16_t) (apdu[0] + 1900); bdate->month = apdu[1]; bdate->day = apdu[2]; bdate->wday = apdu[3]; @@ -1629,37 +1602,32 @@ int decode_application_date( uint8_t * apdu, BACNET_DATE * bdate) { - int len = 0; - uint8_t tag_number; - decode_tag_number(&apdu[len], &tag_number); + int len = 0; + uint8_t tag_number; + decode_tag_number(&apdu[len], &tag_number); - if ( tag_number == BACNET_APPLICATION_TAG_DATE ) - { - len++; - len += decode_date(&apdu[len], bdate); - } - else - { - len = -1; - } - return len; + if (tag_number == BACNET_APPLICATION_TAG_DATE) { + len++; + len += decode_date(&apdu[len], bdate); + } else { + len = -1; + } + return len; } int decode_context_date( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, BACNET_DATE * bdate) { - int len = 0; + int len = 0; - if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { - len += decode_date(&apdu[len], bdate); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag_with_length(&apdu[len], tag_number, &len)) { + len += decode_date(&apdu[len], bdate); + } else { + len = -1; + } + return len; } @@ -2203,7 +2171,7 @@ void testBACDCodeObject( uint32_t decoded_instance = 0; encode_bacnet_object_id(&encoded_array[0], type, instance); - decode_object_id(&encoded_array[0], (uint16_t *) &decoded_type, + decode_object_id(&encoded_array[0], (uint16_t *) & decoded_type, &decoded_instance); ct_test(pTest, decoded_type == type); ct_test(pTest, decoded_instance == instance); @@ -2213,7 +2181,7 @@ void testBACDCodeObject( for (type = 0; type < 1024; type++) { for (instance = 0; instance <= BACNET_MAX_INSTANCE; instance += 1024) { encode_bacnet_object_id(&encoded_array[0], type, instance); - decode_object_id(&encoded_array[0], (uint16_t *) &decoded_type, + decode_object_id(&encoded_array[0], (uint16_t *) & decoded_type, &decoded_instance); ct_test(pTest, decoded_type == type); ct_test(pTest, decoded_instance == instance); @@ -2293,354 +2261,364 @@ void testBACDCodeBitString( } } -void testUnsignedContextDecodes(Test * pTest) +void testUnsignedContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - /* 32 bit number */ - uint32_t in = 0xdeadbeef; - uint32_t out; + /* 32 bit number */ + uint32_t in = 0xdeadbeef; + uint32_t out; - outLen2 = decode_context_unsigned(apdu, 9, &out); + outLen2 = decode_context_unsigned(apdu, 9, &out); - in = 0xdeadbeef; - inLen = encode_context_unsigned(apdu, 10, in); - outLen = decode_context_unsigned(apdu, 10, &out); + in = 0xdeadbeef; + inLen = encode_context_unsigned(apdu, 10, in); + outLen = decode_context_unsigned(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); - ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); + ct_test(pTest, outLen2 == -1); - /* 16 bit number */ - in = 0xdead; - inLen = encode_context_unsigned(apdu, 10, in); - outLen = decode_context_unsigned(apdu, 10, &out); + /* 16 bit number */ + in = 0xdead; + inLen = encode_context_unsigned(apdu, 10, in); + outLen = decode_context_unsigned(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 8 bit number */ - in = 0xde; - inLen = encode_context_unsigned(apdu, 10, in); - outLen = decode_context_unsigned(apdu, 10, &out); + /* 8 bit number */ + in = 0xde; + inLen = encode_context_unsigned(apdu, 10, in); + outLen = decode_context_unsigned(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 4 bit number */ - in = 0xd; - inLen = encode_context_unsigned(apdu, 10, in); - outLen = decode_context_unsigned(apdu, 10, &out); + /* 4 bit number */ + in = 0xd; + inLen = encode_context_unsigned(apdu, 10, in); + outLen = decode_context_unsigned(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 2 bit number */ - in = 0x2; - inLen = encode_context_unsigned(apdu, 10, in); - outLen = decode_context_unsigned(apdu, 10, &out); + /* 2 bit number */ + in = 0x2; + inLen = encode_context_unsigned(apdu, 10, in); + outLen = decode_context_unsigned(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); } -void testSignedContextDecodes(Test * pTest) +void testSignedContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - /* 32 bit number */ - int32_t in = 0xdeadbeef; - int32_t out; + /* 32 bit number */ + int32_t in = 0xdeadbeef; + int32_t out; - outLen2 = decode_context_signed(apdu, 9, &out); + outLen2 = decode_context_signed(apdu, 9, &out); - in = 0xdeadbeef; - inLen = encode_context_signed(apdu, 10, in); - outLen = decode_context_signed(apdu, 10, &out); + in = 0xdeadbeef; + inLen = encode_context_signed(apdu, 10, in); + outLen = decode_context_signed(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); - ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); + ct_test(pTest, outLen2 == -1); - /* 16 bit number */ - in = 0xdead; - inLen = encode_context_signed(apdu, 10, in); - outLen = decode_context_signed(apdu, 10, &out); + /* 16 bit number */ + in = 0xdead; + inLen = encode_context_signed(apdu, 10, in); + outLen = decode_context_signed(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 8 bit number */ - in = 0xde; - inLen = encode_context_signed(apdu, 10, in); - outLen = decode_context_signed(apdu, 10, &out); + /* 8 bit number */ + in = 0xde; + inLen = encode_context_signed(apdu, 10, in); + outLen = decode_context_signed(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 4 bit number */ - in = 0xd; - inLen = encode_context_signed(apdu, 10, in); - outLen = decode_context_signed(apdu, 10, &out); + /* 4 bit number */ + in = 0xd; + inLen = encode_context_signed(apdu, 10, in); + outLen = decode_context_signed(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 2 bit number */ - in = 0x2; - inLen = encode_context_signed(apdu, 10, in); - outLen = decode_context_signed(apdu, 10, &out); + /* 2 bit number */ + in = 0x2; + inLen = encode_context_signed(apdu, 10, in); + outLen = decode_context_signed(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); } -void testEnumeratedContextDecodes(Test * pTest) +void testEnumeratedContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - /* 32 bit number */ - int32_t in = 0xdeadbeef; - int32_t out; + /* 32 bit number */ + int32_t in = 0xdeadbeef; + int32_t out; - outLen2 = decode_context_enumerated(apdu, 9, &out); + outLen2 = decode_context_enumerated(apdu, 9, &out); - in = 0xdeadbeef; - inLen = encode_context_enumerated(apdu, 10, in); - outLen = decode_context_enumerated(apdu, 10, &out); + in = 0xdeadbeef; + inLen = encode_context_enumerated(apdu, 10, in); + outLen = decode_context_enumerated(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); - ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); + ct_test(pTest, outLen2 == -1); - /* 16 bit number */ - in = 0xdead; - inLen = encode_context_enumerated(apdu, 10, in); - outLen = decode_context_enumerated(apdu, 10, &out); + /* 16 bit number */ + in = 0xdead; + inLen = encode_context_enumerated(apdu, 10, in); + outLen = decode_context_enumerated(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 8 bit number */ - in = 0xde; - inLen = encode_context_enumerated(apdu, 10, in); - outLen = decode_context_enumerated(apdu, 10, &out); + /* 8 bit number */ + in = 0xde; + inLen = encode_context_enumerated(apdu, 10, in); + outLen = decode_context_enumerated(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 4 bit number */ - in = 0xd; - inLen = encode_context_enumerated(apdu, 10, in); - outLen = decode_context_enumerated(apdu, 10, &out); + /* 4 bit number */ + in = 0xd; + inLen = encode_context_enumerated(apdu, 10, in); + outLen = decode_context_enumerated(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); - /* 2 bit number */ - in = 0x2; - inLen = encode_context_enumerated(apdu, 10, in); - outLen = decode_context_enumerated(apdu, 10, &out); + /* 2 bit number */ + in = 0x2; + inLen = encode_context_enumerated(apdu, 10, in); + outLen = decode_context_enumerated(apdu, 10, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); } -void testFloatContextDecodes(Test * pTest) +void testFloatContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - /* 32 bit number */ - float in; - float out; + /* 32 bit number */ + float in; + float out; - in = 0.1234f; - inLen = encode_context_real(apdu, 10, in); - outLen = decode_context_real(apdu, 10, &out); - outLen2 = decode_context_real(apdu, 9, &out); + in = 0.1234f; + inLen = encode_context_real(apdu, 10, in); + outLen = decode_context_real(apdu, 10, &out); + outLen2 = decode_context_real(apdu, 9, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); - ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); + ct_test(pTest, outLen2 == -1); - in = 0.0f; - inLen = encode_context_real(apdu, 10, in); - outLen = decode_context_real(apdu, 10, &out); - outLen2 = decode_context_real(apdu, 9, &out); + in = 0.0f; + inLen = encode_context_real(apdu, 10, in); + outLen = decode_context_real(apdu, 10, &out); + outLen2 = decode_context_real(apdu, 9, &out); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in == out); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in == out); } -void testObjectIDContextDecodes(Test * pTest) +void testObjectIDContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - /* 32 bit number */ - uint16_t in_type; - uint32_t in_id; + /* 32 bit number */ + uint16_t in_type; + uint32_t in_id; - uint16_t out_type; - uint32_t out_id; + uint16_t out_type; + uint32_t out_id; - in_type = 0xde; - in_id = 0xbeef; + in_type = 0xde; + in_id = 0xbeef; - inLen = encode_context_object_id(apdu, 10, in_type, in_id); - outLen = decode_context_object_id(apdu, 10, &out_type, &out_id); - outLen2 = decode_context_object_id(apdu, 9, &out_type, &out_id); + inLen = encode_context_object_id(apdu, 10, in_type, in_id); + outLen = decode_context_object_id(apdu, 10, &out_type, &out_id); + outLen2 = decode_context_object_id(apdu, 9, &out_type, &out_id); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in_type == out_type); - ct_test(pTest, in_id == out_id); - ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in_type == out_type); + ct_test(pTest, in_id == out_id); + ct_test(pTest, outLen2 == -1); } -void testCharacterStringContextDecodes(Test * pTest) +void testCharacterStringContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - BACNET_CHARACTER_STRING in; - BACNET_CHARACTER_STRING out; + BACNET_CHARACTER_STRING in; + BACNET_CHARACTER_STRING out; - characterstring_init_ansi(&in, "This is a test"); + characterstring_init_ansi(&in, "This is a test"); - inLen = encode_context_character_string(apdu, 10, &in); - outLen= decode_context_character_string(apdu, 10, &out); - outLen2= decode_context_character_string(apdu, 9, &out); + inLen = encode_context_character_string(apdu, 10, &in); + outLen = decode_context_character_string(apdu, 10, &out); + outLen2 = decode_context_character_string(apdu, 9, &out); - ct_test(pTest, outLen2 == -1); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in.length == out.length); - ct_test(pTest, in.encoding == out.encoding); - ct_test(pTest, strcmp(in.value, out.value) == 0); + ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in.length == out.length); + ct_test(pTest, in.encoding == out.encoding); + ct_test(pTest, strcmp(in.value, out.value) == 0); } -void testBitStringContextDecodes(Test * pTest) +void testBitStringContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - BACNET_BIT_STRING in; - BACNET_BIT_STRING out; + BACNET_BIT_STRING in; + BACNET_BIT_STRING out; - bitstring_init(&in); - bitstring_set_bit(&in, 1, true); - bitstring_set_bit(&in, 3, true); - bitstring_set_bit(&in, 6, true); - bitstring_set_bit(&in, 10, false); - bitstring_set_bit(&in, 11, true); - bitstring_set_bit(&in, 12, false); + bitstring_init(&in); + bitstring_set_bit(&in, 1, true); + bitstring_set_bit(&in, 3, true); + bitstring_set_bit(&in, 6, true); + bitstring_set_bit(&in, 10, false); + bitstring_set_bit(&in, 11, true); + bitstring_set_bit(&in, 12, false); - inLen = encode_context_bitstring(apdu, 10, &in); - outLen= decode_context_bitstring(apdu, 10, &out); - outLen2= decode_context_bitstring(apdu, 9, &out); + inLen = encode_context_bitstring(apdu, 10, &in); + outLen = decode_context_bitstring(apdu, 10, &out); + outLen2 = decode_context_bitstring(apdu, 9, &out); - ct_test(pTest, outLen2 == -1); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in.bits_used == out.bits_used); - ct_test(pTest, memcmp(in.value, out.value, MAX_BITSTRING_BYTES) == 0); + ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in.bits_used == out.bits_used); + ct_test(pTest, memcmp(in.value, out.value, MAX_BITSTRING_BYTES) == 0); } -void testOctetStringContextDecodes(Test * pTest) +void testOctetStringContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - BACNET_OCTET_STRING in; - BACNET_OCTET_STRING out; + BACNET_OCTET_STRING in; + BACNET_OCTET_STRING out; - uint8_t initData[] = {0xde,0xad,0xbe,0xef}; + uint8_t initData[] = { 0xde, 0xad, 0xbe, 0xef }; - octetstring_init(&in, initData, sizeof(initData)); + octetstring_init(&in, initData, sizeof(initData)); - inLen = encode_context_octet_string(apdu, 10, &in); - outLen= decode_context_octet_string(apdu, 10, &out); - outLen2= decode_context_octet_string(apdu, 9, &out); + inLen = encode_context_octet_string(apdu, 10, &in); + outLen = decode_context_octet_string(apdu, 10, &out); + outLen2 = decode_context_octet_string(apdu, 9, &out); - ct_test(pTest, outLen2 == -1); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in.length == out.length); + ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in.length == out.length); ct_test(pTest, octetstring_value_same(&in, &out)); } -void testTimeContextDecodes(Test * pTest) +void testTimeContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - BACNET_TIME in; - BACNET_TIME out; + BACNET_TIME in; + BACNET_TIME out; - in.hour = 10; - in.hundredths = 20; - in.min = 30; - in.sec = 40; + in.hour = 10; + in.hundredths = 20; + in.min = 30; + in.sec = 40; - inLen = encode_context_time(apdu, 10, &in); - outLen= decode_context_bacnet_time(apdu, 10, &out); - outLen2= decode_context_bacnet_time(apdu, 9, &out); + inLen = encode_context_time(apdu, 10, &in); + outLen = decode_context_bacnet_time(apdu, 10, &out); + outLen2 = decode_context_bacnet_time(apdu, 9, &out); - ct_test(pTest, outLen2 == -1); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in.hour == out.hour); - ct_test(pTest, in.hundredths == out.hundredths); - ct_test(pTest, in.min == out.min); - ct_test(pTest, in.sec == out.sec); + ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in.hour == out.hour); + ct_test(pTest, in.hundredths == out.hundredths); + ct_test(pTest, in.min == out.min); + ct_test(pTest, in.sec == out.sec); } -void testDateContextDecodes(Test * pTest) +void testDateContextDecodes( + Test * pTest) { - uint8_t apdu[MAX_APDU]; - int inLen; - int outLen; - int outLen2; + uint8_t apdu[MAX_APDU]; + int inLen; + int outLen; + int outLen2; - BACNET_DATE in; - BACNET_DATE out; + BACNET_DATE in; + BACNET_DATE out; - in.day = 3; - in.month = 10; - in.wday = 5; - in.year = 1945; + in.day = 3; + in.month = 10; + in.wday = 5; + in.year = 1945; - inLen = encode_context_date(apdu, 10, &in); - outLen= decode_context_date(apdu, 10, &out); - outLen2= decode_context_date(apdu, 9, &out); + inLen = encode_context_date(apdu, 10, &in); + outLen = decode_context_date(apdu, 10, &out); + outLen2 = decode_context_date(apdu, 9, &out); - ct_test(pTest, outLen2 == -1); - ct_test(pTest, inLen == outLen); - ct_test(pTest, in.day == out.day); - ct_test(pTest, in.month == out.month); - ct_test(pTest, in.wday == out.wday); - ct_test(pTest, in.year == out.year); + ct_test(pTest, outLen2 == -1); + ct_test(pTest, inLen == outLen); + ct_test(pTest, in.day == out.day); + ct_test(pTest, in.month == out.month); + ct_test(pTest, in.wday == out.wday); + ct_test(pTest, in.year == out.year); } @@ -2696,7 +2674,7 @@ int main( rc = ct_addTestFunction(pTest, testObjectIDContextDecodes); assert(rc); - rc = ct_addTestFunction(pTest, testBitStringContextDecodes); + rc = ct_addTestFunction(pTest, testBitStringContextDecodes); assert(rc); rc = ct_addTestFunction(pTest, testTimeContextDecodes); diff --git a/bacnet-stack/src/bacdevobjpropref.c b/bacnet-stack/src/bacdevobjpropref.c index bb1806f2..57a5ec76 100644 --- a/bacnet-stack/src/bacdevobjpropref.c +++ b/bacnet-stack/src/bacdevobjpropref.c @@ -1,243 +1,235 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#include -#include "bacdcode.h" -#include "npdu.h" -#include "device.h" -#include "datalink.h" -#include "timestamp.h" -#include "bacdevobjpropref.h" - -int bacapp_encode_context_device_obj_property_ref( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) -{ - int len; - int apdu_len = 0; - - len = encode_opening_tag(&apdu[apdu_len], tag_number); - apdu_len += len; - - len = bacapp_encode_device_obj_property_ref(&apdu[apdu_len], value); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], tag_number); - apdu_len += len; - - return apdu_len; -} - -int bacapp_encode_device_obj_property_ref( - uint8_t * apdu, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) -{ - int len; - int apdu_len = 0; - - len = encode_context_object_id(&apdu[apdu_len], 0, - value->objectIdentifier.type, - value->objectIdentifier.instance); - apdu_len += len; - - len = encode_context_enumerated(&apdu[apdu_len], 1, - value->propertyIdentifier); - apdu_len += len; - - if ( value->arrayIndex > 0 ) - { - len = encode_context_unsigned(&apdu[apdu_len], 2, - value->arrayIndex); - apdu_len += len; - } - len = encode_context_object_id(&apdu[apdu_len], 3, - value->deviceIndentifier.type, - value->deviceIndentifier.instance); - apdu_len += len; - - return apdu_len; -} - -int bacapp_decode_device_obj_property_ref( - uint8_t * apdu, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) -{ - int len; - int apdu_len = 0; - - if ( -1 == ( len = decode_context_object_id(&apdu[apdu_len], 0, - &value->objectIdentifier.type, - &value->objectIdentifier.instance)) ) - { - return -1; - } - apdu_len += len; - - if ( -1 == ( len = decode_context_enumerated(&apdu[apdu_len], 1, - &value->propertyIdentifier))) - { - return -1; - } - apdu_len += len; - - if ( decode_is_context_tag(&apdu[apdu_len], 2 )) - { - if ( -1 == ( len = decode_context_unsigned(&apdu[apdu_len], 2, - &value->arrayIndex))) - { - return -1; - } - apdu_len += len; - } - else - { - value->arrayIndex = 0; - } - - if ( decode_is_context_tag(&apdu[apdu_len], 3 )) - { - if ( -1 == ( len = decode_context_object_id(&apdu[apdu_len], 3, - &value->deviceIndentifier.type, - &value->deviceIndentifier.instance)) ) - { - return -1; - } - apdu_len += len; - } - else - { - value->deviceIndentifier.instance = 0; - value->deviceIndentifier.type = 0; - } - - return apdu_len; -} - -int bacapp_decode_context_device_obj_property_ref( - uint8_t * apdu, - uint8_t tag_number, - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) -{ - int len = 0; - int section_length; - - if (decode_is_opening_tag_number(&apdu[len], tag_number)) { - len++; - section_length = bacapp_decode_device_obj_property_ref( - &apdu[len], value); - - if ( section_length == -1 ) - { - len = -1; - } - else - { - len += section_length; - if (decode_is_closing_tag_number(&apdu[len], tag_number)) { - len++; - } - else - { - len = -1; - } - } - } - else - { - len = -1; - } - return len; -} - -#ifdef TEST - -void testDevIdPropRef( - Test * pTest) -{ - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE inData; - BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE outData; - uint8_t buffer[MAX_APDU]; - int inLen; - int outLen; - - - inData.objectIdentifier.instance = 0x1234; - inData.objectIdentifier.type = 15; - - inData.propertyIdentifier = 25; - - inData.arrayIndex = 0x5678; - - inData.deviceIndentifier.instance = 0x4343; - inData.deviceIndentifier.type = 28; - - inLen = bacapp_encode_device_obj_property_ref(buffer, &inData); - outLen = bacapp_decode_device_obj_property_ref(buffer, &outData); - - ct_test(pTest, outLen == inLen); - - ct_test(pTest, inData.objectIdentifier.instance == outData.objectIdentifier.instance); - ct_test(pTest, inData.objectIdentifier.type == outData.objectIdentifier.type); - - ct_test(pTest, inData.propertyIdentifier == outData.propertyIdentifier); - - ct_test(pTest, inData.arrayIndex == outData.arrayIndex); - - ct_test(pTest, inData.deviceIndentifier.instance == outData.deviceIndentifier.instance); - ct_test(pTest, inData.deviceIndentifier.type == outData.deviceIndentifier.type); -} -#ifdef TEST_DEV_ID_PROP_REF - -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Prop Ref", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testDevIdPropRef); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} - -#endif // TEST_DEV_ID_PROP_REF -#endif // TEST +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include +#include "bacdcode.h" +#include "npdu.h" +#include "device.h" +#include "datalink.h" +#include "timestamp.h" +#include "bacdevobjpropref.h" + +int bacapp_encode_context_device_obj_property_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) +{ + int len; + int apdu_len = 0; + + len = encode_opening_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + + len = bacapp_encode_device_obj_property_ref(&apdu[apdu_len], value); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + + return apdu_len; +} + +int bacapp_encode_device_obj_property_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) +{ + int len; + int apdu_len = 0; + + len = + encode_context_object_id(&apdu[apdu_len], 0, + value->objectIdentifier.type, value->objectIdentifier.instance); + apdu_len += len; + + len = + encode_context_enumerated(&apdu[apdu_len], 1, + value->propertyIdentifier); + apdu_len += len; + + if (value->arrayIndex > 0) { + len = encode_context_unsigned(&apdu[apdu_len], 2, value->arrayIndex); + apdu_len += len; + } + len = + encode_context_object_id(&apdu[apdu_len], 3, + value->deviceIndentifier.type, value->deviceIndentifier.instance); + apdu_len += len; + + return apdu_len; +} + +int bacapp_decode_device_obj_property_ref( + uint8_t * apdu, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) +{ + int len; + int apdu_len = 0; + + if (-1 == (len = + decode_context_object_id(&apdu[apdu_len], 0, + &value->objectIdentifier.type, + &value->objectIdentifier.instance))) { + return -1; + } + apdu_len += len; + + if (-1 == (len = + decode_context_enumerated(&apdu[apdu_len], 1, + &value->propertyIdentifier))) { + return -1; + } + apdu_len += len; + + if (decode_is_context_tag(&apdu[apdu_len], 2)) { + if (-1 == (len = + decode_context_unsigned(&apdu[apdu_len], 2, + &value->arrayIndex))) { + return -1; + } + apdu_len += len; + } else { + value->arrayIndex = 0; + } + + if (decode_is_context_tag(&apdu[apdu_len], 3)) { + if (-1 == (len = + decode_context_object_id(&apdu[apdu_len], 3, + &value->deviceIndentifier.type, + &value->deviceIndentifier.instance))) { + return -1; + } + apdu_len += len; + } else { + value->deviceIndentifier.instance = 0; + value->deviceIndentifier.type = 0; + } + + return apdu_len; +} + +int bacapp_decode_context_device_obj_property_ref( + uint8_t * apdu, + uint8_t tag_number, + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) +{ + int len = 0; + int section_length; + + if (decode_is_opening_tag_number(&apdu[len], tag_number)) { + len++; + section_length = + bacapp_decode_device_obj_property_ref(&apdu[len], value); + + if (section_length == -1) { + len = -1; + } else { + len += section_length; + if (decode_is_closing_tag_number(&apdu[len], tag_number)) { + len++; + } else { + len = -1; + } + } + } else { + len = -1; + } + return len; +} + +#ifdef TEST + +void testDevIdPropRef( + Test * pTest) +{ + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE inData; + BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE outData; + uint8_t buffer[MAX_APDU]; + int inLen; + int outLen; + + + inData.objectIdentifier.instance = 0x1234; + inData.objectIdentifier.type = 15; + + inData.propertyIdentifier = 25; + + inData.arrayIndex = 0x5678; + + inData.deviceIndentifier.instance = 0x4343; + inData.deviceIndentifier.type = 28; + + inLen = bacapp_encode_device_obj_property_ref(buffer, &inData); + outLen = bacapp_decode_device_obj_property_ref(buffer, &outData); + + ct_test(pTest, outLen == inLen); + + ct_test(pTest, + inData.objectIdentifier.instance == outData.objectIdentifier.instance); + ct_test(pTest, + inData.objectIdentifier.type == outData.objectIdentifier.type); + + ct_test(pTest, inData.propertyIdentifier == outData.propertyIdentifier); + + ct_test(pTest, inData.arrayIndex == outData.arrayIndex); + + ct_test(pTest, + inData.deviceIndentifier.instance == + outData.deviceIndentifier.instance); + ct_test(pTest, + inData.deviceIndentifier.type == outData.deviceIndentifier.type); +} + +#ifdef TEST_DEV_ID_PROP_REF + +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Prop Ref", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testDevIdPropRef); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} + +#endif // TEST_DEV_ID_PROP_REF +#endif // TEST diff --git a/bacnet-stack/src/bacpropstates.c b/bacnet-stack/src/bacpropstates.c index c0935ee7..18bddf0d 100644 --- a/bacnet-stack/src/bacpropstates.c +++ b/bacnet-stack/src/bacpropstates.c @@ -1,403 +1,432 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#include -#include "bacdcode.h" -#include "npdu.h" -#include "device.h" -#include "datalink.h" -#include "timestamp.h" -#include "bacpropstates.h" - -int bacapp_decode_property_state( - uint8_t * apdu, - BACNET_PROPERTY_STATE * value) -{ - int len = 0; - uint32_t len_value_type; - int section_length; - - - section_length = - decode_tag_number_and_value(&apdu[len], (uint8_t*)&value->tag, - &len_value_type); - - if ( -1 == section_length ) - { - return -1; - } - - len += section_length; - switch(value->tag) - { - case BOOLEAN_VALUE: - value->state.booleanValue = decode_boolean(len_value_type); - break; - - case BINARY_VALUE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.binaryValue))) - { - return -1; - } - break; - - case EVENT_TYPE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.eventType))) - { - return -1; - } - break; - - case POLARITY: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.polarity))) - { - return -1; - } - break; - - case PROGRAM_CHANGE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.programChange))) - { - return -1; - } - break; - - case PROGRAM_STATE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.programState))) - { - return -1; - } - break; - - case REASON_FOR_HALT: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.programError))) - { - return -1; - } - break; - - case RELIABILITY: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.reliability))) - { - return -1; - } - break; - - case STATE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.state))) - { - return -1; - } - break; - - case SYSTEM_STATUS: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.systemStatus))) - { - return -1; - } - break; - - case UNITS: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.units))) - { - return -1; - } - break; - - case UNSIGNED_VALUE: - if ( -1 == ( section_length = decode_unsigned(&apdu[len], len_value_type, &value->state.unsignedValue))) - { - return -1; - } - break; - - case LIFE_SAFETY_MODE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.lifeSafetyMode))) - { - return -1; - } - break; - - case LIFE_SAFETY_STATE: - if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.lifeSafetyState))) - { - return -1; - } - break; - - default: - return -1; - } - len += section_length; - - return len; -} - -int bacapp_decode_context_property_state( - uint8_t * apdu, - uint8_t tag_number, - BACNET_PROPERTY_STATE * value) -{ - int len = 0; - int section_length; - - if (decode_is_opening_tag_number(&apdu[len], tag_number)) { - len++; - section_length = bacapp_decode_property_state( - &apdu[len], value); - - if ( section_length == -1 ) - { - len = -1; - } - else - { - len += section_length; - if (decode_is_closing_tag_number(&apdu[len], tag_number)) { - len++; - } - else - { - len = -1; - } - } - } - else - { - len = -1; - } - return len; -} - -int bacapp_encode_property_state( - uint8_t * apdu, - BACNET_PROPERTY_STATE * value) -{ - int len = 0; /* length of each encoding */ - if (value && apdu) { - switch(value->tag) - { - case BOOLEAN_VALUE: - len = encode_context_boolean(&apdu[0], 0, value->state.booleanValue); - break; - - case BINARY_VALUE: - len = encode_context_enumerated(&apdu[0], 1, value->state.binaryValue); - break; - - case EVENT_TYPE: - len = encode_context_enumerated(&apdu[0], 2, value->state.eventType); - break; - - case POLARITY: - len = encode_context_enumerated(&apdu[0], 3, value->state.polarity); - break; - - case PROGRAM_CHANGE: - len = encode_context_enumerated(&apdu[0], 4, value->state.programChange); - break; - - case PROGRAM_STATE: - len = encode_context_enumerated(&apdu[0], 5, value->state.programState); - break; - - case REASON_FOR_HALT: - len = encode_context_enumerated(&apdu[0], 6, value->state.programError); - break; - - case RELIABILITY: - len = encode_context_enumerated(&apdu[0], 7, value->state.reliability); - break; - - case STATE: - len = encode_context_enumerated(&apdu[0], 8, value->state.state); - break; - - case SYSTEM_STATUS: - len = encode_context_enumerated(&apdu[0], 9, value->state.systemStatus); - break; - - case UNITS: - len = encode_context_enumerated(&apdu[0], 10, value->state.units); - break; - - case UNSIGNED_VALUE: - len = encode_context_unsigned(&apdu[0], 11, value->state.unsignedValue); - break; - - case LIFE_SAFETY_MODE: - len = encode_context_enumerated(&apdu[0], 12, value->state.lifeSafetyMode); - break; - - case LIFE_SAFETY_STATE: - len = encode_context_enumerated(&apdu[0], 13, value->state.lifeSafetyState); - break; - - default: - assert(0); - break; - } - } - return len; -} - -#ifdef TEST - -void testPropStates( - Test * pTest) -{ - BACNET_PROPERTY_STATE inData; - BACNET_PROPERTY_STATE outData; - uint8_t appMsg[MAX_APDU]; - int inLen; - int outLen; - - inData.tag = BOOLEAN_VALUE; - inData.state.booleanValue = true; - - inLen = bacapp_encode_property_state(appMsg, &inData); - - memset(&outData, 0, sizeof(outData)); - - outLen = bacapp_decode_property_state(appMsg, &outData); - - ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.tag == outData.tag ); - ct_test(pTest, inData.state.booleanValue == outData.state.booleanValue ); - - /**************** - ***************** - ****************/ - inData.tag = BINARY_VALUE; - inData.state.binaryValue = BINARY_ACTIVE; - - inLen = bacapp_encode_property_state(appMsg, &inData); - - memset(&outData, 0, sizeof(outData)); - - outLen = bacapp_decode_property_state(appMsg, &outData); - - ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.tag == outData.tag ); - ct_test(pTest, inData.state.binaryValue == outData.state.binaryValue ); - - /**************** - ***************** - ****************/ - inData.tag = EVENT_TYPE; - inData.state.eventType = EVENT_BUFFER_READY; - - inLen = bacapp_encode_property_state(appMsg, &inData); - - memset(&outData, 0, sizeof(outData)); - - outLen = bacapp_decode_property_state(appMsg, &outData); - - ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.tag == outData.tag ); - ct_test(pTest, inData.state.eventType == outData.state.eventType ); - - /**************** - ***************** - ****************/ - inData.tag = POLARITY; - inData.state.polarity = POLARITY_REVERSE; - - inLen = bacapp_encode_property_state(appMsg, &inData); - - memset(&outData, 0, sizeof(outData)); - - outLen = bacapp_decode_property_state(appMsg, &outData); - - ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.tag == outData.tag ); - ct_test(pTest, inData.state.polarity == outData.state.polarity ); - - /**************** - ***************** - ****************/ - inData.tag = PROGRAM_CHANGE; - inData.state.programChange = PROGRAM_REQUEST_RESTART; - - inLen = bacapp_encode_property_state(appMsg, &inData); - - memset(&outData, 0, sizeof(outData)); - - outLen = bacapp_decode_property_state(appMsg, &outData); - - ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.tag == outData.tag ); - ct_test(pTest, inData.state.programChange == outData.state.programChange ); - - /**************** - ***************** - ****************/ - inData.tag = UNSIGNED_VALUE; - inData.state.unsignedValue = 0xdeadbeef; - - inLen = bacapp_encode_property_state(appMsg, &inData); - - memset(&outData, 0, sizeof(outData)); - - outLen = bacapp_decode_property_state(appMsg, &outData); - - ct_test(pTest, outLen == inLen); - ct_test(pTest, inData.tag == outData.tag ); - ct_test(pTest, inData.state.unsignedValue == outData.state.unsignedValue ); - -} - -#ifdef TEST_PROP_STATES - -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Event", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testPropStates); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} - -#endif // TEST_PROP_STATES -#endif // TEST +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include +#include "bacdcode.h" +#include "npdu.h" +#include "device.h" +#include "datalink.h" +#include "timestamp.h" +#include "bacpropstates.h" + +int bacapp_decode_property_state( + uint8_t * apdu, + BACNET_PROPERTY_STATE * value) +{ + int len = 0; + uint32_t len_value_type; + int section_length; + + + section_length = + decode_tag_number_and_value(&apdu[len], (uint8_t *) & value->tag, + &len_value_type); + + if (-1 == section_length) { + return -1; + } + + len += section_length; + switch (value->tag) { + case BOOLEAN_VALUE: + value->state.booleanValue = decode_boolean(len_value_type); + break; + + case BINARY_VALUE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.binaryValue))) { + return -1; + } + break; + + case EVENT_TYPE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.eventType))) { + return -1; + } + break; + + case POLARITY: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.polarity))) { + return -1; + } + break; + + case PROGRAM_CHANGE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.programChange))) { + return -1; + } + break; + + case PROGRAM_STATE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.programState))) { + return -1; + } + break; + + case REASON_FOR_HALT: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.programError))) { + return -1; + } + break; + + case RELIABILITY: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.reliability))) { + return -1; + } + break; + + case STATE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.state))) { + return -1; + } + break; + + case SYSTEM_STATUS: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.systemStatus))) { + return -1; + } + break; + + case UNITS: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.units))) { + return -1; + } + break; + + case UNSIGNED_VALUE: + if (-1 == (section_length = + decode_unsigned(&apdu[len], len_value_type, + &value->state.unsignedValue))) { + return -1; + } + break; + + case LIFE_SAFETY_MODE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.lifeSafetyMode))) { + return -1; + } + break; + + case LIFE_SAFETY_STATE: + if (-1 == (section_length = + decode_enumerated(&apdu[len], len_value_type, + &value->state.lifeSafetyState))) { + return -1; + } + break; + + default: + return -1; + } + len += section_length; + + return len; +} + +int bacapp_decode_context_property_state( + uint8_t * apdu, + uint8_t tag_number, + BACNET_PROPERTY_STATE * value) +{ + int len = 0; + int section_length; + + if (decode_is_opening_tag_number(&apdu[len], tag_number)) { + len++; + section_length = bacapp_decode_property_state(&apdu[len], value); + + if (section_length == -1) { + len = -1; + } else { + len += section_length; + if (decode_is_closing_tag_number(&apdu[len], tag_number)) { + len++; + } else { + len = -1; + } + } + } else { + len = -1; + } + return len; +} + +int bacapp_encode_property_state( + uint8_t * apdu, + BACNET_PROPERTY_STATE * value) +{ + int len = 0; /* length of each encoding */ + if (value && apdu) { + switch (value->tag) { + case BOOLEAN_VALUE: + len = + encode_context_boolean(&apdu[0], 0, + value->state.booleanValue); + break; + + case BINARY_VALUE: + len = + encode_context_enumerated(&apdu[0], 1, + value->state.binaryValue); + break; + + case EVENT_TYPE: + len = + encode_context_enumerated(&apdu[0], 2, + value->state.eventType); + break; + + case POLARITY: + len = + encode_context_enumerated(&apdu[0], 3, + value->state.polarity); + break; + + case PROGRAM_CHANGE: + len = + encode_context_enumerated(&apdu[0], 4, + value->state.programChange); + break; + + case PROGRAM_STATE: + len = + encode_context_enumerated(&apdu[0], 5, + value->state.programState); + break; + + case REASON_FOR_HALT: + len = + encode_context_enumerated(&apdu[0], 6, + value->state.programError); + break; + + case RELIABILITY: + len = + encode_context_enumerated(&apdu[0], 7, + value->state.reliability); + break; + + case STATE: + len = + encode_context_enumerated(&apdu[0], 8, value->state.state); + break; + + case SYSTEM_STATUS: + len = + encode_context_enumerated(&apdu[0], 9, + value->state.systemStatus); + break; + + case UNITS: + len = + encode_context_enumerated(&apdu[0], 10, + value->state.units); + break; + + case UNSIGNED_VALUE: + len = + encode_context_unsigned(&apdu[0], 11, + value->state.unsignedValue); + break; + + case LIFE_SAFETY_MODE: + len = + encode_context_enumerated(&apdu[0], 12, + value->state.lifeSafetyMode); + break; + + case LIFE_SAFETY_STATE: + len = + encode_context_enumerated(&apdu[0], 13, + value->state.lifeSafetyState); + break; + + default: + assert(0); + break; + } + } + return len; +} + +#ifdef TEST + +void testPropStates( + Test * pTest) +{ + BACNET_PROPERTY_STATE inData; + BACNET_PROPERTY_STATE outData; + uint8_t appMsg[MAX_APDU]; + int inLen; + int outLen; + + inData.tag = BOOLEAN_VALUE; + inData.state.booleanValue = true; + + inLen = bacapp_encode_property_state(appMsg, &inData); + + memset(&outData, 0, sizeof(outData)); + + outLen = bacapp_decode_property_state(appMsg, &outData); + + ct_test(pTest, outLen == inLen); + ct_test(pTest, inData.tag == outData.tag); + ct_test(pTest, inData.state.booleanValue == outData.state.booleanValue); + + /**************** + ***************** + ****************/ + inData.tag = BINARY_VALUE; + inData.state.binaryValue = BINARY_ACTIVE; + + inLen = bacapp_encode_property_state(appMsg, &inData); + + memset(&outData, 0, sizeof(outData)); + + outLen = bacapp_decode_property_state(appMsg, &outData); + + ct_test(pTest, outLen == inLen); + ct_test(pTest, inData.tag == outData.tag); + ct_test(pTest, inData.state.binaryValue == outData.state.binaryValue); + + /**************** + ***************** + ****************/ + inData.tag = EVENT_TYPE; + inData.state.eventType = EVENT_BUFFER_READY; + + inLen = bacapp_encode_property_state(appMsg, &inData); + + memset(&outData, 0, sizeof(outData)); + + outLen = bacapp_decode_property_state(appMsg, &outData); + + ct_test(pTest, outLen == inLen); + ct_test(pTest, inData.tag == outData.tag); + ct_test(pTest, inData.state.eventType == outData.state.eventType); + + /**************** + ***************** + ****************/ + inData.tag = POLARITY; + inData.state.polarity = POLARITY_REVERSE; + + inLen = bacapp_encode_property_state(appMsg, &inData); + + memset(&outData, 0, sizeof(outData)); + + outLen = bacapp_decode_property_state(appMsg, &outData); + + ct_test(pTest, outLen == inLen); + ct_test(pTest, inData.tag == outData.tag); + ct_test(pTest, inData.state.polarity == outData.state.polarity); + + /**************** + ***************** + ****************/ + inData.tag = PROGRAM_CHANGE; + inData.state.programChange = PROGRAM_REQUEST_RESTART; + + inLen = bacapp_encode_property_state(appMsg, &inData); + + memset(&outData, 0, sizeof(outData)); + + outLen = bacapp_decode_property_state(appMsg, &outData); + + ct_test(pTest, outLen == inLen); + ct_test(pTest, inData.tag == outData.tag); + ct_test(pTest, inData.state.programChange == outData.state.programChange); + + /**************** + ***************** + ****************/ + inData.tag = UNSIGNED_VALUE; + inData.state.unsignedValue = 0xdeadbeef; + + inLen = bacapp_encode_property_state(appMsg, &inData); + + memset(&outData, 0, sizeof(outData)); + + outLen = bacapp_decode_property_state(appMsg, &outData); + + ct_test(pTest, outLen == inLen); + ct_test(pTest, inData.tag == outData.tag); + ct_test(pTest, inData.state.unsignedValue == outData.state.unsignedValue); + +} + +#ifdef TEST_PROP_STATES + +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Event", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testPropStates); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} + +#endif // TEST_PROP_STATES +#endif // TEST diff --git a/bacnet-stack/src/bacreal.c b/bacnet-stack/src/bacreal.c index f6abbc9a..ccb0bbbd 100644 --- a/bacnet-stack/src/bacreal.c +++ b/bacnet-stack/src/bacreal.c @@ -78,23 +78,22 @@ int decode_real( int decode_context_real( uint8_t * apdu, - uint8_t tag_number, + uint8_t tag_number, float *real_value) { uint32_t len_value; - int len = 0; + int len = 0; - if (decode_is_context_tag(&apdu[len], tag_number)) { - len += decode_tag_number_and_value(&apdu[len], &tag_number, - &len_value); - len += decode_real(&apdu[len], real_value); - } - else - { - len = -1; - } - return len; + if (decode_is_context_tag(&apdu[len], tag_number)) { + len += + decode_tag_number_and_value(&apdu[len], &tag_number, &len_value); + len += decode_real(&apdu[len], real_value); + } else { + len = -1; + } + return len; } + /* from clause 20.2.6 Encoding of a Real Number Value */ /* returns the number of apdu bytes consumed */ int encode_bacnet_real( diff --git a/bacnet-stack/src/bacstr.c b/bacnet-stack/src/bacstr.c index 2cf62248..8db0378e 100644 --- a/bacnet-stack/src/bacstr.c +++ b/bacnet-stack/src/bacstr.c @@ -99,7 +99,7 @@ uint8_t bitstring_bits_used( uint8_t bitstring_bytes_used( BACNET_BIT_STRING * bit_string) { - uint8_t len = 0; /* return value */ + uint8_t len = 0; /* return value */ uint8_t used_bytes = 0; uint8_t last_bit = 0; @@ -544,7 +544,7 @@ bool octetstring_value_same( BACNET_OCTET_STRING * octet_string1, BACNET_OCTET_STRING * octet_string2) { - size_t i = 0; /* loop counter */ + size_t i = 0; /* loop counter */ if (octet_string1 && octet_string2) { if ((octet_string1->length == octet_string2->length) && diff --git a/bacnet-stack/src/cov.c b/bacnet-stack/src/cov.c index b40e7a4d..b61831cf 100644 --- a/bacnet-stack/src/cov.c +++ b/bacnet-stack/src/cov.c @@ -174,7 +174,7 @@ int cov_notify_decode_service_request( uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ int property = 0; /* for decoding */ BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ @@ -373,7 +373,7 @@ int cov_subscribe_decode_service_request( uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ if (apdu_len && data) { /* tag 0 - subscriberProcessIdentifier */ @@ -519,7 +519,7 @@ int cov_subscribe_property_decode_service_request( uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ int property = 0; /* for decoding */ if (apdu_len && data) { diff --git a/bacnet-stack/src/datetime.c b/bacnet-stack/src/datetime.c index 84d55d52..a047d861 100644 --- a/bacnet-stack/src/datetime.c +++ b/bacnet-stack/src/datetime.c @@ -75,7 +75,7 @@ static uint8_t month_days( if ((month == 2) && is_leap_year(year)) return 29; else if (month >= 1 && month <= 12) - return (uint8_t)month_days[month]; + return (uint8_t) month_days[month]; else return 0; } @@ -435,48 +435,47 @@ int bacapp_encode_context_datetime( uint8_t tag_number, BACNET_DATE_TIME * value) { - int len = 0; - int apdu_len = 0; + int len = 0; + int apdu_len = 0; - if ( apdu && value ) - { - len = encode_opening_tag(&apdu[apdu_len], tag_number); - apdu_len += len; + if (apdu && value) { + len = encode_opening_tag(&apdu[apdu_len], tag_number); + apdu_len += len; - len = encode_application_date(&apdu[apdu_len], &value->date); - apdu_len += len; + len = encode_application_date(&apdu[apdu_len], &value->date); + apdu_len += len; - len = encode_application_time(&apdu[apdu_len], &value->time); - apdu_len += len; + len = encode_application_time(&apdu[apdu_len], &value->time); + apdu_len += len; - len = encode_closing_tag(&apdu[apdu_len], tag_number); - apdu_len += len; - } - return apdu_len; + len = encode_closing_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + } + return apdu_len; } int bacapp_decode_datetime( uint8_t * apdu, BACNET_DATE_TIME * value) { - int len = 0; - int section_len; + int len = 0; + int section_len; - if ( -1 == ( section_len = decode_application_date(&apdu[len], &value->date) ) ) - { - return -1; - } - len += section_len; + if (-1 == (section_len = + decode_application_date(&apdu[len], &value->date))) { + return -1; + } + len += section_len; - if ( -1 == ( section_len = decode_application_time(&apdu[len], &value->time) ) ) - { - return -1; - } + if (-1 == (section_len = + decode_application_time(&apdu[len], &value->time))) { + return -1; + } - len += section_len; - - return len; + len += section_len; + + return len; } int bacapp_decode_context_datetime( @@ -484,35 +483,27 @@ int bacapp_decode_context_datetime( uint8_t tag_number, BACNET_DATE_TIME * value) { - int apdu_len = 0; - int len; + int apdu_len = 0; + int len; - if (decode_is_opening_tag_number(&apdu[apdu_len], tag_number)) { - apdu_len++; - } - else - { - return -1; - } + if (decode_is_opening_tag_number(&apdu[apdu_len], tag_number)) { + apdu_len++; + } else { + return -1; + } - if ( -1 == (len = bacapp_decode_datetime(&apdu[apdu_len], value))) - { - return -1; - } - else - { - apdu_len += len; - } + if (-1 == (len = bacapp_decode_datetime(&apdu[apdu_len], value))) { + return -1; + } else { + apdu_len += len; + } - if (decode_is_closing_tag_number(&apdu[apdu_len], tag_number)) - { - apdu_len++; - } - else - { - return -1; - } - return apdu_len; + if (decode_is_closing_tag_number(&apdu[apdu_len], tag_number)) { + apdu_len++; + } else { + return -1; + } + return apdu_len; } @@ -836,36 +827,36 @@ void testBACnetDayOfWeek( void testDatetimeCodec( Test * pTest) { - uint8_t apdu[MAX_APDU]; - BACNET_DATE_TIME datetimeIn; - BACNET_DATE_TIME datetimeOut; - int inLen; - int outLen; + uint8_t apdu[MAX_APDU]; + BACNET_DATE_TIME datetimeIn; + BACNET_DATE_TIME datetimeOut; + int inLen; + int outLen; - datetimeIn.date.day = 1; - datetimeIn.date.month = 2; - datetimeIn.date.wday = 3; - datetimeIn.date.year = 1904; + datetimeIn.date.day = 1; + datetimeIn.date.month = 2; + datetimeIn.date.wday = 3; + datetimeIn.date.year = 1904; - datetimeIn.time.hour = 5; - datetimeIn.time.min = 6; - datetimeIn.time.sec = 7; - datetimeIn.time.hundredths = 8; + datetimeIn.time.hour = 5; + datetimeIn.time.min = 6; + datetimeIn.time.sec = 7; + datetimeIn.time.hundredths = 8; - inLen = bacapp_encode_context_datetime(apdu, 10, &datetimeIn); - outLen = bacapp_decode_context_datetime(apdu, 10, &datetimeOut); + inLen = bacapp_encode_context_datetime(apdu, 10, &datetimeIn); + outLen = bacapp_decode_context_datetime(apdu, 10, &datetimeOut); - ct_test(pTest, inLen == outLen ); + ct_test(pTest, inLen == outLen); - ct_test(pTest, datetimeIn.date.day == datetimeOut.date.day); - ct_test(pTest, datetimeIn.date.month == datetimeOut.date.month); - ct_test(pTest, datetimeIn.date.wday == datetimeOut.date.wday); - ct_test(pTest, datetimeIn.date.year == datetimeOut.date.year); + ct_test(pTest, datetimeIn.date.day == datetimeOut.date.day); + ct_test(pTest, datetimeIn.date.month == datetimeOut.date.month); + ct_test(pTest, datetimeIn.date.wday == datetimeOut.date.wday); + ct_test(pTest, datetimeIn.date.year == datetimeOut.date.year); - ct_test(pTest, datetimeIn.time.hour == datetimeOut.time.hour); - ct_test(pTest, datetimeIn.time.min == datetimeOut.time.min); - ct_test(pTest, datetimeIn.time.sec == datetimeOut.time.sec); - ct_test(pTest, datetimeIn.time.hundredths == datetimeOut.time.hundredths); + ct_test(pTest, datetimeIn.time.hour == datetimeOut.time.hour); + ct_test(pTest, datetimeIn.time.min == datetimeOut.time.min); + ct_test(pTest, datetimeIn.time.sec == datetimeOut.time.sec); + ct_test(pTest, datetimeIn.time.hundredths == datetimeOut.time.hundredths); } @@ -909,4 +900,3 @@ int main( #endif /* TEST_DATE_TIME */ #endif /* TEST */ - diff --git a/bacnet-stack/src/event.c b/bacnet-stack/src/event.c index 462902e3..60be9b4a 100644 --- a/bacnet-stack/src/event.c +++ b/bacnet-stack/src/event.c @@ -1,1387 +1,1534 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ -#include -#include "event.h" -#include "bacdcode.h" -#include "npdu.h" -#include "device.h" -#include "datalink.h" -#include "timestamp.h" - -int uevent_notify_encode_apdu( - uint8_t * apdu, - BACNET_EVENT_NOTIFICATION_DATA * data) -{ - int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ - - - if (apdu) { - apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; - apdu[1] = SERVICE_UNCONFIRMED_EVENT_NOTIFICATION; /* service choice */ - apdu_len = 2; - - len += event_notify_encode_service_request(&apdu[apdu_len], data); - - if ( len > 0 ) - { - apdu_len += len; - } - else - { - apdu_len = 0; - } - } - - return apdu_len; -} - -int cevent_notify_encode_apdu( - uint8_t * apdu, - uint8_t invoke_id, - BACNET_EVENT_NOTIFICATION_DATA * data) -{ - int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ - - uint16_t max_apdu = Device_Max_APDU_Length_Accepted(); - - if (apdu) { - apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; - apdu[1] = encode_max_segs_max_apdu(0, max_apdu); - apdu[2] = invoke_id; - apdu[3] = SERVICE_CONFIRMED_EVENT_NOTIFICATION; /* service choice */ - apdu_len = 4; - - len += event_notify_encode_service_request(&apdu[apdu_len], data); - - if ( len > 0 ) - { - apdu_len += len; - } - else - { - apdu_len = 0; - } - } - - return apdu_len; -} - -int event_notify_encode_service_request( - uint8_t * apdu, - BACNET_EVENT_NOTIFICATION_DATA * data) -{ - int len = 0; /* length of each encoding */ - int apdu_len = 0; /* total length of the apdu, return value */ - //BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ - - - if (apdu) { - /* tag 0 - processIdentifier */ - len = - encode_context_unsigned(&apdu[apdu_len], 0, - data->processIdentifier); - apdu_len += len; - /* tag 1 - initiatingObjectIdentifier */ - len = - encode_context_object_id(&apdu[apdu_len], 1, - data->initiatingObjectIdentifier.type, - data->initiatingObjectIdentifier.instance); - apdu_len += len; - - /* tag 2 - eventObjectIdentifier */ - len = - encode_context_object_id(&apdu[apdu_len], 2, - data->eventObjectIdentifier.type, - data->eventObjectIdentifier.instance); - apdu_len += len; - - /* tag 3 - timeStamp */ - - len = - bacapp_encode_context_timestamp(&apdu[apdu_len], 3, - &data->timeStamp); - apdu_len += len; - - /* tag 4 - noticicationClass */ - - len = - encode_context_unsigned(&apdu[apdu_len], 4, - data->notificationClass); - apdu_len += len; - - /* tag 5 - priority */ - - len = - encode_context_unsigned(&apdu[apdu_len], 5, - data->priority); - apdu_len += len; - - /* tag 6 - eventType */ - len = - encode_context_enumerated(&apdu[apdu_len], 6, - data->eventType); - apdu_len += len; - - /* tag 7 - messageText */ - if ( data->messageText ) - { - len = - encode_context_character_string(&apdu[apdu_len], 7, - data->messageText); - apdu_len += len; - } - /* tag 8 - notifyType */ - len = - encode_context_enumerated(&apdu[apdu_len], 8, - data->notifyType); - apdu_len += len; - - switch(data->notifyType) - { - case NOTIFY_ALARM: - case NOTIFY_EVENT: - /* tag 9 - ackRequired */ - - len = - encode_context_boolean(&apdu[apdu_len], 9, - data->ackRequired); - apdu_len += len; - - /* tag 10 - fromState */ - len = - encode_context_enumerated(&apdu[apdu_len], 10, - data->fromState); - apdu_len += len; - break; - - default: - break; - } - - /* tag 11 - toState */ - len = - encode_context_enumerated(&apdu[apdu_len], 11, - data->toState); - apdu_len += len; - - switch(data->notifyType) - { - case NOTIFY_ALARM: - case NOTIFY_EVENT: - /* tag 12 - event values */ - len = encode_opening_tag(&apdu[apdu_len], 12); - apdu_len += len; - - switch(data->eventType) - { - case EVENT_CHANGE_OF_BITSTRING: - len = encode_opening_tag(&apdu[apdu_len], 0); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 0, - &data->notificationParams.changeOfBitstring.referencedBitString); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 1, - &data->notificationParams.changeOfBitstring.statusFlags); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 0); - apdu_len += len; - break; - - case EVENT_CHANGE_OF_STATE: - len = encode_opening_tag(&apdu[apdu_len], 1); - apdu_len += len; - - len = encode_opening_tag(&apdu[apdu_len], 0); - apdu_len += len; - - len = bacapp_encode_property_state(&apdu[apdu_len], - &data->notificationParams.changeOfState.newState); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 0); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 1, - &data->notificationParams.changeOfState.statusFlags); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 1); - apdu_len += len; - break; - - case EVENT_CHANGE_OF_VALUE: - len = encode_opening_tag(&apdu[apdu_len], 2); - apdu_len += len; - - len = encode_opening_tag(&apdu[apdu_len], 0); - apdu_len += len; - - switch(data->notificationParams.changeOfValue.tag) - { - case CHANGE_OF_VALUE_REAL: - len = encode_context_real(&apdu[apdu_len], 1, - data->notificationParams.changeOfValue.newValue.changeValue); - apdu_len += len; - break; - - case CHANGE_OF_VALUE_BITS: - len = encode_context_bitstring(&apdu[apdu_len], 0, - &data->notificationParams.changeOfValue.newValue.changedBits); - apdu_len += len; - break; - - default: - return 0; - } - - len = encode_closing_tag(&apdu[apdu_len], 0); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 1, - &data->notificationParams.changeOfValue.statusFlags); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 2); - apdu_len += len; - break; - - - case EVENT_FLOATING_LIMIT: - len = encode_opening_tag(&apdu[apdu_len], 4); - apdu_len += len; - - len = encode_context_real(&apdu[apdu_len], 0, - data->notificationParams.floatingLimit.referenceValue); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 1, - &data->notificationParams.floatingLimit.statusFlags); - apdu_len += len; - - len = encode_context_real(&apdu[apdu_len], 2, - data->notificationParams.floatingLimit.setPointValue); - apdu_len += len; - - len = encode_context_real(&apdu[apdu_len], 3, - data->notificationParams.floatingLimit.errorLimit); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 4); - apdu_len += len; - break; - - - case EVENT_OUT_OF_RANGE: - len = encode_opening_tag(&apdu[apdu_len], 5); - apdu_len += len; - - len = encode_context_real(&apdu[apdu_len], 0, - data->notificationParams.outOfRange.exceedingValue); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 1, - &data->notificationParams.outOfRange.statusFlags); - apdu_len += len; - - len = encode_context_real(&apdu[apdu_len], 2, - data->notificationParams.outOfRange.deadband); - apdu_len += len; - - len = encode_context_real(&apdu[apdu_len], 3, - data->notificationParams.outOfRange.exceededLimit); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 5); - apdu_len += len; - break; - - case EVENT_CHANGE_OF_LIFE_SAFETY: - len = encode_opening_tag(&apdu[apdu_len], 8); - apdu_len += len; - - len = encode_context_enumerated(&apdu[apdu_len], 0, - data->notificationParams.changeOfLifeSafety.newState); - apdu_len += len; - - len = encode_context_enumerated(&apdu[apdu_len], 1, - data->notificationParams.changeOfLifeSafety.newMode); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 2, - &data->notificationParams.changeOfLifeSafety.statusFlags); - apdu_len += len; - - len = encode_context_enumerated(&apdu[apdu_len], 3, - data->notificationParams.changeOfLifeSafety.operationExpected); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 8); - apdu_len += len; - break; - - case EVENT_BUFFER_READY: - len = encode_opening_tag(&apdu[apdu_len], 10); - apdu_len += len; - - len = bacapp_encode_context_device_obj_property_ref(&apdu[apdu_len], 0, &data->notificationParams.bufferReady.bufferProperty); - apdu_len += len; - - len = encode_context_unsigned(&apdu[apdu_len], 1, - data->notificationParams.bufferReady.previousNotification); - apdu_len += len; - - len = encode_context_unsigned(&apdu[apdu_len], 2, - data->notificationParams.bufferReady.currentNotification); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 10); - apdu_len += len; - break; - - case EVENT_UNSIGNED_RANGE: - len = encode_opening_tag(&apdu[apdu_len], 11); - apdu_len += len; - - len = encode_context_unsigned(&apdu[apdu_len], 0, - data->notificationParams.unsignedRange.exceedingValue); - apdu_len += len; - - len = encode_context_bitstring(&apdu[apdu_len], 1, - &data->notificationParams.unsignedRange.statusFlags); - apdu_len += len; - - len = encode_context_unsigned(&apdu[apdu_len], 2, - data->notificationParams.unsignedRange.exceededLimit); - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], 11); - apdu_len += len; - break; - - - case EVENT_EXTENDED: - case EVENT_COMMAND_FAILURE: - default: - assert(0); - break; - } - len = encode_closing_tag(&apdu[apdu_len], 12); - apdu_len += len; - break; - } - } - return apdu_len; -} - -int event_notify_decode_service_request( - uint8_t * apdu, - unsigned apdu_len, - BACNET_EVENT_NOTIFICATION_DATA * data) -{ - int len = 0; /* return value */ - int section_length; - uint32_t tmpUInt; - if (apdu_len && data) { - /* tag 0 - processIdentifier */ - if ((section_length = decode_context_unsigned(&apdu[len], 0, - &data->processIdentifier)) == -1) - { - return -1; - } - else - { - len += section_length; - } - - /* tag 1 - initiatingObjectIdentifier */ - if ((section_length = decode_context_object_id(&apdu[len], 1, - &data->initiatingObjectIdentifier.type, - &data->initiatingObjectIdentifier.instance)) == -1) - { - return -1; - } - else - { - len += section_length; - } - /* tag 2 - eventObjectIdentifier */ - if ((section_length = decode_context_object_id(&apdu[len], 2, - &data->eventObjectIdentifier.type, - &data->eventObjectIdentifier.instance)) == -1) - { - return -1; - } - else - { - len += section_length; - } - /* tag 3 - timeStamp */ - if ((section_length = bacapp_decode_context_timestamp(&apdu[len], 3, - &data->timeStamp)) == -1) - { - return -1; - } - else - { - len += section_length; - } - /* tag 4 - noticicationClass */ - if ((section_length = decode_context_unsigned(&apdu[len], 4, - &data->notificationClass)) == -1) - { - return -1; - } - else - { - len += section_length; - } - /* tag 5 - priority */ - if ((section_length = decode_context_unsigned(&apdu[len], 5, - &tmpUInt)) == -1) - { - return -1; - } - else - { - if ( tmpUInt > 0xff ) - { - return -1; - } - else - { - data->priority = (uint8_t)tmpUInt; - len += section_length; - } - } - /* tag 6 - eventType */ - if ((section_length = decode_context_enumerated(&apdu[len], 6, - &data->eventType)) == -1) - { - return -1; - } - else - { - len += section_length; - } - /* tag 7 - messageText */ - - if ( decode_is_context_tag(&apdu[len], 7) ) - { - if ( data->messageText != NULL ) - { - if ((section_length = decode_context_character_string(&apdu[len], 7, - data->messageText)) == -1) - { - /*FIXME This is an optional parameter */ - return -1; - } - else - { - len += section_length; - } - } - else - { - return -1; - } - } - else - { - if ( data->messageText != NULL ) - { - characterstring_init_ansi(data->messageText, ""); - } - } - - /* tag 8 - notifyType */ - if ((section_length = decode_context_enumerated(&apdu[len], 8, - &data->notifyType)) == -1) - { - return -1; - } - else - { - len += section_length; - } - switch(data->notifyType) - { - case NOTIFY_ALARM: - case NOTIFY_EVENT: - /* tag 9 - ackRequired */ - section_length = decode_context_boolean2(&apdu[len], 9, &data->ackRequired); - if ( section_length == -1 ) - { - return -1; - } - len += section_length; - - /* tag 10 - fromState */ - if ((section_length = decode_context_enumerated(&apdu[len], 10, - &data->fromState)) == -1) - { - return -1; - } - else - { - len += section_length; - } - break; - - } - /* tag 11 - toState */ - if ((section_length = decode_context_enumerated(&apdu[len], 11, - &data->toState)) == -1) - { - return -1; - } - else - { - len += section_length; - } - /* tag 12 - eventValues */ - switch(data->notifyType) - { - case NOTIFY_ALARM: - case NOTIFY_EVENT: - if ( decode_is_opening_tag_number(&apdu[len], 12 ) ) - { - len++; - } - else - { - return -1; - } - if ( decode_is_opening_tag_number(&apdu[len], (uint8_t)data->eventType ) ) - { - len++; - } - else - { - return -1; - } - - switch(data->eventType) - { - case EVENT_CHANGE_OF_BITSTRING: - if ( -1 == (section_length = decode_context_bitstring(&apdu[len], 0, &data->notificationParams.changeOfBitstring.referencedBitString))) - { - return -1; - } - len += section_length; - - if ( -1 == (section_length = decode_context_bitstring(&apdu[len], 1, &data->notificationParams.changeOfBitstring.statusFlags))) - { - return -1; - } - len += section_length; - - break; - - case EVENT_CHANGE_OF_STATE: - if ( -1 == (section_length = bacapp_decode_context_property_state(&apdu[len], 0, &data->notificationParams.changeOfState.newState))) - { - return -1; - } - len += section_length; - - if ( -1 == (section_length = decode_context_bitstring(&apdu[len], 1, &data->notificationParams.changeOfState.statusFlags))) - { - return -1; - } - len += section_length; - - break; - - case EVENT_CHANGE_OF_VALUE: - if ( !decode_is_opening_tag_number(&apdu[len], 0)) - { - return -1; - } - len++; - - if ( decode_is_context_tag(&apdu[len], CHANGE_OF_VALUE_BITS)) - { - - if ( -1 == (section_length = decode_context_bitstring(&apdu[len], 0, &data->notificationParams.changeOfValue.newValue.changedBits))) - { - return -1; - } - - len += section_length; - data->notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_BITS; - } - else if ( decode_is_context_tag(&apdu[len], CHANGE_OF_VALUE_REAL)) - { - if ( -1 == (section_length = decode_context_real(&apdu[len], 1, &data->notificationParams.changeOfValue.newValue.changeValue))) - { - return -1; - } - - len += section_length; - data->notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_REAL; - } - else - { - return -1; - } - if ( !decode_is_closing_tag_number(&apdu[len], 0)) - { - return -1; - } - len++; - - - if ( -1 == (section_length = decode_context_bitstring(&apdu[len], 1, &data->notificationParams.changeOfValue.statusFlags))) - { - return -1; - } - len += section_length; - break; - - case EVENT_FLOATING_LIMIT: - if ( -1 == ( section_length = decode_context_real(&apdu[len], 0, &data->notificationParams.floatingLimit.referenceValue))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_bitstring(&apdu[len], 1, &data->notificationParams.floatingLimit.statusFlags))) - { - return -1; - } - len += section_length; - if ( -1 == ( section_length = decode_context_real(&apdu[len], 2, &data->notificationParams.floatingLimit.setPointValue))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_real(&apdu[len], 3, &data->notificationParams.floatingLimit.errorLimit))) - { - return -1; - } - len += section_length; - break; - - case EVENT_OUT_OF_RANGE: - if ( -1 == ( section_length = decode_context_real(&apdu[len], 0, &data->notificationParams.outOfRange.exceedingValue))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_bitstring(&apdu[len], 1, &data->notificationParams.outOfRange.statusFlags))) - { - return -1; - } - len += section_length; - if ( -1 == ( section_length = decode_context_real(&apdu[len], 2, &data->notificationParams.outOfRange.deadband))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_real(&apdu[len], 3, &data->notificationParams.outOfRange.exceededLimit))) - { - return -1; - } - len += section_length; - break; - - - case EVENT_CHANGE_OF_LIFE_SAFETY: - if ( -1 == ( section_length = decode_context_enumerated(&apdu[len], 0, &data->notificationParams.changeOfLifeSafety.newState))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_enumerated(&apdu[len], 1, &data->notificationParams.changeOfLifeSafety.newMode))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_bitstring(&apdu[len], 2, &data->notificationParams.changeOfLifeSafety.statusFlags))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_enumerated(&apdu[len], 3, &data->notificationParams.changeOfLifeSafety.operationExpected))) - { - return -1; - } - len += section_length; - break; - - case EVENT_BUFFER_READY: - if ( -1 == ( section_length = bacapp_decode_context_device_obj_property_ref(&apdu[len], 0, &data->notificationParams.bufferReady.bufferProperty))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_unsigned(&apdu[len], 1, &data->notificationParams.bufferReady.previousNotification))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_unsigned(&apdu[len], 2, &data->notificationParams.bufferReady.currentNotification))) - { - return -1; - } - len += section_length; - break; - - case EVENT_UNSIGNED_RANGE: - if ( -1 == ( section_length = decode_context_unsigned(&apdu[len], 0, &data->notificationParams.unsignedRange.exceedingValue))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_bitstring(&apdu[len], 1, &data->notificationParams.unsignedRange.statusFlags))) - { - return -1; - } - len += section_length; - - if ( -1 == ( section_length = decode_context_unsigned(&apdu[len], 2, &data->notificationParams.unsignedRange.exceededLimit))) - { - return -1; - } - len += section_length; - break; - - - default: - return -1; - } - if ( decode_is_closing_tag_number(&apdu[len], (uint8_t)data->eventType ) ) - { - len++; - } - else - { - return -1; - } - if ( decode_is_closing_tag_number(&apdu[len], 12 ) ) - { - len++; - } - else - { - return -1; - } - } - } - - return len; -} - -#ifndef TEST - -int uevent_notify_send( - uint8_t * buffer, - BACNET_EVENT_NOTIFICATION_DATA * data, - BACNET_ADDRESS *dest) -{ - int len = 0; - int pdu_len = 0; - int bytes_sent = 0; - BACNET_NPDU_DATA npdu_data; - - /* encode the NPDU portion of the packet */ - npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); - pdu_len = npdu_encode_pdu(buffer, dest, NULL, &npdu_data); - /* encode the APDU portion of the packet */ - len = uevent_notify_encode_apdu(&buffer[pdu_len], data); - pdu_len += len; - /* send the data */ - bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len); - - return bytes_sent; -} -#endif - - -#ifdef TEST - -#include -#include -#include "ctest.h" - - -BACNET_EVENT_NOTIFICATION_DATA data; -BACNET_EVENT_NOTIFICATION_DATA data2; - -void testBitstring( - Test * pTest, - BACNET_BIT_STRING *bs1, - BACNET_BIT_STRING *bs2) -{ - - int i; - ct_test(pTest, bs1->bits_used == bs2->bits_used); - for ( i = 0; i < MAX_BITSTRING_BYTES; i++) - { - ct_test(pTest, bs1->value[i] == bs2->value[i]); - } -} - -void testBaseEventState( - Test * pTest) -{ - ct_test(pTest, data.processIdentifier == data2.processIdentifier); - ct_test(pTest, data.initiatingObjectIdentifier.instance == data2.initiatingObjectIdentifier.instance); - ct_test(pTest, data.initiatingObjectIdentifier.type == data2.initiatingObjectIdentifier.type); - ct_test(pTest, data.eventObjectIdentifier.instance == data2.eventObjectIdentifier.instance); - ct_test(pTest, data.eventObjectIdentifier.type == data2.eventObjectIdentifier.type); - ct_test(pTest, data.notificationClass == data2.notificationClass); - ct_test(pTest, data.priority == data2.priority); - ct_test(pTest, data.notifyType == data2.notifyType); - ct_test(pTest, data.fromState == data2.fromState); - ct_test(pTest, data.toState == data2.toState); - ct_test(pTest, data.toState == data2.toState); - - if ( data.messageText != NULL && data2.messageText != NULL ) - { - ct_test(pTest, data.messageText->encoding == data2.messageText->encoding); - ct_test(pTest, data.messageText->length == data2.messageText->length); - ct_test(pTest, strcmp(data.messageText->value, data2.messageText->value) == 0); - } - - ct_test(pTest, data.timeStamp.tag == data2.timeStamp.tag); - - switch(data.timeStamp.tag) - { - case TIME_STAMP_SEQUENCE: - ct_test(pTest, data.timeStamp.value.sequenceNum == data2.timeStamp.value.sequenceNum); - break; - - case TIME_STAMP_DATETIME: - ct_test(pTest, data.timeStamp.value.dateTime.time.hour == data2.timeStamp.value.dateTime.time.hour); - ct_test(pTest, data.timeStamp.value.dateTime.time.min == data2.timeStamp.value.dateTime.time.min); - ct_test(pTest, data.timeStamp.value.dateTime.time.sec == data2.timeStamp.value.dateTime.time.sec); - ct_test(pTest, data.timeStamp.value.dateTime.time.hundredths == data2.timeStamp.value.dateTime.time.hundredths); - - ct_test(pTest, data.timeStamp.value.dateTime.date.day == data2.timeStamp.value.dateTime.date.day); - ct_test(pTest, data.timeStamp.value.dateTime.date.month == data2.timeStamp.value.dateTime.date.month); - ct_test(pTest, data.timeStamp.value.dateTime.date.wday == data2.timeStamp.value.dateTime.date.wday); - ct_test(pTest, data.timeStamp.value.dateTime.date.year == data2.timeStamp.value.dateTime.date.year); - break; - - case TIME_STAMP_TIME: - ct_test(pTest, data.timeStamp.value.time.hour == data2.timeStamp.value.time.hour); - ct_test(pTest, data.timeStamp.value.time.min == data2.timeStamp.value.time.min); - ct_test(pTest, data.timeStamp.value.time.sec == data2.timeStamp.value.time.sec); - ct_test(pTest, data.timeStamp.value.time.hundredths == data2.timeStamp.value.time.hundredths); - break; - - default: - ct_fail(pTest, "Unknown type"); - break; - } -} - -void testEventEventState( - Test * pTest) -{ - uint8_t buffer[1000]; - int inLen; - int outLen; - BACNET_CHARACTER_STRING messageText; - BACNET_CHARACTER_STRING messageText2; - characterstring_init_ansi(&messageText, "This is a test of the message text\n"); - - data.messageText = &messageText; - data2.messageText = &messageText2; - - data.processIdentifier = 1234; - data.initiatingObjectIdentifier.type = OBJECT_ANALOG_INPUT; - data.initiatingObjectIdentifier.instance = 100; - data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT; - data.eventObjectIdentifier.instance = 200; - data.timeStamp.value.sequenceNum = 1234; - data.timeStamp.tag = TIME_STAMP_SEQUENCE; - data.notificationClass = 50; - data.priority = 50; - data.notifyType = NOTIFY_ALARM; - data.fromState = EVENT_STATE_NORMAL; - data.toState = EVENT_STATE_OFFNORMAL; - - data.eventType = EVENT_CHANGE_OF_STATE; - data.notificationParams.changeOfState.newState.tag = UNITS; - data.notificationParams.changeOfState.newState.state.units = UNITS_SQUARE_METERS; - - bitstring_init(&data.notificationParams.changeOfState.statusFlags); - bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - - inLen = event_notify_encode_service_request(&buffer[0], &data); - - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - ct_test(pTest, data.notificationParams.changeOfState.newState.tag == data2.notificationParams.changeOfState.newState.tag); - ct_test(pTest, data.notificationParams.changeOfState.newState.state.units == data2.notificationParams.changeOfState.newState.state.units); - - testBitstring(pTest, - &data.notificationParams.changeOfState.statusFlags, - &data2.notificationParams.changeOfState.statusFlags); - - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - - /* - ** Same, but timestamp of - */ - data.timeStamp.tag = TIME_STAMP_DATETIME; - data.timeStamp.value.dateTime.time.hour = 1; - data.timeStamp.value.dateTime.time.min = 2; - data.timeStamp.value.dateTime.time.sec = 3; - data.timeStamp.value.dateTime.time.hundredths = 4; - - data.timeStamp.value.dateTime.date.day = 1; - data.timeStamp.value.dateTime.date.month = 1; - data.timeStamp.value.dateTime.date.wday = 1; - data.timeStamp.value.dateTime.date.year = 1945; - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - ct_test(pTest, data.notificationParams.changeOfState.newState.tag == data2.notificationParams.changeOfState.newState.tag); - ct_test(pTest, data.notificationParams.changeOfState.newState.state.units == data2.notificationParams.changeOfState.newState.state.units); - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - - /* - ** Event Type = EVENT_CHANGE_OF_BITSTRING - */ - data.timeStamp.value.sequenceNum = 1234; - data.timeStamp.tag = TIME_STAMP_SEQUENCE; - - data.eventType = EVENT_CHANGE_OF_BITSTRING; - - bitstring_init(&data.notificationParams.changeOfBitstring.referencedBitString); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.referencedBitString, 0, true); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.referencedBitString, 1, false); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.referencedBitString, 2, true); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.referencedBitString, 2, false); - - bitstring_init(&data.notificationParams.changeOfBitstring.statusFlags); - - bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - testBitstring(pTest, - &data.notificationParams.changeOfBitstring.referencedBitString, - &data2.notificationParams.changeOfBitstring.referencedBitString); - - testBitstring(pTest, - &data.notificationParams.changeOfBitstring.statusFlags, - &data2.notificationParams.changeOfBitstring.statusFlags); - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /* - ** Event Type = EVENT_CHANGE_OF_VALUE - float value - */ - - data.eventType = EVENT_CHANGE_OF_VALUE; - data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_REAL; - data.notificationParams.changeOfValue.newValue.changeValue = 1.23f; - - bitstring_init(&data.notificationParams.changeOfValue.statusFlags); - - bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - testBitstring(pTest, - &data.notificationParams.changeOfValue.statusFlags, - &data2.notificationParams.changeOfValue.statusFlags); - - ct_test(pTest, data.notificationParams.changeOfValue.tag == - data2.notificationParams.changeOfValue.tag); - - ct_test(pTest, data.notificationParams.changeOfValue.newValue.changeValue == - data2.notificationParams.changeOfValue.newValue.changeValue); - - - - /* - ** Event Type = EVENT_CHANGE_OF_VALUE - bitstring value - */ - - data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_BITS; - - bitstring_init(&data.notificationParams.changeOfValue.newValue.changedBits); - bitstring_set_bit(&data.notificationParams.changeOfValue.newValue.changedBits, 0, true); - bitstring_set_bit(&data.notificationParams.changeOfValue.newValue.changedBits, 1, false); - bitstring_set_bit(&data.notificationParams.changeOfValue.newValue.changedBits, 2, false); - bitstring_set_bit(&data.notificationParams.changeOfValue.newValue.changedBits, 3, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - testBitstring(pTest, - &data.notificationParams.changeOfValue.statusFlags, - &data2.notificationParams.changeOfValue.statusFlags); - - ct_test(pTest, data.notificationParams.changeOfValue.tag == - data2.notificationParams.changeOfValue.tag); - - testBitstring(pTest, &data.notificationParams.changeOfValue.newValue.changedBits, - &data2.notificationParams.changeOfValue.newValue.changedBits); - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /* - ** Event Type = EVENT_FLOATING_LIMIT - */ - data.eventType = EVENT_FLOATING_LIMIT; - data.notificationParams.floatingLimit.referenceValue = 1.23f; - data.notificationParams.floatingLimit.setPointValue = 2.34f; - data.notificationParams.floatingLimit.errorLimit = 3.45f; - - bitstring_init(&data.notificationParams.floatingLimit.statusFlags); - - bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - ct_test(pTest, data.notificationParams.floatingLimit.referenceValue == - data2.notificationParams.floatingLimit.referenceValue); - - ct_test(pTest, data.notificationParams.floatingLimit.setPointValue == - data2.notificationParams.floatingLimit.setPointValue); - - ct_test(pTest, data.notificationParams.floatingLimit.errorLimit == - data2.notificationParams.floatingLimit.errorLimit); - testBitstring(pTest, - &data.notificationParams.floatingLimit.statusFlags, - &data2.notificationParams.floatingLimit.statusFlags); - - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /* - ** Event Type = EVENT_OUT_OF_RANGE - */ - data.eventType = EVENT_OUT_OF_RANGE; - data.notificationParams.outOfRange.exceedingValue = 3.45f; - data.notificationParams.outOfRange.deadband = 2.34f; - data.notificationParams.outOfRange.exceededLimit = 1.23f; - - bitstring_init(&data.notificationParams.outOfRange.statusFlags); - - bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - ct_test(pTest, data.notificationParams.outOfRange.deadband == - data2.notificationParams.outOfRange.deadband); - - ct_test(pTest, data.notificationParams.outOfRange.exceededLimit == - data2.notificationParams.outOfRange.exceededLimit); - - ct_test(pTest, data.notificationParams.outOfRange.exceedingValue == - data2.notificationParams.outOfRange.exceedingValue); - testBitstring(pTest, - &data.notificationParams.outOfRange.statusFlags, - &data2.notificationParams.outOfRange.statusFlags); - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /* - ** Event Type = EVENT_CHANGE_OF_LIFE_SAFETY - */ - data.eventType = EVENT_CHANGE_OF_LIFE_SAFETY; - data.notificationParams.changeOfLifeSafety.newState = LIFE_SAFETY_STATE_ALARM; - data.notificationParams.changeOfLifeSafety.newMode = LIFE_SAFETY_MODE_ARMED; - data.notificationParams.changeOfLifeSafety.operationExpected = LIFE_SAFETY_OP_RESET; - - bitstring_init(&data.notificationParams.changeOfLifeSafety.statusFlags); - - bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - ct_test(pTest, data.notificationParams.changeOfLifeSafety.newMode == - data2.notificationParams.changeOfLifeSafety.newMode); - - ct_test(pTest, data.notificationParams.changeOfLifeSafety.newState == - data2.notificationParams.changeOfLifeSafety.newState); - - ct_test(pTest, data.notificationParams.changeOfLifeSafety.operationExpected == - data2.notificationParams.changeOfLifeSafety.operationExpected); - - testBitstring(pTest, - &data.notificationParams.changeOfLifeSafety.statusFlags, - &data2.notificationParams.changeOfLifeSafety.statusFlags); - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /* - ** Event Type = EVENT_UNSIGNED_RANGE - */ - data.eventType = EVENT_UNSIGNED_RANGE; - data.notificationParams.unsignedRange.exceedingValue = 1234; - data.notificationParams.unsignedRange.exceededLimit = 2345; - - bitstring_init(&data.notificationParams.unsignedRange.statusFlags); - - bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, STATUS_FLAG_IN_ALARM, true); - bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, STATUS_FLAG_FAULT, false); - bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, STATUS_FLAG_OUT_OF_SERVICE, false); - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - ct_test(pTest, data.notificationParams.unsignedRange.exceedingValue == - data2.notificationParams.unsignedRange.exceedingValue); - - ct_test(pTest, data.notificationParams.unsignedRange.exceededLimit == - data2.notificationParams.unsignedRange.exceededLimit); - - testBitstring(pTest, - &data.notificationParams.unsignedRange.statusFlags, - &data2.notificationParams.unsignedRange.statusFlags); - - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /**********************************************************************************/ - /* - ** Event Type = EVENT_BUFFER_READY - */ - data.eventType = EVENT_BUFFER_READY; - data.notificationParams.bufferReady.previousNotification = 1234; - data.notificationParams.bufferReady.currentNotification = 2345; - data.notificationParams.bufferReady.bufferProperty.deviceIndentifier.type = OBJECT_DEVICE; - data.notificationParams.bufferReady.bufferProperty.deviceIndentifier.instance = 500; - data.notificationParams.bufferReady.bufferProperty.objectIdentifier.type = OBJECT_ANALOG_INPUT; - data.notificationParams.bufferReady.bufferProperty.objectIdentifier.instance = 100; - data.notificationParams.bufferReady.bufferProperty.propertyIdentifier = PROP_PRESENT_VALUE; - data.notificationParams.bufferReady.bufferProperty.arrayIndex = 0; - - memset(buffer, 0, MAX_APDU); - inLen = event_notify_encode_service_request(&buffer[0], &data); - - memset(&data2, 0, sizeof(data2)); - data2.messageText = &messageText2; - outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); - - ct_test(pTest, inLen == outLen); - testBaseEventState(pTest); - - ct_test(pTest, data.notificationParams.bufferReady.previousNotification == - data2.notificationParams.bufferReady.previousNotification); - - ct_test(pTest, data.notificationParams.bufferReady.currentNotification == - data2.notificationParams.bufferReady.currentNotification); - - - ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.deviceIndentifier.type == - data2.notificationParams.bufferReady.bufferProperty.deviceIndentifier.type); - - ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.deviceIndentifier.instance == - data2.notificationParams.bufferReady.bufferProperty.deviceIndentifier.instance); - - ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.objectIdentifier.instance == - data2.notificationParams.bufferReady.bufferProperty.objectIdentifier.instance); - - ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.objectIdentifier.type == - data2.notificationParams.bufferReady.bufferProperty.objectIdentifier.type); - - ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.propertyIdentifier == - data2.notificationParams.bufferReady.bufferProperty.propertyIdentifier); - - ct_test(pTest, data.notificationParams.bufferReady.bufferProperty.arrayIndex == - data2.notificationParams.bufferReady.bufferProperty.arrayIndex); -} - -#ifdef TEST_EVENT - -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Event", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testEventEventState); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} - -#endif // TEST_EVENT -#endif // TEST +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ +#include +#include "event.h" +#include "bacdcode.h" +#include "npdu.h" +#include "device.h" +#include "datalink.h" +#include "timestamp.h" + +int uevent_notify_encode_apdu( + uint8_t * apdu, + BACNET_EVENT_NOTIFICATION_DATA * data) +{ + int len = 0; /* length of each encoding */ + int apdu_len = 0; /* total length of the apdu, return value */ + + + if (apdu) { + apdu[0] = PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST; + apdu[1] = SERVICE_UNCONFIRMED_EVENT_NOTIFICATION; /* service choice */ + apdu_len = 2; + + len += event_notify_encode_service_request(&apdu[apdu_len], data); + + if (len > 0) { + apdu_len += len; + } else { + apdu_len = 0; + } + } + + return apdu_len; +} + +int cevent_notify_encode_apdu( + uint8_t * apdu, + uint8_t invoke_id, + BACNET_EVENT_NOTIFICATION_DATA * data) +{ + int len = 0; /* length of each encoding */ + int apdu_len = 0; /* total length of the apdu, return value */ + + uint16_t max_apdu = Device_Max_APDU_Length_Accepted(); + + if (apdu) { + apdu[0] = PDU_TYPE_CONFIRMED_SERVICE_REQUEST; + apdu[1] = encode_max_segs_max_apdu(0, max_apdu); + apdu[2] = invoke_id; + apdu[3] = SERVICE_CONFIRMED_EVENT_NOTIFICATION; /* service choice */ + apdu_len = 4; + + len += event_notify_encode_service_request(&apdu[apdu_len], data); + + if (len > 0) { + apdu_len += len; + } else { + apdu_len = 0; + } + } + + return apdu_len; +} + +int event_notify_encode_service_request( + uint8_t * apdu, + BACNET_EVENT_NOTIFICATION_DATA * data) +{ + int len = 0; /* length of each encoding */ + int apdu_len = 0; /* total length of the apdu, return value */ + //BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ + + + if (apdu) { + /* tag 0 - processIdentifier */ + len = + encode_context_unsigned(&apdu[apdu_len], 0, + data->processIdentifier); + apdu_len += len; + /* tag 1 - initiatingObjectIdentifier */ + len = + encode_context_object_id(&apdu[apdu_len], 1, + data->initiatingObjectIdentifier.type, + data->initiatingObjectIdentifier.instance); + apdu_len += len; + + /* tag 2 - eventObjectIdentifier */ + len = + encode_context_object_id(&apdu[apdu_len], 2, + data->eventObjectIdentifier.type, + data->eventObjectIdentifier.instance); + apdu_len += len; + + /* tag 3 - timeStamp */ + + len = + bacapp_encode_context_timestamp(&apdu[apdu_len], 3, + &data->timeStamp); + apdu_len += len; + + /* tag 4 - noticicationClass */ + + len = + encode_context_unsigned(&apdu[apdu_len], 4, + data->notificationClass); + apdu_len += len; + + /* tag 5 - priority */ + + len = encode_context_unsigned(&apdu[apdu_len], 5, data->priority); + apdu_len += len; + + /* tag 6 - eventType */ + len = encode_context_enumerated(&apdu[apdu_len], 6, data->eventType); + apdu_len += len; + + /* tag 7 - messageText */ + if (data->messageText) { + len = + encode_context_character_string(&apdu[apdu_len], 7, + data->messageText); + apdu_len += len; + } + /* tag 8 - notifyType */ + len = encode_context_enumerated(&apdu[apdu_len], 8, data->notifyType); + apdu_len += len; + + switch (data->notifyType) { + case NOTIFY_ALARM: + case NOTIFY_EVENT: + /* tag 9 - ackRequired */ + + len = + encode_context_boolean(&apdu[apdu_len], 9, + data->ackRequired); + apdu_len += len; + + /* tag 10 - fromState */ + len = + encode_context_enumerated(&apdu[apdu_len], 10, + data->fromState); + apdu_len += len; + break; + + default: + break; + } + + /* tag 11 - toState */ + len = encode_context_enumerated(&apdu[apdu_len], 11, data->toState); + apdu_len += len; + + switch (data->notifyType) { + case NOTIFY_ALARM: + case NOTIFY_EVENT: + /* tag 12 - event values */ + len = encode_opening_tag(&apdu[apdu_len], 12); + apdu_len += len; + + switch (data->eventType) { + case EVENT_CHANGE_OF_BITSTRING: + len = encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 0, + &data->notificationParams.changeOfBitstring. + referencedBitString); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.changeOfBitstring. + statusFlags); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 0); + apdu_len += len; + break; + + case EVENT_CHANGE_OF_STATE: + len = encode_opening_tag(&apdu[apdu_len], 1); + apdu_len += len; + + len = encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += len; + + len = + bacapp_encode_property_state(&apdu[apdu_len], + &data->notificationParams.changeOfState.newState); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 0); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.changeOfState. + statusFlags); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 1); + apdu_len += len; + break; + + case EVENT_CHANGE_OF_VALUE: + len = encode_opening_tag(&apdu[apdu_len], 2); + apdu_len += len; + + len = encode_opening_tag(&apdu[apdu_len], 0); + apdu_len += len; + + switch (data->notificationParams.changeOfValue.tag) { + case CHANGE_OF_VALUE_REAL: + len = + encode_context_real(&apdu[apdu_len], 1, + data->notificationParams.changeOfValue. + newValue.changeValue); + apdu_len += len; + break; + + case CHANGE_OF_VALUE_BITS: + len = + encode_context_bitstring(&apdu[apdu_len], + 0, + &data->notificationParams.changeOfValue. + newValue.changedBits); + apdu_len += len; + break; + + default: + return 0; + } + + len = encode_closing_tag(&apdu[apdu_len], 0); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.changeOfValue. + statusFlags); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 2); + apdu_len += len; + break; + + + case EVENT_FLOATING_LIMIT: + len = encode_opening_tag(&apdu[apdu_len], 4); + apdu_len += len; + + len = + encode_context_real(&apdu[apdu_len], 0, + data->notificationParams.floatingLimit. + referenceValue); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.floatingLimit. + statusFlags); + apdu_len += len; + + len = + encode_context_real(&apdu[apdu_len], 2, + data->notificationParams.floatingLimit. + setPointValue); + apdu_len += len; + + len = + encode_context_real(&apdu[apdu_len], 3, + data->notificationParams.floatingLimit.errorLimit); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 4); + apdu_len += len; + break; + + + case EVENT_OUT_OF_RANGE: + len = encode_opening_tag(&apdu[apdu_len], 5); + apdu_len += len; + + len = + encode_context_real(&apdu[apdu_len], 0, + data->notificationParams.outOfRange. + exceedingValue); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.outOfRange.statusFlags); + apdu_len += len; + + len = + encode_context_real(&apdu[apdu_len], 2, + data->notificationParams.outOfRange.deadband); + apdu_len += len; + + len = + encode_context_real(&apdu[apdu_len], 3, + data->notificationParams.outOfRange.exceededLimit); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 5); + apdu_len += len; + break; + + case EVENT_CHANGE_OF_LIFE_SAFETY: + len = encode_opening_tag(&apdu[apdu_len], 8); + apdu_len += len; + + len = + encode_context_enumerated(&apdu[apdu_len], 0, + data->notificationParams.changeOfLifeSafety. + newState); + apdu_len += len; + + len = + encode_context_enumerated(&apdu[apdu_len], 1, + data->notificationParams.changeOfLifeSafety. + newMode); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 2, + &data->notificationParams.changeOfLifeSafety. + statusFlags); + apdu_len += len; + + len = + encode_context_enumerated(&apdu[apdu_len], 3, + data->notificationParams.changeOfLifeSafety. + operationExpected); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 8); + apdu_len += len; + break; + + case EVENT_BUFFER_READY: + len = encode_opening_tag(&apdu[apdu_len], 10); + apdu_len += len; + + len = + bacapp_encode_context_device_obj_property_ref(&apdu + [apdu_len], 0, + &data->notificationParams.bufferReady. + bufferProperty); + apdu_len += len; + + len = + encode_context_unsigned(&apdu[apdu_len], 1, + data->notificationParams.bufferReady. + previousNotification); + apdu_len += len; + + len = + encode_context_unsigned(&apdu[apdu_len], 2, + data->notificationParams.bufferReady. + currentNotification); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 10); + apdu_len += len; + break; + + case EVENT_UNSIGNED_RANGE: + len = encode_opening_tag(&apdu[apdu_len], 11); + apdu_len += len; + + len = + encode_context_unsigned(&apdu[apdu_len], 0, + data->notificationParams.unsignedRange. + exceedingValue); + apdu_len += len; + + len = + encode_context_bitstring(&apdu[apdu_len], 1, + &data->notificationParams.unsignedRange. + statusFlags); + apdu_len += len; + + len = + encode_context_unsigned(&apdu[apdu_len], 2, + data->notificationParams.unsignedRange. + exceededLimit); + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], 11); + apdu_len += len; + break; + + + case EVENT_EXTENDED: + case EVENT_COMMAND_FAILURE: + default: + assert(0); + break; + } + len = encode_closing_tag(&apdu[apdu_len], 12); + apdu_len += len; + break; + } + } + return apdu_len; +} + +int event_notify_decode_service_request( + uint8_t * apdu, + unsigned apdu_len, + BACNET_EVENT_NOTIFICATION_DATA * data) +{ + int len = 0; /* return value */ + int section_length; + uint32_t tmpUInt; + if (apdu_len && data) { + /* tag 0 - processIdentifier */ + if ((section_length = + decode_context_unsigned(&apdu[len], 0, + &data->processIdentifier)) == -1) { + return -1; + } else { + len += section_length; + } + + /* tag 1 - initiatingObjectIdentifier */ + if ((section_length = + decode_context_object_id(&apdu[len], 1, + &data->initiatingObjectIdentifier.type, + &data->initiatingObjectIdentifier.instance)) == -1) { + return -1; + } else { + len += section_length; + } + /* tag 2 - eventObjectIdentifier */ + if ((section_length = + decode_context_object_id(&apdu[len], 2, + &data->eventObjectIdentifier.type, + &data->eventObjectIdentifier.instance)) == -1) { + return -1; + } else { + len += section_length; + } + /* tag 3 - timeStamp */ + if ((section_length = + bacapp_decode_context_timestamp(&apdu[len], 3, + &data->timeStamp)) == -1) { + return -1; + } else { + len += section_length; + } + /* tag 4 - noticicationClass */ + if ((section_length = + decode_context_unsigned(&apdu[len], 4, + &data->notificationClass)) == -1) { + return -1; + } else { + len += section_length; + } + /* tag 5 - priority */ + if ((section_length = + decode_context_unsigned(&apdu[len], 5, &tmpUInt)) == -1) { + return -1; + } else { + if (tmpUInt > 0xff) { + return -1; + } else { + data->priority = (uint8_t) tmpUInt; + len += section_length; + } + } + /* tag 6 - eventType */ + if ((section_length = + decode_context_enumerated(&apdu[len], 6, + &data->eventType)) == -1) { + return -1; + } else { + len += section_length; + } + /* tag 7 - messageText */ + + if (decode_is_context_tag(&apdu[len], 7)) { + if (data->messageText != NULL) { + if ((section_length = + decode_context_character_string(&apdu[len], 7, + data->messageText)) == -1) { + /*FIXME This is an optional parameter */ + return -1; + } else { + len += section_length; + } + } else { + return -1; + } + } else { + if (data->messageText != NULL) { + characterstring_init_ansi(data->messageText, ""); + } + } + + /* tag 8 - notifyType */ + if ((section_length = + decode_context_enumerated(&apdu[len], 8, + &data->notifyType)) == -1) { + return -1; + } else { + len += section_length; + } + switch (data->notifyType) { + case NOTIFY_ALARM: + case NOTIFY_EVENT: + /* tag 9 - ackRequired */ + section_length = + decode_context_boolean2(&apdu[len], 9, &data->ackRequired); + if (section_length == -1) { + return -1; + } + len += section_length; + + /* tag 10 - fromState */ + if ((section_length = + decode_context_enumerated(&apdu[len], 10, + &data->fromState)) == -1) { + return -1; + } else { + len += section_length; + } + break; + + } + /* tag 11 - toState */ + if ((section_length = + decode_context_enumerated(&apdu[len], 11, + &data->toState)) == -1) { + return -1; + } else { + len += section_length; + } + /* tag 12 - eventValues */ + switch (data->notifyType) { + case NOTIFY_ALARM: + case NOTIFY_EVENT: + if (decode_is_opening_tag_number(&apdu[len], 12)) { + len++; + } else { + return -1; + } + if (decode_is_opening_tag_number(&apdu[len], + (uint8_t) data->eventType)) { + len++; + } else { + return -1; + } + + switch (data->eventType) { + case EVENT_CHANGE_OF_BITSTRING: + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 0, + &data->notificationParams. + changeOfBitstring.referencedBitString))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams. + changeOfBitstring.statusFlags))) { + return -1; + } + len += section_length; + + break; + + case EVENT_CHANGE_OF_STATE: + if (-1 == (section_length = + bacapp_decode_context_property_state(&apdu + [len], 0, + &data->notificationParams.changeOfState. + newState))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.changeOfState. + statusFlags))) { + return -1; + } + len += section_length; + + break; + + case EVENT_CHANGE_OF_VALUE: + if (!decode_is_opening_tag_number(&apdu[len], 0)) { + return -1; + } + len++; + + if (decode_is_context_tag(&apdu[len], + CHANGE_OF_VALUE_BITS)) { + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 0, + &data->notificationParams. + changeOfValue.newValue.changedBits))) { + return -1; + } + + len += section_length; + data->notificationParams.changeOfValue.tag = + CHANGE_OF_VALUE_BITS; + } else if (decode_is_context_tag(&apdu[len], + CHANGE_OF_VALUE_REAL)) { + if (-1 == (section_length = + decode_context_real(&apdu[len], 1, + &data->notificationParams. + changeOfValue.newValue.changeValue))) { + return -1; + } + + len += section_length; + data->notificationParams.changeOfValue.tag = + CHANGE_OF_VALUE_REAL; + } else { + return -1; + } + if (!decode_is_closing_tag_number(&apdu[len], 0)) { + return -1; + } + len++; + + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.changeOfValue. + statusFlags))) { + return -1; + } + len += section_length; + break; + + case EVENT_FLOATING_LIMIT: + if (-1 == (section_length = + decode_context_real(&apdu[len], 0, + &data->notificationParams.floatingLimit. + referenceValue))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.floatingLimit. + statusFlags))) { + return -1; + } + len += section_length; + if (-1 == (section_length = + decode_context_real(&apdu[len], 2, + &data->notificationParams.floatingLimit. + setPointValue))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_real(&apdu[len], 3, + &data->notificationParams.floatingLimit. + errorLimit))) { + return -1; + } + len += section_length; + break; + + case EVENT_OUT_OF_RANGE: + if (-1 == (section_length = + decode_context_real(&apdu[len], 0, + &data->notificationParams.outOfRange. + exceedingValue))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.outOfRange. + statusFlags))) { + return -1; + } + len += section_length; + if (-1 == (section_length = + decode_context_real(&apdu[len], 2, + &data->notificationParams.outOfRange. + deadband))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_real(&apdu[len], 3, + &data->notificationParams.outOfRange. + exceededLimit))) { + return -1; + } + len += section_length; + break; + + + case EVENT_CHANGE_OF_LIFE_SAFETY: + if (-1 == (section_length = + decode_context_enumerated(&apdu[len], 0, + &data->notificationParams. + changeOfLifeSafety.newState))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_enumerated(&apdu[len], 1, + &data->notificationParams. + changeOfLifeSafety.newMode))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 2, + &data->notificationParams. + changeOfLifeSafety.statusFlags))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_enumerated(&apdu[len], 3, + &data->notificationParams. + changeOfLifeSafety.operationExpected))) { + return -1; + } + len += section_length; + break; + + case EVENT_BUFFER_READY: + if (-1 == (section_length = + bacapp_decode_context_device_obj_property_ref + (&apdu[len], 0, + &data->notificationParams.bufferReady. + bufferProperty))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_unsigned(&apdu[len], 1, + &data->notificationParams.bufferReady. + previousNotification))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_unsigned(&apdu[len], 2, + &data->notificationParams.bufferReady. + currentNotification))) { + return -1; + } + len += section_length; + break; + + case EVENT_UNSIGNED_RANGE: + if (-1 == (section_length = + decode_context_unsigned(&apdu[len], 0, + &data->notificationParams.unsignedRange. + exceedingValue))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_bitstring(&apdu[len], 1, + &data->notificationParams.unsignedRange. + statusFlags))) { + return -1; + } + len += section_length; + + if (-1 == (section_length = + decode_context_unsigned(&apdu[len], 2, + &data->notificationParams.unsignedRange. + exceededLimit))) { + return -1; + } + len += section_length; + break; + + + default: + return -1; + } + if (decode_is_closing_tag_number(&apdu[len], + (uint8_t) data->eventType)) { + len++; + } else { + return -1; + } + if (decode_is_closing_tag_number(&apdu[len], 12)) { + len++; + } else { + return -1; + } + } + } + + return len; +} + +#ifndef TEST + +int uevent_notify_send( + uint8_t * buffer, + BACNET_EVENT_NOTIFICATION_DATA * data, + BACNET_ADDRESS * dest) +{ + int len = 0; + int pdu_len = 0; + int bytes_sent = 0; + BACNET_NPDU_DATA npdu_data; + + /* encode the NPDU portion of the packet */ + npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); + pdu_len = npdu_encode_pdu(buffer, dest, NULL, &npdu_data); + /* encode the APDU portion of the packet */ + len = uevent_notify_encode_apdu(&buffer[pdu_len], data); + pdu_len += len; + /* send the data */ + bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len); + + return bytes_sent; +} +#endif + + +#ifdef TEST + +#include +#include +#include "ctest.h" + + +BACNET_EVENT_NOTIFICATION_DATA data; +BACNET_EVENT_NOTIFICATION_DATA data2; + +void testBitstring( + Test * pTest, + BACNET_BIT_STRING * bs1, + BACNET_BIT_STRING * bs2) +{ + + int i; + ct_test(pTest, bs1->bits_used == bs2->bits_used); + for (i = 0; i < MAX_BITSTRING_BYTES; i++) { + ct_test(pTest, bs1->value[i] == bs2->value[i]); + } +} + +void testBaseEventState( + Test * pTest) +{ + ct_test(pTest, data.processIdentifier == data2.processIdentifier); + ct_test(pTest, + data.initiatingObjectIdentifier.instance == + data2.initiatingObjectIdentifier.instance); + ct_test(pTest, + data.initiatingObjectIdentifier.type == + data2.initiatingObjectIdentifier.type); + ct_test(pTest, + data.eventObjectIdentifier.instance == + data2.eventObjectIdentifier.instance); + ct_test(pTest, + data.eventObjectIdentifier.type == data2.eventObjectIdentifier.type); + ct_test(pTest, data.notificationClass == data2.notificationClass); + ct_test(pTest, data.priority == data2.priority); + ct_test(pTest, data.notifyType == data2.notifyType); + ct_test(pTest, data.fromState == data2.fromState); + ct_test(pTest, data.toState == data2.toState); + ct_test(pTest, data.toState == data2.toState); + + if (data.messageText != NULL && data2.messageText != NULL) { + ct_test(pTest, + data.messageText->encoding == data2.messageText->encoding); + ct_test(pTest, data.messageText->length == data2.messageText->length); + ct_test(pTest, strcmp(data.messageText->value, + data2.messageText->value) == 0); + } + + ct_test(pTest, data.timeStamp.tag == data2.timeStamp.tag); + + switch (data.timeStamp.tag) { + case TIME_STAMP_SEQUENCE: + ct_test(pTest, + data.timeStamp.value.sequenceNum == + data2.timeStamp.value.sequenceNum); + break; + + case TIME_STAMP_DATETIME: + ct_test(pTest, + data.timeStamp.value.dateTime.time.hour == + data2.timeStamp.value.dateTime.time.hour); + ct_test(pTest, + data.timeStamp.value.dateTime.time.min == + data2.timeStamp.value.dateTime.time.min); + ct_test(pTest, + data.timeStamp.value.dateTime.time.sec == + data2.timeStamp.value.dateTime.time.sec); + ct_test(pTest, + data.timeStamp.value.dateTime.time.hundredths == + data2.timeStamp.value.dateTime.time.hundredths); + + ct_test(pTest, + data.timeStamp.value.dateTime.date.day == + data2.timeStamp.value.dateTime.date.day); + ct_test(pTest, + data.timeStamp.value.dateTime.date.month == + data2.timeStamp.value.dateTime.date.month); + ct_test(pTest, + data.timeStamp.value.dateTime.date.wday == + data2.timeStamp.value.dateTime.date.wday); + ct_test(pTest, + data.timeStamp.value.dateTime.date.year == + data2.timeStamp.value.dateTime.date.year); + break; + + case TIME_STAMP_TIME: + ct_test(pTest, + data.timeStamp.value.time.hour == + data2.timeStamp.value.time.hour); + ct_test(pTest, + data.timeStamp.value.time.min == + data2.timeStamp.value.time.min); + ct_test(pTest, + data.timeStamp.value.time.sec == + data2.timeStamp.value.time.sec); + ct_test(pTest, + data.timeStamp.value.time.hundredths == + data2.timeStamp.value.time.hundredths); + break; + + default: + ct_fail(pTest, "Unknown type"); + break; + } +} + +void testEventEventState( + Test * pTest) +{ + uint8_t buffer[1000]; + int inLen; + int outLen; + BACNET_CHARACTER_STRING messageText; + BACNET_CHARACTER_STRING messageText2; + characterstring_init_ansi(&messageText, + "This is a test of the message text\n"); + + data.messageText = &messageText; + data2.messageText = &messageText2; + + data.processIdentifier = 1234; + data.initiatingObjectIdentifier.type = OBJECT_ANALOG_INPUT; + data.initiatingObjectIdentifier.instance = 100; + data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT; + data.eventObjectIdentifier.instance = 200; + data.timeStamp.value.sequenceNum = 1234; + data.timeStamp.tag = TIME_STAMP_SEQUENCE; + data.notificationClass = 50; + data.priority = 50; + data.notifyType = NOTIFY_ALARM; + data.fromState = EVENT_STATE_NORMAL; + data.toState = EVENT_STATE_OFFNORMAL; + + data.eventType = EVENT_CHANGE_OF_STATE; + data.notificationParams.changeOfState.newState.tag = UNITS; + data.notificationParams.changeOfState.newState.state.units = + UNITS_SQUARE_METERS; + + bitstring_init(&data.notificationParams.changeOfState.statusFlags); + bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.changeOfState.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + + inLen = event_notify_encode_service_request(&buffer[0], &data); + + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.changeOfState.newState.tag == + data2.notificationParams.changeOfState.newState.tag); + ct_test(pTest, + data.notificationParams.changeOfState.newState.state.units == + data2.notificationParams.changeOfState.newState.state.units); + + testBitstring(pTest, &data.notificationParams.changeOfState.statusFlags, + &data2.notificationParams.changeOfState.statusFlags); + + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + + /* + ** Same, but timestamp of + */ + data.timeStamp.tag = TIME_STAMP_DATETIME; + data.timeStamp.value.dateTime.time.hour = 1; + data.timeStamp.value.dateTime.time.min = 2; + data.timeStamp.value.dateTime.time.sec = 3; + data.timeStamp.value.dateTime.time.hundredths = 4; + + data.timeStamp.value.dateTime.date.day = 1; + data.timeStamp.value.dateTime.date.month = 1; + data.timeStamp.value.dateTime.date.wday = 1; + data.timeStamp.value.dateTime.date.year = 1945; + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + ct_test(pTest, + data.notificationParams.changeOfState.newState.tag == + data2.notificationParams.changeOfState.newState.tag); + ct_test(pTest, + data.notificationParams.changeOfState.newState.state.units == + data2.notificationParams.changeOfState.newState.state.units); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + + /* + ** Event Type = EVENT_CHANGE_OF_BITSTRING + */ + data.timeStamp.value.sequenceNum = 1234; + data.timeStamp.tag = TIME_STAMP_SEQUENCE; + + data.eventType = EVENT_CHANGE_OF_BITSTRING; + + bitstring_init(&data.notificationParams.changeOfBitstring. + referencedBitString); + bitstring_set_bit(&data.notificationParams.changeOfBitstring. + referencedBitString, 0, true); + bitstring_set_bit(&data.notificationParams.changeOfBitstring. + referencedBitString, 1, false); + bitstring_set_bit(&data.notificationParams.changeOfBitstring. + referencedBitString, 2, true); + bitstring_set_bit(&data.notificationParams.changeOfBitstring. + referencedBitString, 2, false); + + bitstring_init(&data.notificationParams.changeOfBitstring.statusFlags); + + bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.changeOfBitstring.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + testBitstring(pTest, + &data.notificationParams.changeOfBitstring.referencedBitString, + &data2.notificationParams.changeOfBitstring.referencedBitString); + + testBitstring(pTest, + &data.notificationParams.changeOfBitstring.statusFlags, + &data2.notificationParams.changeOfBitstring.statusFlags); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_CHANGE_OF_VALUE - float value + */ + + data.eventType = EVENT_CHANGE_OF_VALUE; + data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_REAL; + data.notificationParams.changeOfValue.newValue.changeValue = 1.23f; + + bitstring_init(&data.notificationParams.changeOfValue.statusFlags); + + bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.changeOfValue.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + testBitstring(pTest, &data.notificationParams.changeOfValue.statusFlags, + &data2.notificationParams.changeOfValue.statusFlags); + + ct_test(pTest, + data.notificationParams.changeOfValue.tag == + data2.notificationParams.changeOfValue.tag); + + ct_test(pTest, + data.notificationParams.changeOfValue.newValue.changeValue == + data2.notificationParams.changeOfValue.newValue.changeValue); + + + + /* + ** Event Type = EVENT_CHANGE_OF_VALUE - bitstring value + */ + + data.notificationParams.changeOfValue.tag = CHANGE_OF_VALUE_BITS; + + bitstring_init(&data.notificationParams.changeOfValue.newValue. + changedBits); + bitstring_set_bit(&data.notificationParams.changeOfValue.newValue. + changedBits, 0, true); + bitstring_set_bit(&data.notificationParams.changeOfValue.newValue. + changedBits, 1, false); + bitstring_set_bit(&data.notificationParams.changeOfValue.newValue. + changedBits, 2, false); + bitstring_set_bit(&data.notificationParams.changeOfValue.newValue. + changedBits, 3, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + testBitstring(pTest, &data.notificationParams.changeOfValue.statusFlags, + &data2.notificationParams.changeOfValue.statusFlags); + + ct_test(pTest, + data.notificationParams.changeOfValue.tag == + data2.notificationParams.changeOfValue.tag); + + testBitstring(pTest, + &data.notificationParams.changeOfValue.newValue.changedBits, + &data2.notificationParams.changeOfValue.newValue.changedBits); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_FLOATING_LIMIT + */ + data.eventType = EVENT_FLOATING_LIMIT; + data.notificationParams.floatingLimit.referenceValue = 1.23f; + data.notificationParams.floatingLimit.setPointValue = 2.34f; + data.notificationParams.floatingLimit.errorLimit = 3.45f; + + bitstring_init(&data.notificationParams.floatingLimit.statusFlags); + + bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.floatingLimit.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.floatingLimit.referenceValue == + data2.notificationParams.floatingLimit.referenceValue); + + ct_test(pTest, + data.notificationParams.floatingLimit.setPointValue == + data2.notificationParams.floatingLimit.setPointValue); + + ct_test(pTest, + data.notificationParams.floatingLimit.errorLimit == + data2.notificationParams.floatingLimit.errorLimit); + testBitstring(pTest, &data.notificationParams.floatingLimit.statusFlags, + &data2.notificationParams.floatingLimit.statusFlags); + + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_OUT_OF_RANGE + */ + data.eventType = EVENT_OUT_OF_RANGE; + data.notificationParams.outOfRange.exceedingValue = 3.45f; + data.notificationParams.outOfRange.deadband = 2.34f; + data.notificationParams.outOfRange.exceededLimit = 1.23f; + + bitstring_init(&data.notificationParams.outOfRange.statusFlags); + + bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.outOfRange.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.outOfRange.deadband == + data2.notificationParams.outOfRange.deadband); + + ct_test(pTest, + data.notificationParams.outOfRange.exceededLimit == + data2.notificationParams.outOfRange.exceededLimit); + + ct_test(pTest, + data.notificationParams.outOfRange.exceedingValue == + data2.notificationParams.outOfRange.exceedingValue); + testBitstring(pTest, &data.notificationParams.outOfRange.statusFlags, + &data2.notificationParams.outOfRange.statusFlags); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_CHANGE_OF_LIFE_SAFETY + */ + data.eventType = EVENT_CHANGE_OF_LIFE_SAFETY; + data.notificationParams.changeOfLifeSafety.newState = + LIFE_SAFETY_STATE_ALARM; + data.notificationParams.changeOfLifeSafety.newMode = + LIFE_SAFETY_MODE_ARMED; + data.notificationParams.changeOfLifeSafety.operationExpected = + LIFE_SAFETY_OP_RESET; + + bitstring_init(&data.notificationParams.changeOfLifeSafety.statusFlags); + + bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.changeOfLifeSafety.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.changeOfLifeSafety.newMode == + data2.notificationParams.changeOfLifeSafety.newMode); + + ct_test(pTest, + data.notificationParams.changeOfLifeSafety.newState == + data2.notificationParams.changeOfLifeSafety.newState); + + ct_test(pTest, + data.notificationParams.changeOfLifeSafety.operationExpected == + data2.notificationParams.changeOfLifeSafety.operationExpected); + + testBitstring(pTest, + &data.notificationParams.changeOfLifeSafety.statusFlags, + &data2.notificationParams.changeOfLifeSafety.statusFlags); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_UNSIGNED_RANGE + */ + data.eventType = EVENT_UNSIGNED_RANGE; + data.notificationParams.unsignedRange.exceedingValue = 1234; + data.notificationParams.unsignedRange.exceededLimit = 2345; + + bitstring_init(&data.notificationParams.unsignedRange.statusFlags); + + bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, + STATUS_FLAG_IN_ALARM, true); + bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, + STATUS_FLAG_FAULT, false); + bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, + STATUS_FLAG_OVERRIDDEN, false); + bitstring_set_bit(&data.notificationParams.unsignedRange.statusFlags, + STATUS_FLAG_OUT_OF_SERVICE, false); + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.unsignedRange.exceedingValue == + data2.notificationParams.unsignedRange.exceedingValue); + + ct_test(pTest, + data.notificationParams.unsignedRange.exceededLimit == + data2.notificationParams.unsignedRange.exceededLimit); + + testBitstring(pTest, &data.notificationParams.unsignedRange.statusFlags, + &data2.notificationParams.unsignedRange.statusFlags); + + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /**********************************************************************************/ + /* + ** Event Type = EVENT_BUFFER_READY + */ + data.eventType = EVENT_BUFFER_READY; + data.notificationParams.bufferReady.previousNotification = 1234; + data.notificationParams.bufferReady.currentNotification = 2345; + data.notificationParams.bufferReady.bufferProperty.deviceIndentifier.type = + OBJECT_DEVICE; + data.notificationParams.bufferReady.bufferProperty.deviceIndentifier. + instance = 500; + data.notificationParams.bufferReady.bufferProperty.objectIdentifier.type = + OBJECT_ANALOG_INPUT; + data.notificationParams.bufferReady.bufferProperty.objectIdentifier. + instance = 100; + data.notificationParams.bufferReady.bufferProperty.propertyIdentifier = + PROP_PRESENT_VALUE; + data.notificationParams.bufferReady.bufferProperty.arrayIndex = 0; + + memset(buffer, 0, MAX_APDU); + inLen = event_notify_encode_service_request(&buffer[0], &data); + + memset(&data2, 0, sizeof(data2)); + data2.messageText = &messageText2; + outLen = event_notify_decode_service_request(&buffer[0], inLen, &data2); + + ct_test(pTest, inLen == outLen); + testBaseEventState(pTest); + + ct_test(pTest, + data.notificationParams.bufferReady.previousNotification == + data2.notificationParams.bufferReady.previousNotification); + + ct_test(pTest, + data.notificationParams.bufferReady.currentNotification == + data2.notificationParams.bufferReady.currentNotification); + + + ct_test(pTest, + data.notificationParams.bufferReady.bufferProperty.deviceIndentifier. + type == + data2.notificationParams.bufferReady.bufferProperty.deviceIndentifier. + type); + + ct_test(pTest, + data.notificationParams.bufferReady.bufferProperty.deviceIndentifier. + instance == + data2.notificationParams.bufferReady.bufferProperty.deviceIndentifier. + instance); + + ct_test(pTest, + data.notificationParams.bufferReady.bufferProperty.objectIdentifier. + instance == + data2.notificationParams.bufferReady.bufferProperty.objectIdentifier. + instance); + + ct_test(pTest, + data.notificationParams.bufferReady.bufferProperty.objectIdentifier. + type == + data2.notificationParams.bufferReady.bufferProperty.objectIdentifier. + type); + + ct_test(pTest, + data.notificationParams.bufferReady.bufferProperty. + propertyIdentifier == + data2.notificationParams.bufferReady.bufferProperty. + propertyIdentifier); + + ct_test(pTest, + data.notificationParams.bufferReady.bufferProperty.arrayIndex == + data2.notificationParams.bufferReady.bufferProperty.arrayIndex); +} + +#ifdef TEST_EVENT + +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Event", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testEventEventState); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} + +#endif // TEST_EVENT +#endif // TEST diff --git a/bacnet-stack/src/filename.c b/bacnet-stack/src/filename.c index 08ab11b6..253e4365 100644 --- a/bacnet-stack/src/filename.c +++ b/bacnet-stack/src/filename.c @@ -37,7 +37,7 @@ char *filename_remove_path( const char *filename_in) { - char *filename_out = (char *)filename_in; + char *filename_out = (char *) filename_in; /* allow the device ID to be set */ if (filename_in) { diff --git a/bacnet-stack/src/iam.c b/bacnet-stack/src/iam.c index f4ed89c5..20fe4ddb 100755 --- a/bacnet-stack/src/iam.c +++ b/bacnet-stack/src/iam.c @@ -80,7 +80,7 @@ int iam_decode_service_request( { int len = 0; int apdu_len = 0; /* total length of the apdu, return value */ - uint16_t object_type = 0; /* should be a Device Object */ + uint16_t object_type = 0; /* should be a Device Object */ uint32_t object_instance = 0; uint8_t tag_number = 0; uint32_t len_value = 0; diff --git a/bacnet-stack/src/ihave.c b/bacnet-stack/src/ihave.c index 15847927..89542eed 100644 --- a/bacnet-stack/src/ihave.c +++ b/bacnet-stack/src/ihave.c @@ -77,7 +77,7 @@ int ihave_decode_service_request( int len = 0; uint8_t tag_number = 0; uint32_t len_value = 0; - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ if (apdu_len && data) { /* deviceIdentifier */ diff --git a/bacnet-stack/src/memcopy.c b/bacnet-stack/src/memcopy.c index b3613c7f..40e179c5 100644 --- a/bacnet-stack/src/memcopy.c +++ b/bacnet-stack/src/memcopy.c @@ -36,12 +36,12 @@ /* copy len bytes from src to offset of dest if there is enough space. */ /* returns 0 if there is not enough space, or the number of bytes copied. */ size_t memcopy( - void * dest, - void * src, - size_t offset, /* where in dest to put the data */ + void *dest, + void *src, + size_t offset, /* where in dest to put the data */ size_t len, /* amount of data to copy */ - size_t max) /* total size of destination */ -{ + size_t max) +{ /* total size of destination */ size_t i; size_t copy_len = 0; char *s1, *s2; @@ -73,15 +73,14 @@ void test_memcopy( char big_buffer[480] = ""; size_t len = 0; - len = memcopy(&buffer[0], &data1[0], 0, - sizeof(data1), sizeof(buffer)); + len = memcopy(&buffer[0], &data1[0], 0, sizeof(data1), sizeof(buffer)); ct_test(pTest, len == sizeof(data1)); ct_test(pTest, memcmp(&buffer[0], &data1[0], len) == 0); - len = memcopy(&buffer[0], &data2[0], len, - sizeof(data2), sizeof(buffer)); + len = memcopy(&buffer[0], &data2[0], len, sizeof(data2), sizeof(buffer)); ct_test(pTest, len == sizeof(data2)); - len = memcopy(&buffer[0], &big_buffer[0], 1, - sizeof(big_buffer), sizeof(buffer)); + len = + memcopy(&buffer[0], &big_buffer[0], 1, sizeof(big_buffer), + sizeof(buffer)); ct_test(pTest, len == 0); } diff --git a/bacnet-stack/src/rp.c b/bacnet-stack/src/rp.c index b7dd178c..53937866 100644 --- a/bacnet-stack/src/rp.c +++ b/bacnet-stack/src/rp.c @@ -81,7 +81,7 @@ int rp_decode_service_request( unsigned len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ int property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ @@ -214,8 +214,8 @@ int rp_ack_decode_service_request( uint32_t len_value_type = 0; int tag_len = 0; /* length of tag decode */ int len = 0; /* total length of decodes */ - uint16_t object = 0; /* object type */ - int property = 0; /* for decoding */ + uint16_t object = 0; /* object type */ + int property = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */ /* FIXME: check apdu_len against the len during decode */ diff --git a/bacnet-stack/src/rpm.c b/bacnet-stack/src/rpm.c index e5d8a0ba..e249f15c 100644 --- a/bacnet-stack/src/rpm.c +++ b/bacnet-stack/src/rpm.c @@ -110,13 +110,13 @@ int rpm_encode_apdu( uint8_t * apdu, size_t max_apdu, uint8_t invoke_id, - BACNET_READ_ACCESS_DATA *read_access_data) + BACNET_READ_ACCESS_DATA * read_access_data) { int apdu_len = 0; /* total length of the apdu, return value */ - int len = 0; /* length of the data */ - BACNET_READ_ACCESS_DATA *rpm_object; /* current object */ - uint8_t apdu_temp[16]; /* temp for data before copy */ - BACNET_PROPERTY_REFERENCE *rpm_property; /* current property */ + int len = 0; /* length of the data */ + BACNET_READ_ACCESS_DATA *rpm_object; /* current object */ + uint8_t apdu_temp[16]; /* temp for data before copy */ + BACNET_PROPERTY_REFERENCE *rpm_property; /* current property */ len = rpm_encode_apdu_init(&apdu_temp[0], invoke_id); len = memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu); @@ -126,9 +126,9 @@ int rpm_encode_apdu( apdu_len += len; rpm_object = read_access_data; while (rpm_object) { - len = encode_context_object_id(&apdu_temp[0], 0, - rpm_object->object_type, - rpm_object->object_instance); + len = + encode_context_object_id(&apdu_temp[0], 0, rpm_object->object_type, + rpm_object->object_instance); len = memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu); if (len == 0) { return 0; @@ -144,7 +144,8 @@ int rpm_encode_apdu( rpm_property = rpm_object->listOfProperties; while (rpm_property) { /* stuff as many properties into it as APDU length will allow */ - len = encode_context_enumerated(&apdu_temp[0], 0, + len = + encode_context_enumerated(&apdu_temp[0], 0, rpm_property->propertyIdentifier); len = memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu); if (len == 0) { @@ -153,9 +154,11 @@ int rpm_encode_apdu( apdu_len += len; /* optional array index */ if (rpm_property->propertyArrayIndex != BACNET_ARRAY_ALL) { - len = encode_context_unsigned(&apdu_temp[0], 1, + len = + encode_context_unsigned(&apdu_temp[0], 1, rpm_property->propertyArrayIndex); - len = memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu); + len = + memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu); if (len == 0) { return 0; } @@ -183,7 +186,7 @@ int rpm_decode_object_id( uint32_t * object_instance) { unsigned len = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ /* check for value pointers */ if (apdu && apdu_len && object_type && object_instance) { @@ -383,7 +386,7 @@ int rpm_ack_decode_object_id( uint32_t * object_instance) { unsigned len = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ /* check for value pointers */ if (apdu && apdu_len && object_type && object_instance) { diff --git a/bacnet-stack/src/sbuf.c b/bacnet-stack/src/sbuf.c index 24a38be8..851f9d83 100644 --- a/bacnet-stack/src/sbuf.c +++ b/bacnet-stack/src/sbuf.c @@ -43,8 +43,8 @@ void sbuf_init( STATIC_BUFFER * b, /* static buffer structure */ char *data, /* data block */ - unsigned size) /* actual size, in bytes, of the data block or array of data */ -{ + unsigned size) +{ /* actual size, in bytes, of the data block or array of data */ if (b) { b->data = data; b->size = size; diff --git a/bacnet-stack/src/timestamp.c b/bacnet-stack/src/timestamp.c index cdf0b974..ee501a88 100644 --- a/bacnet-stack/src/timestamp.c +++ b/bacnet-stack/src/timestamp.c @@ -1,283 +1,301 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2008 John Minack - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#include "assert.h" -#include "timestamp.h" - -int bacapp_encode_context_timestamp( - uint8_t * apdu, - uint8_t tag_number, - BACNET_TIMESTAMP * value) -{ - int len = 0; /* length of each encoding */ - int apdu_len = 0; - - if (value && apdu) { - len = encode_opening_tag(&apdu[apdu_len], tag_number); - apdu_len += len; - - switch(value->tag) - { - case TIME_STAMP_TIME: - len = encode_context_time(&apdu[apdu_len], 0, &value->value.time); - break; - - case TIME_STAMP_SEQUENCE: - len = encode_context_unsigned(&apdu[apdu_len], 1, value->value.sequenceNum); - break; - - case TIME_STAMP_DATETIME: - len = bacapp_encode_context_datetime(&apdu[apdu_len], 2, &value->value.dateTime); - break; - - default: - len = 0; - assert(0); - break; - } - apdu_len += len; - - len = encode_closing_tag(&apdu[apdu_len], tag_number); - apdu_len += len; - } - return apdu_len; -} - -int bacapp_decode_context_timestamp( - uint8_t * apdu, - uint8_t tag_number, - BACNET_TIMESTAMP * value) -{ - int len = 0; - int section_len; - uint32_t len_value_type; - uint32_t sequenceNum; - - - if (decode_is_opening_tag_number(&apdu[len], tag_number)) { - len++; - - section_len = - decode_tag_number_and_value(&apdu[len], &value->tag, - &len_value_type); - - if ( -1 == section_len ) - { - return -1; - } - switch( value->tag ) - { - case TIME_STAMP_TIME: - if ( (section_len = decode_context_bacnet_time(&apdu[len], TIME_STAMP_TIME, &value->value.time)) == -1 ) - { - return -1; - } - else - { - len += section_len; - } - break; - - case TIME_STAMP_SEQUENCE: - if ( (section_len = decode_context_unsigned(&apdu[len], TIME_STAMP_SEQUENCE, &sequenceNum)) == -1 ) - { - return -1; - } - else - { - if ( sequenceNum <= 0xffff ) - { - len += section_len; - value->value.sequenceNum = (uint16_t)sequenceNum; - } - else - { - return -1; - } - } - break; - - case TIME_STAMP_DATETIME: - if ( (section_len = bacapp_decode_context_datetime(&apdu[len], TIME_STAMP_DATETIME, &value->value.dateTime)) == -1 ) - { - return -1; - } - else - { - len += section_len; - } - break; - - default: - return -1; - } - if (decode_is_closing_tag_number(&apdu[len], tag_number)) { - len++; - } - else - { - return -1; - } - } - return len; -} - -#ifdef TEST - -#include -#include -#include "ctest.h" - - -void testTimestampSequence( - Test * pTest) -{ - BACNET_TIMESTAMP testTimestampIn; - BACNET_TIMESTAMP testTimestampOut; - uint8_t buffer[MAX_APDU]; - int inLen; - int outLen; - - testTimestampIn.tag = TIME_STAMP_SEQUENCE; - testTimestampIn.value.sequenceNum = 0x1234; - - memset(&testTimestampOut, 0, sizeof(testTimestampOut)); - - - inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); - outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); - - ct_test(pTest, inLen == outLen); - ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); - ct_test(pTest, testTimestampIn.value.sequenceNum == testTimestampOut.value.sequenceNum); -} - -void testTimestampTime( - Test * pTest) -{ - BACNET_TIMESTAMP testTimestampIn; - BACNET_TIMESTAMP testTimestampOut; - uint8_t buffer[MAX_APDU]; - int inLen; - int outLen; - - testTimestampIn.tag = TIME_STAMP_TIME; - testTimestampIn.value.time.hour = 1; - testTimestampIn.value.time.min = 2; - testTimestampIn.value.time.sec = 3; - testTimestampIn.value.time.hundredths = 4; - - memset(&testTimestampOut, 0, sizeof(testTimestampOut)); - - - inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); - outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); - - ct_test(pTest, inLen == outLen); - ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); - ct_test(pTest, testTimestampIn.value.time.hour == testTimestampOut.value.time.hour); - ct_test(pTest, testTimestampIn.value.time.min == testTimestampOut.value.time.min); - ct_test(pTest, testTimestampIn.value.time.sec == testTimestampOut.value.time.sec); - ct_test(pTest, testTimestampIn.value.time.hundredths == testTimestampOut.value.time.hundredths); -} - -void testTimestampTimeDate( - Test * pTest) -{ - BACNET_TIMESTAMP testTimestampIn; - BACNET_TIMESTAMP testTimestampOut; - uint8_t buffer[MAX_APDU]; - int inLen; - int outLen; - - testTimestampIn.tag = TIME_STAMP_DATETIME; - testTimestampIn.value.dateTime.time.hour = 1; - testTimestampIn.value.dateTime.time.min = 2; - testTimestampIn.value.dateTime.time.sec = 3; - testTimestampIn.value.dateTime.time.hundredths = 4; - - testTimestampIn.value.dateTime.date.year = 1901; - testTimestampIn.value.dateTime.date.month = 1; - testTimestampIn.value.dateTime.date.wday = 2; - testTimestampIn.value.dateTime.date.day = 3; - - memset(&testTimestampOut, 0, sizeof(testTimestampOut)); - - inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); - outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); - - ct_test(pTest, inLen == outLen); - ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); - ct_test(pTest, testTimestampIn.value.dateTime.time.hour == testTimestampOut.value.dateTime.time.hour); - ct_test(pTest, testTimestampIn.value.dateTime.time.min == testTimestampOut.value.dateTime.time.min); - ct_test(pTest, testTimestampIn.value.dateTime.time.sec == testTimestampOut.value.dateTime.time.sec); - ct_test(pTest, testTimestampIn.value.dateTime.time.hundredths == testTimestampOut.value.dateTime.time.hundredths); - - ct_test(pTest, testTimestampIn.value.dateTime.date.year == testTimestampOut.value.dateTime.date.year); - ct_test(pTest, testTimestampIn.value.dateTime.date.month == testTimestampOut.value.dateTime.date.month); - ct_test(pTest, testTimestampIn.value.dateTime.date.wday == testTimestampOut.value.dateTime.date.wday); - ct_test(pTest, testTimestampIn.value.dateTime.date.day == testTimestampOut.value.dateTime.date.day); - -} - -#ifdef TEST_TIME_STAMP - -int main( - void) -{ - Test *pTest; - bool rc; - - pTest = ct_create("BACnet Time Stamp", NULL); - /* individual tests */ - rc = ct_addTestFunction(pTest, testTimestampSequence); - assert(rc); - - rc = ct_addTestFunction(pTest, testTimestampTime); - assert(rc); - - rc = ct_addTestFunction(pTest, testTimestampTimeDate); - assert(rc); - - ct_setStream(pTest, stdout); - ct_run(pTest); - (void) ct_report(pTest); - ct_destroy(pTest); - - return 0; -} - -#endif // TEST_TIME_STAMP -#endif // TEST - +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2008 John Minack + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include "assert.h" +#include "timestamp.h" + +int bacapp_encode_context_timestamp( + uint8_t * apdu, + uint8_t tag_number, + BACNET_TIMESTAMP * value) +{ + int len = 0; /* length of each encoding */ + int apdu_len = 0; + + if (value && apdu) { + len = encode_opening_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + + switch (value->tag) { + case TIME_STAMP_TIME: + len = + encode_context_time(&apdu[apdu_len], 0, + &value->value.time); + break; + + case TIME_STAMP_SEQUENCE: + len = + encode_context_unsigned(&apdu[apdu_len], 1, + value->value.sequenceNum); + break; + + case TIME_STAMP_DATETIME: + len = + bacapp_encode_context_datetime(&apdu[apdu_len], 2, + &value->value.dateTime); + break; + + default: + len = 0; + assert(0); + break; + } + apdu_len += len; + + len = encode_closing_tag(&apdu[apdu_len], tag_number); + apdu_len += len; + } + return apdu_len; +} + +int bacapp_decode_context_timestamp( + uint8_t * apdu, + uint8_t tag_number, + BACNET_TIMESTAMP * value) +{ + int len = 0; + int section_len; + uint32_t len_value_type; + uint32_t sequenceNum; + + + if (decode_is_opening_tag_number(&apdu[len], tag_number)) { + len++; + + section_len = + decode_tag_number_and_value(&apdu[len], &value->tag, + &len_value_type); + + if (-1 == section_len) { + return -1; + } + switch (value->tag) { + case TIME_STAMP_TIME: + if ((section_len = + decode_context_bacnet_time(&apdu[len], TIME_STAMP_TIME, + &value->value.time)) == -1) { + return -1; + } else { + len += section_len; + } + break; + + case TIME_STAMP_SEQUENCE: + if ((section_len = + decode_context_unsigned(&apdu[len], + TIME_STAMP_SEQUENCE, &sequenceNum)) == -1) { + return -1; + } else { + if (sequenceNum <= 0xffff) { + len += section_len; + value->value.sequenceNum = (uint16_t) sequenceNum; + } else { + return -1; + } + } + break; + + case TIME_STAMP_DATETIME: + if ((section_len = + bacapp_decode_context_datetime(&apdu[len], + TIME_STAMP_DATETIME, + &value->value.dateTime)) == -1) { + return -1; + } else { + len += section_len; + } + break; + + default: + return -1; + } + if (decode_is_closing_tag_number(&apdu[len], tag_number)) { + len++; + } else { + return -1; + } + } + return len; +} + +#ifdef TEST + +#include +#include +#include "ctest.h" + + +void testTimestampSequence( + Test * pTest) +{ + BACNET_TIMESTAMP testTimestampIn; + BACNET_TIMESTAMP testTimestampOut; + uint8_t buffer[MAX_APDU]; + int inLen; + int outLen; + + testTimestampIn.tag = TIME_STAMP_SEQUENCE; + testTimestampIn.value.sequenceNum = 0x1234; + + memset(&testTimestampOut, 0, sizeof(testTimestampOut)); + + + inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); + outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); + + ct_test(pTest, inLen == outLen); + ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); + ct_test(pTest, + testTimestampIn.value.sequenceNum == + testTimestampOut.value.sequenceNum); +} + +void testTimestampTime( + Test * pTest) +{ + BACNET_TIMESTAMP testTimestampIn; + BACNET_TIMESTAMP testTimestampOut; + uint8_t buffer[MAX_APDU]; + int inLen; + int outLen; + + testTimestampIn.tag = TIME_STAMP_TIME; + testTimestampIn.value.time.hour = 1; + testTimestampIn.value.time.min = 2; + testTimestampIn.value.time.sec = 3; + testTimestampIn.value.time.hundredths = 4; + + memset(&testTimestampOut, 0, sizeof(testTimestampOut)); + + + inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); + outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); + + ct_test(pTest, inLen == outLen); + ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); + ct_test(pTest, + testTimestampIn.value.time.hour == testTimestampOut.value.time.hour); + ct_test(pTest, + testTimestampIn.value.time.min == testTimestampOut.value.time.min); + ct_test(pTest, + testTimestampIn.value.time.sec == testTimestampOut.value.time.sec); + ct_test(pTest, + testTimestampIn.value.time.hundredths == + testTimestampOut.value.time.hundredths); +} + +void testTimestampTimeDate( + Test * pTest) +{ + BACNET_TIMESTAMP testTimestampIn; + BACNET_TIMESTAMP testTimestampOut; + uint8_t buffer[MAX_APDU]; + int inLen; + int outLen; + + testTimestampIn.tag = TIME_STAMP_DATETIME; + testTimestampIn.value.dateTime.time.hour = 1; + testTimestampIn.value.dateTime.time.min = 2; + testTimestampIn.value.dateTime.time.sec = 3; + testTimestampIn.value.dateTime.time.hundredths = 4; + + testTimestampIn.value.dateTime.date.year = 1901; + testTimestampIn.value.dateTime.date.month = 1; + testTimestampIn.value.dateTime.date.wday = 2; + testTimestampIn.value.dateTime.date.day = 3; + + memset(&testTimestampOut, 0, sizeof(testTimestampOut)); + + inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); + outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); + + ct_test(pTest, inLen == outLen); + ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); + ct_test(pTest, + testTimestampIn.value.dateTime.time.hour == + testTimestampOut.value.dateTime.time.hour); + ct_test(pTest, + testTimestampIn.value.dateTime.time.min == + testTimestampOut.value.dateTime.time.min); + ct_test(pTest, + testTimestampIn.value.dateTime.time.sec == + testTimestampOut.value.dateTime.time.sec); + ct_test(pTest, + testTimestampIn.value.dateTime.time.hundredths == + testTimestampOut.value.dateTime.time.hundredths); + + ct_test(pTest, + testTimestampIn.value.dateTime.date.year == + testTimestampOut.value.dateTime.date.year); + ct_test(pTest, + testTimestampIn.value.dateTime.date.month == + testTimestampOut.value.dateTime.date.month); + ct_test(pTest, + testTimestampIn.value.dateTime.date.wday == + testTimestampOut.value.dateTime.date.wday); + ct_test(pTest, + testTimestampIn.value.dateTime.date.day == + testTimestampOut.value.dateTime.date.day); + +} + +#ifdef TEST_TIME_STAMP + +int main( + void) +{ + Test *pTest; + bool rc; + + pTest = ct_create("BACnet Time Stamp", NULL); + /* individual tests */ + rc = ct_addTestFunction(pTest, testTimestampSequence); + assert(rc); + + rc = ct_addTestFunction(pTest, testTimestampTime); + assert(rc); + + rc = ct_addTestFunction(pTest, testTimestampTimeDate); + assert(rc); + + ct_setStream(pTest, stdout); + ct_run(pTest); + (void) ct_report(pTest); + ct_destroy(pTest); + + return 0; +} + +#endif // TEST_TIME_STAMP +#endif // TEST diff --git a/bacnet-stack/src/whohas.c b/bacnet-stack/src/whohas.c index 572989b5..b3c4b239 100644 --- a/bacnet-stack/src/whohas.c +++ b/bacnet-stack/src/whohas.c @@ -88,7 +88,7 @@ int whohas_decode_service_request( uint8_t tag_number = 0; uint32_t len_value = 0; uint32_t decoded_value = 0; /* for decoding */ - uint16_t decoded_type = 0; /* for decoding */ + uint16_t decoded_type = 0; /* for decoding */ if (apdu_len && data) { /* optional limits - must be used as a pair */ diff --git a/bacnet-stack/src/wp.c b/bacnet-stack/src/wp.c index 1604e6c8..a61781b3 100644 --- a/bacnet-stack/src/wp.c +++ b/bacnet-stack/src/wp.c @@ -99,7 +99,7 @@ int wp_decode_service_request( int tag_len = 0; uint8_t tag_number = 0; uint32_t len_value_type = 0; - uint16_t type = 0; /* for decoding */ + uint16_t type = 0; /* for decoding */ int property = 0; /* for decoding */ uint32_t unsigned_value = 0; int i = 0; /* loop counter */