Indented.

This commit is contained in:
skarg
2008-11-24 12:48:09 +00:00
parent fdfd6a9f9f
commit d1a1c1c8a6
71 changed files with 6873 additions and 6754 deletions
+2 -2
View File
@@ -426,8 +426,8 @@ static bool cov_subscribe(
switch (cov_data->monitoredObjectIdentifier.type) { switch (cov_data->monitoredObjectIdentifier.type) {
case OBJECT_BINARY_INPUT: case OBJECT_BINARY_INPUT:
if (Binary_Input_Valid_Instance( if (Binary_Input_Valid_Instance(cov_data->
cov_data->monitoredObjectIdentifier.instance)) { monitoredObjectIdentifier.instance)) {
status = status =
cov_list_subscribe(src, cov_data, error_class, error_code); cov_list_subscribe(src, cov_data, error_class, error_code);
} else { } else {
+3 -4
View File
@@ -244,8 +244,7 @@ int RPM_Encode_Property(
rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0], rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0],
error_class, error_code); error_class, error_code);
len = len =
memcopy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len, memcopy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len, max_apdu);
max_apdu);
if (!len) { if (!len) {
return 0; return 0;
} }
@@ -344,8 +343,8 @@ void handler_read_property_multiple(
rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], object_type, rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], object_type,
object_instance); object_instance);
copy_len = copy_len =
memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], apdu_len,
apdu_len, len, sizeof(Handler_Transmit_Buffer)); len, sizeof(Handler_Transmit_Buffer));
if (!copy_len) { if (!copy_len) {
apdu_len = apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
+18 -21
View File
@@ -45,11 +45,11 @@
/* note: initial the linked list of read_access_data */ /* note: initial the linked list of read_access_data */
static int rpm_ack_decode_service_request( static int rpm_ack_decode_service_request(
uint8_t * apdu, 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) BACNET_READ_ACCESS_DATA * read_access_data)
{ {
int decoded_len = 0; /* return value */ int decoded_len = 0; /* return value */
int len = 0; /* number of bytes returned from decoding */ int len = 0; /* number of bytes returned from decoding */
BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
@@ -60,9 +60,8 @@ static int rpm_ack_decode_service_request(
rpm_object = read_access_data; rpm_object = read_access_data;
old_rpm_object = rpm_object; old_rpm_object = rpm_object;
while (rpm_object && apdu_len) { while (rpm_object && apdu_len) {
len = rpm_ack_decode_object_id( len =
apdu, apdu_len, rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type,
&rpm_object->object_type,
&rpm_object->object_instance); &rpm_object->object_instance);
if (len <= 0) { if (len <= 0) {
old_rpm_object->next = NULL; old_rpm_object->next = NULL;
@@ -76,9 +75,8 @@ static int rpm_ack_decode_service_request(
rpm_object->listOfProperties = rpm_property; rpm_object->listOfProperties = rpm_property;
old_rpm_property = rpm_property; old_rpm_property = rpm_property;
while (rpm_property && apdu_len) { while (rpm_property && apdu_len) {
len = rpm_ack_decode_object_property( len =
apdu, rpm_ack_decode_object_property(apdu, apdu_len,
apdu_len,
&rpm_property->propertyIdentifier, &rpm_property->propertyIdentifier,
&rpm_property->propertyArrayIndex); &rpm_property->propertyArrayIndex);
if (len <= 0) { if (len <= 0) {
@@ -94,15 +92,13 @@ static int rpm_ack_decode_service_request(
apdu_len--; apdu_len--;
apdu++; apdu++;
/* note: if this is an array, there will be /* 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)); value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE));
rpm_property->value = value; rpm_property->value = value;
old_value = value; old_value = value;
while (value && (apdu_len > 0)) { while (value && (apdu_len > 0)) {
len = bacapp_decode_application_data( len =
apdu, bacapp_decode_application_data(apdu, apdu_len, value);
apdu_len,
value);
decoded_len += len; decoded_len += len;
apdu_len -= len; apdu_len -= len;
apdu += len; apdu += len;
@@ -113,7 +109,8 @@ static int rpm_ack_decode_service_request(
break; break;
} else { } else {
old_value = value; old_value = value;
value = calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE)); value =
calloc(1, sizeof(BACNET_APPLICATION_DATA_VALUE));
old_value->next = value; old_value->next = value;
} }
} }
@@ -174,8 +171,7 @@ static void PrintReadPropertyMultipleData(
} }
#endif #endif
while (value) { while (value) {
bacapp_print_value(stdout, bacapp_print_value(stdout, value,
value,
listOfProperties->propertyIdentifier); listOfProperties->propertyIdentifier);
#if PRINT_ENABLED #if PRINT_ENABLED
if (value->next) { if (value->next) {
@@ -205,19 +201,20 @@ void handler_read_property_multiple_ack(
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
{ {
int len = 0; int len = 0;
BACNET_READ_ACCESS_DATA * rpm_data; BACNET_READ_ACCESS_DATA *rpm_data;
BACNET_READ_ACCESS_DATA * old_rpm_data; BACNET_READ_ACCESS_DATA *old_rpm_data;
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
BACNET_PROPERTY_REFERENCE *old_rpm_property; BACNET_PROPERTY_REFERENCE *old_rpm_property;
BACNET_APPLICATION_DATA_VALUE *value; BACNET_APPLICATION_DATA_VALUE *value;
BACNET_APPLICATION_DATA_VALUE *old_value; BACNET_APPLICATION_DATA_VALUE *old_value;
(void) src; (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)); rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rpm_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); rpm_data);
} }
#if 1 #if 1
+81 -85
View File
@@ -1,85 +1,81 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
/* special for this module */ /* special for this module */
#include "cov.h" #include "cov.h"
#include "bactext.h" #include "bactext.h"
/* note: nothing is specified in BACnet about what to do with the /* note: nothing is specified in BACnet about what to do with the
information received from Unconfirmed COV Notifications. */ information received from Unconfirmed COV Notifications. */
void handler_ucov_notification( void handler_ucov_notification(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src) BACNET_ADDRESS * src)
{ {
BACNET_COV_DATA cov_data; BACNET_COV_DATA cov_data;
BACNET_PROPERTY_VALUE property_value; BACNET_PROPERTY_VALUE property_value;
int len = 0; int len = 0;
/* create linked list to store data if more /* create linked list to store data if more
than one property value is expected */ than one property value is expected */
property_value.next = NULL; property_value.next = NULL;
cov_data.listOfValues = &property_value; cov_data.listOfValues = &property_value;
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "UCOV: Received Notification!\n"); fprintf(stderr, "UCOV: Received Notification!\n");
#endif #endif
/* decode the service request only */ /* decode the service request only */
len = cov_notify_decode_service_request( len =
service_request, service_len, &cov_data); cov_notify_decode_service_request(service_request, service_len,
#if PRINT_ENABLED &cov_data);
if (len > 0) { #if PRINT_ENABLED
fprintf(stderr, "UCOV: PID=%u ", if (len > 0) {
cov_data.subscriberProcessIdentifier); fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
cov_data.initiatingDeviceIdentifier); fprintf(stderr, "%s %u ",
fprintf(stderr, "%s %u ", bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
bactext_object_type_name( cov_data.monitoredObjectIdentifier.instance);
cov_data.monitoredObjectIdentifier.type), fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
cov_data.monitoredObjectIdentifier.instance); fprintf(stderr, "%s ",
fprintf(stderr, "time remaining=%u seconds ", bactext_property_name(property_value.propertyIdentifier));
cov_data.timeRemaining); if (property_value.propertyArrayIndex != BACNET_ARRAY_ALL) {
fprintf(stderr, "%s ", fprintf(stderr, "%u ", property_value.propertyArrayIndex);
bactext_property_name(property_value.propertyIdentifier)); }
if (property_value.propertyArrayIndex != BACNET_ARRAY_ALL) { fprintf(stderr, "\n");
fprintf(stderr, "%u ", } else {
property_value.propertyArrayIndex); fprintf(stderr, "UCOV: Unable to decode service request!\n");
} }
fprintf(stderr, "\n"); #endif
} else { }
fprintf(stderr, "UCOV: Unable to decode service request!\n");
}
#endif
}
+93 -94
View File
@@ -1,94 +1,93 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include "config.h" #include "config.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "address.h" #include "address.h"
#include "tsm.h" #include "tsm.h"
#include "dcc.h" #include "dcc.h"
#include "npdu.h" #include "npdu.h"
#include "apdu.h" #include "apdu.h"
#include "device.h" #include "device.h"
#include "datalink.h" #include "datalink.h"
#include "iam.h" #include "iam.h"
/* some demo stuff needed */ /* some demo stuff needed */
#include "handlers.h" #include "handlers.h"
int iam_encode_pdu( int iam_encode_pdu(
uint8_t * buffer, uint8_t * buffer,
BACNET_ADDRESS * dest, BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data) BACNET_NPDU_DATA * npdu_data)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
/* I-Am is a global broadcast */ /* I-Am is a global broadcast */
datalink_get_broadcast_address(dest); datalink_get_broadcast_address(dest);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = npdu_encode_pdu(&buffer[0], dest, NULL, npdu_data); pdu_len = npdu_encode_pdu(&buffer[0], dest, NULL, npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len =
iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(), iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(),
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier());
pdu_len += len; pdu_len += len;
return pdu_len; return pdu_len;
} }
void Send_I_Am( void Send_I_Am(
uint8_t * buffer) uint8_t * buffer)
{ {
int pdu_len = 0; int pdu_len = 0;
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
#if 0 #if 0
/* note: there is discussion in the BACnet committee /* note: there is discussion in the BACnet committee
that we should allow a device to reply with I-Am that we should allow a device to reply with I-Am
so that dynamic binding always work. If the DCC so that dynamic binding always work. If the DCC
initiator loses the MAC address and routing info, initiator loses the MAC address and routing info,
they can never re-enable DCC because they can't they can never re-enable DCC because they can't
find the device with WhoIs/I-Am */ find the device with WhoIs/I-Am */
/* are we are forbidden to send? */ /* are we are forbidden to send? */
if (!dcc_communication_enabled()) if (!dcc_communication_enabled())
return 0; return 0;
#endif #endif
/* encode the data */ /* encode the data */
pdu_len = iam_encode_pdu(buffer, &dest, &npdu_data); pdu_len = iam_encode_pdu(buffer, &dest, &npdu_data);
/* send data */ /* send data */
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send I-Am Reply (%s)!\n", fprintf(stderr, "Failed to Send I-Am Reply (%s)!\n", strerror(errno));
strerror(errno)); #endif
#endif }
}
+5 -11
View File
@@ -69,8 +69,7 @@ void Send_Who_Is_Router_To_Network(
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, false,
false,
MESSAGE_PRIORITY_NORMAL); MESSAGE_PRIORITY_NORMAL);
/* fixme: should dnet/dlen/dadr be set in NPDU? */ /* fixme: should dnet/dlen/dadr be set in NPDU? */
pdu_len = pdu_len =
@@ -112,8 +111,7 @@ void Send_I_Am_Router_To_Network(
unsigned index = 0; unsigned index = 0;
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(&npdu_data,
NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, false,
false,
MESSAGE_PRIORITY_NORMAL); MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data); 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; BACNET_ROUTER_PORT *router_port;
unsigned i = 0; /* counter */ unsigned i = 0; /* counter */
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE, true,
NETWORK_MESSAGE_INIT_RT_TABLE,
true,
MESSAGE_PRIORITY_NORMAL); MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data); 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; int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
npdu_encode_npdu_network(&npdu_data, npdu_encode_npdu_network(&npdu_data, NETWORK_MESSAGE_INIT_RT_TABLE_ACK,
NETWORK_MESSAGE_INIT_RT_TABLE_ACK, false, MESSAGE_PRIORITY_NORMAL);
false,
MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data); npdu_encode_pdu(&Handler_Transmit_Buffer[0], NULL, NULL, &npdu_data);
/* encode the optional DNET list portion of the packet */ /* encode the optional DNET list portion of the packet */
+5 -10
View File
@@ -48,7 +48,7 @@ uint8_t Send_Read_Property_Multiple_Request(
uint8_t * pdu, uint8_t * pdu,
size_t max_pdu, size_t max_pdu,
uint32_t device_id, /* destination device */ 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 dest;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
@@ -72,14 +72,10 @@ uint8_t Send_Read_Property_Multiple_Request(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data);
npdu_encode_pdu(&pdu[0], &dest, &my_address,
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = rpm_encode_apdu( len =
&pdu[pdu_len], rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
max_pdu - pdu_len,
invoke_id,
read_access_data); read_access_data);
if (len <= 0) { if (len <= 0) {
return 0; return 0;
@@ -94,8 +90,7 @@ uint8_t Send_Read_Property_Multiple_Request(
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &pdu[0], (uint16_t) pdu_len); &npdu_data, &pdu[0], (uint16_t) pdu_len);
bytes_sent = bytes_sent =
datalink_send_pdu(&dest, &npdu_data, datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
&pdu[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
+16 -23
View File
@@ -86,9 +86,9 @@ static void MyRejectHandler(
} }
static void My_Router_Handler( static void My_Router_Handler(
BACNET_ADDRESS *src, BACNET_ADDRESS * src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA * npdu_data,
uint8_t * npdu, /* PDU data */ uint8_t * npdu, /* PDU data */
uint16_t npdu_len) uint16_t npdu_len)
{ {
uint16_t npdu_offset = 0; uint16_t npdu_offset = 0;
@@ -122,26 +122,26 @@ static void My_Router_Handler(
} }
} }
port_mappings = npdu[0]; port_mappings = npdu[0];
printf("\nPort Mappings: %u\n",port_mappings); printf("\nPort Mappings: %u\n", port_mappings);
npdu_offset = 1; npdu_offset = 1;
npdu_len--; npdu_len--;
while (npdu_len) { while (npdu_len) {
len = decode_unsigned16(&npdu[npdu_offset], &dnet); len = decode_unsigned16(&npdu[npdu_offset], &dnet);
printf("DNET=%hu, ",dnet); printf("DNET=%hu, ", dnet);
npdu_offset += len; npdu_offset += len;
npdu_len -= len; npdu_len -= len;
if (!npdu_len) { if (!npdu_len) {
break; break;
} }
port_id = npdu[npdu_offset]; port_id = npdu[npdu_offset];
printf("Port ID=%u, ",port_id); printf("Port ID=%u, ", port_id);
npdu_offset++; npdu_offset++;
npdu_len--; npdu_len--;
if (!npdu_len) { if (!npdu_len) {
break; break;
} }
port_info_len = npdu[npdu_offset]; 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_offset++;
npdu_len--; npdu_len--;
printf("Port Info=\""); printf("Port Info=\"");
@@ -150,7 +150,7 @@ static void My_Router_Handler(
break; break;
} }
if (j < port_info_len) { if (j < port_info_len) {
printf("%02X",npdu[npdu_offset]); printf("%02X", npdu[npdu_offset]);
npdu_offset++; npdu_offset++;
npdu_len--; npdu_len--;
} }
@@ -182,7 +182,7 @@ static void My_NPDU_Handler(
apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data); apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
if (npdu_data.network_layer_message) { 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)); (uint16_t) (pdu_len - apdu_offset));
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
@@ -325,7 +325,8 @@ static void address_parse(BACNET_ADDRESS * dst,
dst->mac_len = 6; dst->mac_len = 6;
for (index = 0; index < 4; index++) { for (index = 0; index < 4; index++) {
dst->mac[index] = mac[index]; dst->mac[index] = mac[index];
} encode_unsigned16(&dst->mac[4], }
encode_unsigned16(&dst->mac[4],
port); port);
} else { } else {
count = count =
@@ -364,22 +365,14 @@ int main(int argc, char *argv[]) {
filename_remove_path(argv[0])); filename_remove_path(argv[0]));
return 0; return 0;
} }
if (( if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
argc > 1) && (
strcmp(argv[1],
"--help") == 0)) {
printf("Send BACnet Initialize-Routing-Table message to a network\r\n" printf("Send BACnet Initialize-Routing-Table message to a network\r\n"
"and wait for responses. Displays their network information.\r\n" "and wait for responses. Displays their network information.\r\n"
"\r\n" "\r\n" "address:\r\n"
"address:\r\n"
"MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\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" "DNET ID Len Info:\r\n" "Port-info data:\r\n" " DNET:\r\n"
"Port-info data:\r\n" " Destination network number 0-65534\r\n" " ID:\r\n"
" DNET:\r\n" " Port Identifier number 0-255\r\n" " Info:\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" " 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 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" "To query using Initialize-Routing-Table message to 192.168.0.18:\r\n"
+2 -2
View File
@@ -139,7 +139,7 @@ static void milliseconds_task_win32(
/* functions used by the MS/TP state machine to put or get data */ /* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive( uint16_t MSTP_Put_Receive(
volatile struct mstp_port_struct_t * mstp_port) volatile struct mstp_port_struct_t *mstp_port)
{ {
(void) mstp_port; (void) mstp_port;
@@ -217,7 +217,7 @@ static void write_received_packet(
fwrite(&ts_sec, sizeof(ts_sec), 1, pFile); fwrite(&ts_sec, sizeof(ts_sec), 1, pFile);
fwrite(&ts_usec, sizeof(ts_usec), 1, pFile); fwrite(&ts_usec, sizeof(ts_usec), 1, pFile);
if (mstp_port->DataLength) { 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; incl_len = orig_len = 8 + max_data + 2;
} else { } else {
incl_len = orig_len = 8; incl_len = orig_len = 8;
+2 -2
View File
@@ -308,12 +308,12 @@ int Binary_Output_Encode_Property_APDU(
apdu_len = encode_application_enumerated(&apdu[0], present_value); apdu_len = encode_application_enumerated(&apdu[0], present_value);
break; break;
case PROP_ACTIVE_TEXT: case PROP_ACTIVE_TEXT:
characterstring_init_ansi(&char_string,"on" ); characterstring_init_ansi(&char_string, "on");
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_INACTIVE_TEXT: case PROP_INACTIVE_TEXT:
characterstring_init_ansi(&char_string,"off" ); characterstring_init_ansi(&char_string, "off");
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
+21 -25
View File
@@ -216,23 +216,21 @@ static void Init_DataLink(
#endif #endif
} }
void cleanup(void) void cleanup(void) {
{
BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_READ_ACCESS_DATA *old_rpm_object; BACNET_READ_ACCESS_DATA *old_rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
BACNET_PROPERTY_REFERENCE *old_rpm_property; BACNET_PROPERTY_REFERENCE *old_rpm_property;
rpm_object = Read_Access_Data; rpm_object = Read_Access_Data;
old_rpm_object = rpm_object; old_rpm_object = rpm_object;
while (rpm_object) { while (rpm_object) {
rpm_property = rpm_object->listOfProperties; rpm_property = rpm_object->listOfProperties;
while (rpm_property) { while (rpm_property) {
old_rpm_property = rpm_property; old_rpm_property = rpm_property;
rpm_property = rpm_property->next; rpm_property = rpm_property->next;
free(old_rpm_property); free(old_rpm_property);
} } old_rpm_object = rpm_object;
old_rpm_object = rpm_object;
rpm_object = rpm_object->next; rpm_object = rpm_object->next;
free(old_rpm_object); free(old_rpm_object);
} }
@@ -251,14 +249,16 @@ int main(int argc, char *argv[]) {
time_t timeout_seconds = 0; time_t timeout_seconds = 0;
uint8_t invoke_id = 0; uint8_t invoke_id = 0;
bool found = false; bool found = false;
uint8_t buffer[MAX_PDU] = {0}; uint8_t buffer[MAX_PDU] = {
0};
BACNET_READ_ACCESS_DATA *rpm_object; BACNET_READ_ACCESS_DATA *rpm_object;
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
if (argc < 5) { if (argc < 5) {
printf("Usage: %s device-instance object-type object-instance " 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)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("device-instance:\r\n" printf("device-instance:\r\n"
"BACnet Device Object Instance number that you are\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" "If the property is an array, individual elements can\r\n"
"be read. If this parameter is missing and the property\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" "is an array, the entire array will be read.\r\n"
"\r\nExample:\r\n" "\r\nExample:\r\n" "If you want read the ALL property in\r\n"
"If you want read the ALL property in\r\n"
"Device object 123, you would use the following command:\r\n" "Device object 123, you would use the following command:\r\n"
"%s 123 8 123 8 -1\r\n" "%s 123 8 123 8 -1\r\n"
"If you want read the OPTIONAL property in\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" "%s 123 8 123 80 -1\r\n"
"If you want read the REQUIRED property in\r\n" "If you want read the REQUIRED property in\r\n"
"Device object 123, you would use the following command:\r\n" "Device object 123, you would use the following command:\r\n"
"%s 123 8 123 105 -1\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]), filename_remove_path(argv[0]));
filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
} }
return 0; return 0;
} }
@@ -315,8 +312,7 @@ int main(int argc, char *argv[]) {
arg_sets = 0; arg_sets = 0;
while (rpm_object) { while (rpm_object) {
tag_value_arg = 2 + (arg_sets * 4); tag_value_arg = 2 + (arg_sets * 4);
rpm_object->object_type = rpm_object->object_type = strtol(argv[tag_value_arg], NULL, 0);
strtol(argv[tag_value_arg], NULL, 0);
tag_value_arg++; tag_value_arg++;
args_remaining--; args_remaining--;
if (args_remaining <= 0) { if (args_remaining <= 0) {
@@ -328,8 +324,7 @@ int main(int argc, char *argv[]) {
rpm_object->object_type, MAX_BACNET_OBJECT_TYPE + 1); rpm_object->object_type, MAX_BACNET_OBJECT_TYPE + 1);
return 1; return 1;
} }
rpm_object->object_instance = rpm_object->object_instance = strtol(argv[tag_value_arg], NULL, 0);
strtol(argv[tag_value_arg], NULL, 0);
tag_value_arg++; tag_value_arg++;
args_remaining--; args_remaining--;
if (args_remaining <= 0) { if (args_remaining <= 0) {
@@ -350,12 +345,14 @@ int main(int argc, char *argv[]) {
tag_value_arg++; tag_value_arg++;
args_remaining--; args_remaining--;
if (args_remaining <= 0) { 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; return 1;
} }
if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) {
fprintf(stderr, "property=%u - it must be less than %u\r\n", 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; return 1;
} }
rpm_property->propertyArrayIndex = rpm_property->propertyArrayIndex =
@@ -413,10 +410,9 @@ int main(int argc, char *argv[]) {
&Target_Address); &Target_Address);
if (found) { if (found) {
if (invoke_id == 0) { if (invoke_id == 0) {
invoke_id = Send_Read_Property_Multiple_Request( invoke_id =
&buffer[0], Send_Read_Property_Multiple_Request(&buffer[0],
sizeof(buffer), sizeof(buffer), Target_Device_Object_Instance,
Target_Device_Object_Instance,
Read_Access_Data); Read_Access_Data);
} else if (tsm_invoke_id_free(invoke_id)) } else if (tsm_invoke_id_free(invoke_id))
break; break;
+1 -1
View File
@@ -87,7 +87,7 @@ static void Init_Service_Handlers(
handler_timesync); handler_timesync);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV, apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
handler_cov_subscribe); handler_cov_subscribe);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION, apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_COV_NOTIFICATION,
handler_ucov_notification); handler_ucov_notification);
/* handle communication so we can shutup when asked */ /* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
+2 -2
View File
@@ -212,8 +212,8 @@ int main(int argc, char *argv[]) {
filename_remove_path(argv[0]), filename_remove_path(argv[0])); filename_remove_path(argv[0]), filename_remove_path(argv[0]));
return 0; return 0;
} }
/* decode the command line parameters */ /* decode the command line parameters */ cov_data.
cov_data.subscriberProcessIdentifier = strtol(argv[1], NULL, 0); subscriberProcessIdentifier = strtol(argv[1], NULL, 0);
cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0); cov_data.initiatingDeviceIdentifier = strtol(argv[2], NULL, 0);
cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0); cov_data.monitoredObjectIdentifier.type = strtol(argv[3], NULL, 0);
cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0); cov_data.monitoredObjectIdentifier.instance = strtol(argv[4], NULL, 0);
+1 -1
View File
@@ -87,7 +87,7 @@ static void Init_Service_Handlers(
void) void)
{ {
/* Note: this applications doesn't need to handle who-is /* 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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler
+5 -5
View File
@@ -86,9 +86,9 @@ static void MyRejectHandler(
} }
static void My_Router_Handler( static void My_Router_Handler(
BACNET_ADDRESS *src, BACNET_ADDRESS * src,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA * npdu_data,
uint8_t * npdu, /* PDU data */ uint8_t * npdu, /* PDU data */
uint16_t npdu_len) uint16_t npdu_len)
{ {
uint16_t npdu_offset = 0; uint16_t npdu_offset = 0;
@@ -109,7 +109,7 @@ static void My_Router_Handler(
printf("\nNetworks: "); printf("\nNetworks: ");
while (npdu_len) { while (npdu_len) {
len = decode_unsigned16(&npdu[npdu_offset], &dnet); len = decode_unsigned16(&npdu[npdu_offset], &dnet);
printf("%hu",dnet); printf("%hu", dnet);
npdu_len -= len; npdu_len -= len;
if (npdu_len) { if (npdu_len) {
printf(", "); printf(", ");
@@ -141,7 +141,7 @@ void My_NPDU_Handler(
apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data); apdu_offset = npdu_decode(&pdu[0], &dest, src, &npdu_data);
if (npdu_data.network_layer_message) { 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)); (uint16_t) (pdu_len - apdu_offset));
} else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) { } else if ((apdu_offset > 0) && (apdu_offset <= pdu_len)) {
if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) && if ((npdu_data.protocol_version == BACNET_PROTOCOL_VERSION) &&
+47 -47
View File
@@ -112,10 +112,10 @@ extern "C" {
bool decode_context_boolean( bool decode_context_boolean(
uint8_t * apdu); uint8_t * apdu);
int decode_context_boolean2( int decode_context_boolean2(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
bool *boolean_value); bool * boolean_value);
/* from clause 20.2.10 Encoding of a Bit String Value */ /* from clause 20.2.10 Encoding of a Bit String Value */
/* returns the number of apdu bytes consumed */ /* returns the number of apdu bytes consumed */
@@ -126,7 +126,7 @@ extern "C" {
int decode_context_bitstring( int decode_context_bitstring(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_BIT_STRING * bit_string); BACNET_BIT_STRING * bit_string);
/* returns the number of apdu bytes consumed */ /* returns the number of apdu bytes consumed */
int encode_bitstring( int encode_bitstring(
@@ -154,15 +154,15 @@ extern "C" {
/* from clause 20.2.7 Encoding of a Double Precision Real Number Value */ /* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */ /* returns the number of apdu bytes consumed */
int encode_application_double( int encode_application_double(
uint8_t * apdu, uint8_t * apdu,
double value); double value);
int encode_context_double( int encode_context_double(
uint8_t * apdu, uint8_t * apdu,
int tag_number, int tag_number,
double value); double value);
/* from clause 20.2.14 Encoding of an Object Identifier Value */ /* from clause 20.2.14 Encoding of an Object Identifier Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */ /* returns the number of apdu bytes consumed */
@@ -171,11 +171,11 @@ int encode_context_double(
uint16_t * object_type, uint16_t * object_type,
uint32_t * instance); uint32_t * instance);
int decode_context_object_id( int decode_context_object_id(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
uint16_t *object_type, uint16_t * object_type,
uint32_t * instance); uint32_t * instance);
int encode_bacnet_object_id( int encode_bacnet_object_id(
uint8_t * apdu, uint8_t * apdu,
@@ -210,7 +210,7 @@ int encode_context_double(
BACNET_OCTET_STRING * octet_string); BACNET_OCTET_STRING * octet_string);
int decode_context_octet_string( int decode_context_octet_string(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_OCTET_STRING * octet_string); BACNET_OCTET_STRING * octet_string);
@@ -231,10 +231,10 @@ int encode_context_double(
uint8_t * apdu, uint8_t * apdu,
uint32_t len_value, uint32_t len_value,
BACNET_CHARACTER_STRING * char_string); BACNET_CHARACTER_STRING * char_string);
int decode_context_character_string( int decode_context_character_string(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_CHARACTER_STRING * char_string); BACNET_CHARACTER_STRING * char_string);
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */ /* from clause 20.2.4 Encoding of an Unsigned Integer Value */
@@ -254,10 +254,10 @@ int encode_context_double(
uint8_t * apdu, uint8_t * apdu,
uint32_t len_value, uint32_t len_value,
uint32_t * value); uint32_t * value);
int decode_context_unsigned( int decode_context_unsigned(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
uint32_t * value); uint32_t * value);
/* from clause 20.2.5 Encoding of a Signed Integer Value */ /* from clause 20.2.5 Encoding of a Signed Integer Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */ /* and 20.2.1 General Rules for Encoding BACnet Tags */
@@ -276,10 +276,10 @@ int encode_context_double(
uint8_t * apdu, uint8_t * apdu,
uint32_t len_value, uint32_t len_value,
int32_t * value); int32_t * value);
int decode_context_signed( int decode_context_signed(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
int32_t * value); int32_t * value);
/* from clause 20.2.11 Encoding of an Enumerated Value */ /* from clause 20.2.11 Encoding of an Enumerated Value */
@@ -289,10 +289,10 @@ int encode_context_double(
uint8_t * apdu, uint8_t * apdu,
uint32_t len_value, uint32_t len_value,
int *value); int *value);
int decode_context_enumerated( int decode_context_enumerated(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_value, uint8_t tag_value,
int *value); int *value);
int encode_bacnet_enumerated( int encode_bacnet_enumerated(
uint8_t * apdu, uint8_t * apdu,
int value); int value);
@@ -320,13 +320,13 @@ int encode_context_double(
uint8_t * apdu, uint8_t * apdu,
int tag_number, int tag_number,
BACNET_TIME * btime); BACNET_TIME * btime);
int decode_application_time( int decode_application_time(
uint8_t * apdu, uint8_t * apdu,
BACNET_TIME * btime); BACNET_TIME * btime);
int decode_context_bacnet_time( int decode_context_bacnet_time(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_TIME * btime); BACNET_TIME * btime);
/* BACnet Date */ /* BACnet Date */
@@ -354,10 +354,10 @@ int encode_context_double(
int decode_application_date( int decode_application_date(
uint8_t * apdu, uint8_t * apdu,
BACNET_DATE * bdate); BACNET_DATE * bdate);
int decode_context_date( int decode_context_date(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_DATE * bdate); BACNET_DATE * bdate);
/* from clause 20.1.2.4 max-segments-accepted */ /* from clause 20.1.2.4 max-segments-accepted */
/* and clause 20.1.2.5 max-APDU-length-accepted */ /* and clause 20.1.2.5 max-APDU-length-accepted */
+72 -75
View File
@@ -1,75 +1,72 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef _BAC_DEV_PROP_REF_H_ #ifndef _BAC_DEV_PROP_REF_H_
#define _BAC_DEV_PROP_REF_H_ #define _BAC_DEV_PROP_REF_H_
typedef struct { typedef struct {
BACNET_OBJECT_ID objectIdentifier; BACNET_OBJECT_ID objectIdentifier;
BACNET_PROPERTY_ID propertyIdentifier; BACNET_PROPERTY_ID propertyIdentifier;
uint32_t arrayIndex; uint32_t arrayIndex;
BACNET_OBJECT_ID deviceIndentifier; BACNET_OBJECT_ID deviceIndentifier;
} BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE; } BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int bacapp_encode_device_obj_property_ref( int bacapp_encode_device_obj_property_ref(
uint8_t * apdu, uint8_t * apdu,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value);
int bacapp_encode_context_device_obj_property_ref( int bacapp_encode_context_device_obj_property_ref(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value);
int bacapp_decode_device_obj_property_ref( int bacapp_decode_device_obj_property_ref(
uint8_t * apdu, uint8_t * apdu,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value);
int bacapp_decode_context_device_obj_property_ref( int bacapp_decode_context_device_obj_property_ref(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value); BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif //_BAC_DEV_PROP_REF_H_
#endif //_BAC_DEV_PROP_REF_H_
+102 -104
View File
@@ -1,104 +1,102 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef _BAC_PROP_STATES_H_ #ifndef _BAC_PROP_STATES_H_
#define _BAC_PROP_STATES_H_ #define _BAC_PROP_STATES_H_
#include "bacenum.h" #include "bacenum.h"
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "bacapp.h" #include "bacapp.h"
#include <time.h> #include <time.h>
#include "timestamp.h" #include "timestamp.h"
typedef enum { typedef enum {
BOOLEAN_VALUE, BOOLEAN_VALUE,
BINARY_VALUE, BINARY_VALUE,
EVENT_TYPE, EVENT_TYPE,
POLARITY, POLARITY,
PROGRAM_CHANGE, PROGRAM_CHANGE,
PROGRAM_STATE, PROGRAM_STATE,
REASON_FOR_HALT, REASON_FOR_HALT,
RELIABILITY, RELIABILITY,
STATE, STATE,
SYSTEM_STATUS, SYSTEM_STATUS,
UNITS, UNITS,
UNSIGNED_VALUE, UNSIGNED_VALUE,
LIFE_SAFETY_MODE, LIFE_SAFETY_MODE,
LIFE_SAFETY_STATE, LIFE_SAFETY_STATE,
} BACNET_PROPERTY_STATE_TYPE; } BACNET_PROPERTY_STATE_TYPE;
typedef struct { typedef struct {
BACNET_PROPERTY_STATE_TYPE tag; BACNET_PROPERTY_STATE_TYPE tag;
union { union {
bool booleanValue; bool booleanValue;
BACNET_BINARY_PV binaryValue; BACNET_BINARY_PV binaryValue;
BACNET_EVENT_TYPE eventType; BACNET_EVENT_TYPE eventType;
BACNET_POLARITY polarity; BACNET_POLARITY polarity;
BACNET_PROGRAM_REQUEST programChange; BACNET_PROGRAM_REQUEST programChange;
BACNET_PROGRAM_STATE programState; BACNET_PROGRAM_STATE programState;
BACNET_PROGRAM_ERROR programError; BACNET_PROGRAM_ERROR programError;
BACNET_RELIABILITY reliability; BACNET_RELIABILITY reliability;
BACNET_EVENT_STATE state; BACNET_EVENT_STATE state;
BACNET_DEVICE_STATUS systemStatus; BACNET_DEVICE_STATUS systemStatus;
BACNET_ENGINEERING_UNITS units; BACNET_ENGINEERING_UNITS units;
uint32_t unsignedValue; uint32_t unsignedValue;
BACNET_LIFE_SAFETY_MODE lifeSafetyMode; BACNET_LIFE_SAFETY_MODE lifeSafetyMode;
BACNET_LIFE_SAFETY_STATE lifeSafetyState; BACNET_LIFE_SAFETY_STATE lifeSafetyState;
} state; } state;
} BACNET_PROPERTY_STATE; } BACNET_PROPERTY_STATE;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int bacapp_decode_property_state( int bacapp_decode_property_state(
uint8_t * apdu, uint8_t * apdu,
BACNET_PROPERTY_STATE * value); BACNET_PROPERTY_STATE * value);
int bacapp_decode_context_property_state( int bacapp_decode_context_property_state(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_PROPERTY_STATE * value); BACNET_PROPERTY_STATE * value);
int bacapp_encode_property_state( int bacapp_encode_property_state(
uint8_t * apdu, uint8_t * apdu,
BACNET_PROPERTY_STATE * value); BACNET_PROPERTY_STATE * value);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif // _BAC_PROP_STATES_H_
#endif // _BAC_PROP_STATES_H_
+1 -1
View File
@@ -48,7 +48,7 @@ extern "C" {
int decode_context_real( int decode_context_real(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
float *real_value); float *real_value);
int encode_bacnet_real( int encode_bacnet_real(
float value, float value,
+2 -2
View File
@@ -78,8 +78,8 @@ extern "C" {
uint8_t Send_Read_Property_Multiple_Request( uint8_t Send_Read_Property_Multiple_Request(
uint8_t * pdu, uint8_t * pdu,
size_t max_pdu, size_t max_pdu,
uint32_t device_id, /* destination device */ uint32_t device_id, /* destination device */
BACNET_READ_ACCESS_DATA *read_access_data); BACNET_READ_ACCESS_DATA * read_access_data);
/* returns the invoke ID for confirmed request, or 0 if failed */ /* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Write_Property_Request( uint8_t Send_Write_Property_Request(
+11 -11
View File
@@ -138,19 +138,19 @@ extern "C" {
void datetime_time_wildcard_set( void datetime_time_wildcard_set(
BACNET_TIME * btime); BACNET_TIME * btime);
int bacapp_encode_context_datetime( int bacapp_encode_context_datetime(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_DATE_TIME * value); BACNET_DATE_TIME * value);
int bacapp_decode_datetime( int bacapp_decode_datetime(
uint8_t * apdu, uint8_t * apdu,
BACNET_DATE_TIME * value); BACNET_DATE_TIME * value);
int bacapp_decode_context_datetime( int bacapp_decode_context_datetime(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_DATE_TIME * value); BACNET_DATE_TIME * value);
#ifdef __cplusplus #ifdef __cplusplus
} }
+15 -18
View File
@@ -38,26 +38,23 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include "bacdef.h" #include "bacdef.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#if DEBUG_ENABLED #if DEBUG_ENABLED
void debug_printf( void debug_printf(
const char *format, const char *format,
...); ...);
#else #else
static void debug_printf( static void debug_printf(
const char *format, const char *format,
...) ...) {
{ format = format;
format = format; }
#endif
#ifdef __cplusplus
} }
#endif #endif /* __cplusplus */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif #endif
+212 -212
View File
@@ -1,212 +1,212 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef BACNET_EVENT_H_ #ifndef BACNET_EVENT_H_
#define BACNET_EVENT_H_ #define BACNET_EVENT_H_
#include "bacenum.h" #include "bacenum.h"
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "bacapp.h" #include "bacapp.h"
#include "timestamp.h" #include "timestamp.h"
#include "bacpropstates.h" #include "bacpropstates.h"
#include "bacdevobjpropref.h" #include "bacdevobjpropref.h"
typedef enum { typedef enum {
CHANGE_OF_VALUE_BITS, CHANGE_OF_VALUE_BITS,
CHANGE_OF_VALUE_REAL CHANGE_OF_VALUE_REAL
} CHANGE_OF_VALUE_TYPE; } CHANGE_OF_VALUE_TYPE;
/* /*
** Based on UnconfirmedEventNotification-Request ** Based on UnconfirmedEventNotification-Request
*/ */
typedef struct BACnet_Event_Notification_Data { typedef struct BACnet_Event_Notification_Data {
uint32_t processIdentifier; uint32_t processIdentifier;
BACNET_OBJECT_ID initiatingObjectIdentifier; BACNET_OBJECT_ID initiatingObjectIdentifier;
BACNET_OBJECT_ID eventObjectIdentifier; BACNET_OBJECT_ID eventObjectIdentifier;
BACNET_TIMESTAMP timeStamp; BACNET_TIMESTAMP timeStamp;
uint32_t notificationClass; uint32_t notificationClass;
uint8_t priority; uint8_t priority;
BACNET_EVENT_TYPE eventType; BACNET_EVENT_TYPE eventType;
BACNET_CHARACTER_STRING* messageText; /* OPTIONAL - Set to NULL if not being used */ BACNET_CHARACTER_STRING *messageText; /* OPTIONAL - Set to NULL if not being used */
BACNET_NOTIFY_TYPE notifyType; BACNET_NOTIFY_TYPE notifyType;
bool ackRequired; bool ackRequired;
BACNET_EVENT_STATE fromState; BACNET_EVENT_STATE fromState;
BACNET_EVENT_STATE toState; BACNET_EVENT_STATE toState;
/* /*
** Each of these structures in the union maps to a particular eventtype ** Each of these structures in the union maps to a particular eventtype
** Based on BACnetNotificationParameters ** Based on BACnetNotificationParameters
*/ */
union { union {
/* /*
** EVENT_CHANGE_OF_BITSTRING ** EVENT_CHANGE_OF_BITSTRING
*/ */
struct { struct {
BACNET_BIT_STRING referencedBitString; BACNET_BIT_STRING referencedBitString;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
} changeOfBitstring; } changeOfBitstring;
/* /*
** EVENT_CHANGE_OF_STATE ** EVENT_CHANGE_OF_STATE
*/ */
struct { struct {
BACNET_PROPERTY_STATE newState; BACNET_PROPERTY_STATE newState;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
} changeOfState; } changeOfState;
/* /*
** EVENT_CHANGE_OF_VALUE ** EVENT_CHANGE_OF_VALUE
*/ */
struct { struct {
union { union {
BACNET_BIT_STRING changedBits; BACNET_BIT_STRING changedBits;
float changeValue; float changeValue;
} newValue; } newValue;
CHANGE_OF_VALUE_TYPE tag; CHANGE_OF_VALUE_TYPE tag;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
} changeOfValue; } changeOfValue;
/* /*
** EVENT_COMMAND_FAILURE ** EVENT_COMMAND_FAILURE
** **
** Not Supported! ** Not Supported!
*/ */
/* /*
** EVENT_FLOATING_LIMIT ** EVENT_FLOATING_LIMIT
*/ */
struct { struct {
float referenceValue; float referenceValue;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
float setPointValue; float setPointValue;
float errorLimit; float errorLimit;
} floatingLimit; } floatingLimit;
/* /*
** EVENT_OUT_OF_RANGE ** EVENT_OUT_OF_RANGE
*/ */
struct { struct {
float exceedingValue; float exceedingValue;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
float deadband; float deadband;
float exceededLimit; float exceededLimit;
} outOfRange; } outOfRange;
/* /*
** EVENT_CHANGE_OF_LIFE_SAFETY ** EVENT_CHANGE_OF_LIFE_SAFETY
*/ */
struct { struct {
BACNET_LIFE_SAFETY_STATE newState; BACNET_LIFE_SAFETY_STATE newState;
BACNET_LIFE_SAFETY_MODE newMode; BACNET_LIFE_SAFETY_MODE newMode;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
BACNET_LIFE_SAFETY_OPERATION operationExpected; BACNET_LIFE_SAFETY_OPERATION operationExpected;
} changeOfLifeSafety; } changeOfLifeSafety;
/* /*
** EVENT_EXTENDED ** EVENT_EXTENDED
** **
** Not Supported! ** Not Supported!
*/ */
/* /*
** EVENT_BUFFER_READY ** EVENT_BUFFER_READY
*/ */
struct { struct {
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE bufferProperty; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE bufferProperty;
uint32_t previousNotification; uint32_t previousNotification;
uint32_t currentNotification; uint32_t currentNotification;
} bufferReady; } bufferReady;
/* /*
** EVENT_UNSIGNED_RANGE ** EVENT_UNSIGNED_RANGE
*/ */
struct { struct {
uint32_t exceedingValue; uint32_t exceedingValue;
BACNET_BIT_STRING statusFlags; BACNET_BIT_STRING statusFlags;
uint32_t exceededLimit; uint32_t exceededLimit;
} unsignedRange; } unsignedRange;
} notificationParams; } notificationParams;
} BACNET_EVENT_NOTIFICATION_DATA; } BACNET_EVENT_NOTIFICATION_DATA;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*************************************************** /***************************************************
** **
** Creates a Confirmed Event Notification APDU ** Creates a Confirmed Event Notification APDU
** **
****************************************************/ ****************************************************/
int cevent_notify_encode_apdu( int cevent_notify_encode_apdu(
uint8_t * apdu, uint8_t * apdu,
uint8_t invoke_id, uint8_t invoke_id,
BACNET_EVENT_NOTIFICATION_DATA * data); BACNET_EVENT_NOTIFICATION_DATA * data);
/*************************************************** /***************************************************
** **
** Creates an Unconfirmed Event Notification APDU ** Creates an Unconfirmed Event Notification APDU
** **
****************************************************/ ****************************************************/
int uevent_notify_encode_apdu( int uevent_notify_encode_apdu(
uint8_t * apdu, uint8_t * apdu,
BACNET_EVENT_NOTIFICATION_DATA * data); BACNET_EVENT_NOTIFICATION_DATA * data);
/*************************************************** /***************************************************
** **
** Encodes the service data part of Event Notification ** Encodes the service data part of Event Notification
** **
****************************************************/ ****************************************************/
int event_notify_encode_service_request( int event_notify_encode_service_request(
uint8_t * apdu, uint8_t * apdu,
BACNET_EVENT_NOTIFICATION_DATA * data); BACNET_EVENT_NOTIFICATION_DATA * data);
/*************************************************** /***************************************************
** **
** Decodes the service data part of Event Notification ** Decodes the service data part of Event Notification
** **
****************************************************/ ****************************************************/
int event_notify_decode_service_request( int event_notify_decode_service_request(
uint8_t * apdu, uint8_t * apdu,
unsigned apdu_len, unsigned apdu_len,
BACNET_EVENT_NOTIFICATION_DATA * data); BACNET_EVENT_NOTIFICATION_DATA * data);
/*************************************************** /***************************************************
** **
** Sends an Unconfirmed Event Notifcation to a dest ** Sends an Unconfirmed Event Notifcation to a dest
** **
****************************************************/ ****************************************************/
int uevent_notify_send( int uevent_notify_send(
uint8_t * buffer, uint8_t * buffer,
BACNET_EVENT_NOTIFICATION_DATA * data, BACNET_EVENT_NOTIFICATION_DATA * data,
BACNET_ADDRESS *dest); BACNET_ADDRESS * dest);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* BACNET_EVENT_H_ */ #endif /* BACNET_EVENT_H_ */
+6 -6
View File
@@ -47,12 +47,12 @@ extern "C" {
/* copy len bytes from src to offset of dest if there is enough space. */ /* 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. */ /* returns 0 if there is not enough space, or the number of bytes copied. */
size_t memcopy( size_t memcopy(
void * dest, void *dest,
void * src, void *src,
size_t offset, /* where in dest to put the data */ size_t offset, /* where in dest to put the data */
size_t len, /* amount of data to copy */ size_t len, /* amount of data to copy */
size_t max); /* total size of destination */ size_t max); /* total size of destination */
#ifdef __cplusplus #ifdef __cplusplus
} }
+1 -1
View File
@@ -82,7 +82,7 @@ extern "C" {
uint8_t * apdu, uint8_t * apdu,
size_t max_apdu, size_t max_apdu,
uint8_t invoke_id, 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 */ /* decode the object portion of the service request only */
int rpm_decode_object_id( int rpm_decode_object_id(
+76 -78
View File
@@ -1,78 +1,76 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef _TIMESTAMP_H_ #ifndef _TIMESTAMP_H_
#define _TIMESTAMP_H_ #define _TIMESTAMP_H_
#include "bacdcode.h" #include "bacdcode.h"
typedef enum { typedef enum {
TIME_STAMP_TIME = 0, TIME_STAMP_TIME = 0,
TIME_STAMP_SEQUENCE = 1, TIME_STAMP_SEQUENCE = 1,
TIME_STAMP_DATETIME = 2, TIME_STAMP_DATETIME = 2,
} BACNET_TIMESTAMP_TAG; } BACNET_TIMESTAMP_TAG;
typedef uint8_t TYPE_BACNET_TIMESTAMP_TYPE; typedef uint8_t TYPE_BACNET_TIMESTAMP_TYPE;
typedef struct { typedef struct {
TYPE_BACNET_TIMESTAMP_TYPE tag; TYPE_BACNET_TIMESTAMP_TYPE tag;
union { union {
BACNET_TIME time; BACNET_TIME time;
uint16_t sequenceNum; uint16_t sequenceNum;
BACNET_DATE_TIME dateTime; BACNET_DATE_TIME dateTime;
} value; } value;
} BACNET_TIMESTAMP; } BACNET_TIMESTAMP;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
int bacapp_encode_context_timestamp( int bacapp_encode_context_timestamp(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_TIMESTAMP * value); BACNET_TIMESTAMP * value);
int bacapp_decode_context_timestamp( int bacapp_decode_context_timestamp(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_TIMESTAMP * value); BACNET_TIMESTAMP * value);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif
#endif
+19 -18
View File
@@ -1,18 +1,19 @@
#ifndef __MAIN_H__ #ifndef __MAIN_H__
#define __MAIN_H__ #define __MAIN_H__
#include <windows.h> #include <windows.h>
/* To use this exported function of dll, include this header /* To use this exported function of dll, include this header
* in your project. * in your project.
*/ */
#ifdef BUILD_DLL #ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport) #define DLL_EXPORT __declspec(dllexport)
#else #else
#define DLL_EXPORT __declspec(dllimport) #define DLL_EXPORT __declspec(dllimport)
#endif #endif
void DLL_EXPORT SomeFunction(const LPCSTR sometext); void DLL_EXPORT SomeFunction(
const LPCSTR sometext);
#endif // __MAIN_H__
#endif // __MAIN_H__
+159 -159
View File
@@ -1,159 +1,159 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* Analog Input Objects customize for your use */ /* Analog Input Objects customize for your use */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "config.h" #include "config.h"
/* Analog Input = Photocell */ /* Analog Input = Photocell */
#define MAX_ANALOG_INPUTS 9 #define MAX_ANALOG_INPUTS 9
#if (MAX_ANALOG_INPUTS > 9) #if (MAX_ANALOG_INPUTS > 9)
#error Modify the Analog_Input_Name to handle multiple digits #error Modify the Analog_Input_Name to handle multiple digits
#endif #endif
float Present_Value[MAX_ANALOG_INPUTS]; float Present_Value[MAX_ANALOG_INPUTS];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(
uint32_t object_instance) uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_INPUTS) if (object_instance < MAX_ANALOG_INPUTS)
return true; return true;
return false; return false;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(
void) void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(
unsigned index) unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. */ /* we simply have 0-n object instances. */
unsigned Analog_Input_Instance_To_Index( unsigned Analog_Input_Instance_To_Index(
uint32_t object_instance) uint32_t object_instance)
{ {
return object_instance; return object_instance;
} }
char *Analog_Input_Name( char *Analog_Input_Name(
uint32_t object_instance) uint32_t object_instance)
{ {
static char text_string[5] = "AI-0"; /* okay for single thread */ static char text_string[5] = "AI-0"; /* okay for single thread */
if (object_instance < MAX_ANALOG_INPUTS) { if (object_instance < MAX_ANALOG_INPUTS) {
text_string[3] = '0' + (uint8_t) object_instance; text_string[3] = '0' + (uint8_t) object_instance;
return text_string; return text_string;
} }
return NULL; return NULL;
} }
/* return apdu length, or -1 on error */ /* return apdu length, or -1 on error */
/* assumption - object has already exists */ /* assumption - object has already exists */
int Analog_Input_Encode_Property_APDU( int Analog_Input_Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
unsigned object_index; unsigned object_index;
(void) array_index; (void) array_index;
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance); object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different. You could make Description writable and different.
Note that Object-Name must be unique in this device */ Note that Object-Name must be unique in this device */
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance)); Analog_Input_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
object_index = Analog_Input_Instance_To_Index(object_instance); object_index = Analog_Input_Instance_To_Index(object_instance);
apdu_len = apdu_len =
encode_application_real(&apdu[0], Present_Value[object_index]); encode_application_real(&apdu[0], Present_Value[object_index]);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); 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_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false); apdu_len = encode_application_boolean(&apdu[0], false);
break; break;
case PROP_UNITS: case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
return apdu_len; return apdu_len;
} }
+123 -123
View File
@@ -1,123 +1,123 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2007 Steve Karg Copyright (C) 2007 Steve Karg
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "bits.h" #include "bits.h"
#include "apdu.h" #include "apdu.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "handlers.h" #include "handlers.h"
bool apdu_service_supported( bool apdu_service_supported(
BACNET_SERVICES_SUPPORTED service_supported) BACNET_SERVICES_SUPPORTED service_supported)
{ {
bool status = false; bool status = false;
if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) { if (service_supported == SERVICE_SUPPORTED_READ_PROPERTY) {
status = true; status = true;
} }
return status; return status;
} }
uint16_t apdu_decode_confirmed_service_request( uint16_t apdu_decode_confirmed_service_request(
uint8_t * apdu, /* APDU data */ uint8_t * apdu, /* APDU data */
uint16_t apdu_len, uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA * service_data, BACNET_CONFIRMED_SERVICE_DATA * service_data,
uint8_t * service_choice, uint8_t * service_choice,
uint8_t ** service_request, uint8_t ** service_request,
uint16_t * service_request_len) uint16_t * service_request_len)
{ {
uint16_t len = 0; /* counts where we are in PDU */ uint16_t len = 0; /* counts where we are in PDU */
service_data->segmented_message = (apdu[0] & BIT3) ? true : false; service_data->segmented_message = (apdu[0] & BIT3) ? true : false;
service_data->more_follows = (apdu[0] & BIT2) ? true : false; service_data->more_follows = (apdu[0] & BIT2) ? true : false;
service_data->segmented_response_accepted = service_data->segmented_response_accepted =
(apdu[0] & BIT1) ? true : false; (apdu[0] & BIT1) ? true : false;
service_data->max_segs = decode_max_segs(apdu[1]); service_data->max_segs = decode_max_segs(apdu[1]);
service_data->max_resp = decode_max_apdu(apdu[1]); service_data->max_resp = decode_max_apdu(apdu[1]);
service_data->invoke_id = apdu[2]; service_data->invoke_id = apdu[2];
len = 3; len = 3;
if (service_data->segmented_message) { if (service_data->segmented_message) {
service_data->sequence_number = apdu[len++]; service_data->sequence_number = apdu[len++];
service_data->proposed_window_number = apdu[len++]; service_data->proposed_window_number = apdu[len++];
} }
*service_choice = apdu[len++]; *service_choice = apdu[len++];
*service_request = &apdu[len]; *service_request = &apdu[len];
*service_request_len = apdu_len - len; *service_request_len = apdu_len - len;
return len; return len;
} }
void apdu_handler( void apdu_handler(
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
uint8_t * apdu, /* APDU data */ uint8_t * apdu, /* APDU data */
uint16_t apdu_len) uint16_t apdu_len)
{ {
BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 }; BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 };
uint8_t service_choice = 0; uint8_t service_choice = 0;
uint8_t *service_request = NULL; uint8_t *service_request = NULL;
uint16_t service_request_len = 0; uint16_t service_request_len = 0;
uint16_t len = 0; /* counts where we are in PDU */ uint16_t len = 0; /* counts where we are in PDU */
if (apdu) { if (apdu) {
/* PDU Type */ /* PDU Type */
switch (apdu[0] & 0xF0) { switch (apdu[0] & 0xF0) {
case PDU_TYPE_CONFIRMED_SERVICE_REQUEST: case PDU_TYPE_CONFIRMED_SERVICE_REQUEST:
len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */ len = apdu_decode_confirmed_service_request(&apdu[0], /* APDU data */
apdu_len, &service_data, &service_choice, &service_request, apdu_len, &service_data, &service_choice, &service_request,
&service_request_len); &service_request_len);
if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) { if (service_choice == SERVICE_CONFIRMED_READ_PROPERTY) {
handler_read_property(service_request, service_request_len, handler_read_property(service_request, service_request_len,
src, &service_data); src, &service_data);
} else { } else {
handler_unrecognized_service(service_request, handler_unrecognized_service(service_request,
service_request_len, src, &service_data); service_request_len, src, &service_data);
} }
break; break;
case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST: case PDU_TYPE_UNCONFIRMED_SERVICE_REQUEST:
case PDU_TYPE_SIMPLE_ACK: case PDU_TYPE_SIMPLE_ACK:
case PDU_TYPE_COMPLEX_ACK: case PDU_TYPE_COMPLEX_ACK:
case PDU_TYPE_SEGMENT_ACK: case PDU_TYPE_SEGMENT_ACK:
case PDU_TYPE_ERROR: case PDU_TYPE_ERROR:
case PDU_TYPE_REJECT: case PDU_TYPE_REJECT:
case PDU_TYPE_ABORT: case PDU_TYPE_ABORT:
default: default:
break; break;
} }
} }
return; return;
} }
+253 -253
View File
@@ -1,253 +1,253 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* Analog Value Objects - customize for your use */ /* Analog Value Objects - customize for your use */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacenum.h" #include "bacenum.h"
#include "bacapp.h" #include "bacapp.h"
#include "config.h" /* the custom stuff */ #include "config.h" /* the custom stuff */
#include "wp.h" #include "wp.h"
#include "av.h" #include "av.h"
#if (MAX_ANALOG_VALUES > 10) #if (MAX_ANALOG_VALUES > 10)
#error Modify the Analog_Value_Name to handle multiple digits #error Modify the Analog_Value_Name to handle multiple digits
#endif #endif
float AV_Present_Value[MAX_ANALOG_VALUES]; float AV_Present_Value[MAX_ANALOG_VALUES];
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(
uint32_t object_instance) uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
return true; return true;
return false; return false;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(
void) void)
{ {
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(
unsigned index) unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(
uint32_t object_instance) uint32_t object_instance)
{ {
return object_instance; return object_instance;
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
char *Analog_Value_Name( char *Analog_Value_Name(
uint32_t object_instance) uint32_t object_instance)
{ {
static char text_string[5] = "AV-"; /* okay for single thread */ static char text_string[5] = "AV-"; /* okay for single thread */
text_string[3] = '0' + (uint8_t) object_instance; text_string[3] = '0' + (uint8_t) object_instance;
return text_string; return text_string;
} }
/* return apdu len, or -1 on error */ /* return apdu len, or -1 on error */
int Analog_Value_Encode_Property_APDU( int Analog_Value_Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
unsigned object_index; unsigned object_index;
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
object_instance); object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Analog_Value_Name(object_instance)); Analog_Value_Name(object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE); encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
apdu_len = apdu_len =
encode_application_real(&apdu[0], encode_application_real(&apdu[0],
AV_Present_Value[object_index]); AV_Present_Value[object_index]);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false); 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_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false); bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false); apdu_len = encode_application_boolean(&apdu[0], false);
break; break;
case PROP_UNITS: case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT); apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
return apdu_len; return apdu_len;
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data, BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
if (!Analog_Value_Valid_Instance(wp_data->object_instance)) { if (!Analog_Value_Valid_Instance(wp_data->object_instance)) {
*error_class = ERROR_CLASS_OBJECT; *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT; *error_code = ERROR_CODE_UNKNOWN_OBJECT;
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len =
bacapp_decode_application_data(wp_data->application_data, bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */ /* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) { if (value.tag == BACNET_APPLICATION_TAG_REAL) {
object_index = object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance); Analog_Value_Instance_To_Index(wp_data->object_instance);
AV_Present_Value[object_index] = value.type.Real; AV_Present_Value[object_index] = value.type.Real;
status = true; status = true;
} else { } else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE; *error_code = ERROR_CODE_INVALID_DATA_TYPE;
} }
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED; *error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break; break;
} }
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
void testAnalog_Value( void testAnalog_Value(
Test * pTest) Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = { 0 }; uint8_t apdu[MAX_APDU] = { 0 };
int len = 0; int len = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE; BACNET_OBJECT_TYPE decoded_type = OBJECT_ANALOG_VALUE;
uint32_t decoded_instance = 0; uint32_t decoded_instance = 0;
uint32_t instance = 123; uint32_t instance = 123;
BACNET_ERROR_CLASS error_class; BACNET_ERROR_CLASS error_class;
BACNET_ERROR_CODE error_code; BACNET_ERROR_CODE error_code;
len = len =
Analog_Value_Encode_Property_APDU(&apdu[0], instance, Analog_Value_Encode_Property_APDU(&apdu[0], instance,
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code); PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0); ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value); len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID); ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
len = len =
decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance); decode_object_id(&apdu[len], (int *) &decoded_type, &decoded_instance);
ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE); ct_test(pTest, decoded_type == OBJECT_ANALOG_VALUE);
ct_test(pTest, decoded_instance == instance); ct_test(pTest, decoded_instance == instance);
return; return;
} }
#ifdef TEST_ANALOG_VALUE #ifdef TEST_ANALOG_VALUE
int main( int main(
void) void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
pTest = ct_create("BACnet Analog Value", NULL); pTest = ct_create("BACnet Analog Value", NULL);
/* individual tests */ /* individual tests */
rc = ct_addTestFunction(pTest, testAnalog_Value); rc = ct_addTestFunction(pTest, testAnalog_Value);
assert(rc); assert(rc);
ct_setStream(pTest, stdout); ct_setStream(pTest, stdout);
ct_run(pTest); ct_run(pTest);
(void) ct_report(pTest); (void) ct_report(pTest);
ct_destroy(pTest); ct_destroy(pTest);
return 0; return 0;
} }
#endif /* TEST_ANALOG_VALUE */ #endif /* TEST_ANALOG_VALUE */
#endif /* TEST */ #endif /* TEST */
+18 -18
View File
@@ -1,18 +1,18 @@
#ifndef AVR035_H #ifndef AVR035_H
#define AVR035_H #define AVR035_H
/* from AVR035: Efficient C Coding for AVR */ /* from AVR035: Efficient C Coding for AVR */
/* a=register, b=bit number to act upon */ /* a=register, b=bit number to act upon */
#define BIT_SET(a,b) ((a) |= (1<<(b))) #define BIT_SET(a,b) ((a) |= (1<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b))) #define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1<<(b))) #define BIT_FLIP(a,b) ((a) ^= (1<<(b)))
#define BIT_CHECK(a,b) ((a) & (1<<(b))) #define BIT_CHECK(a,b) ((a) & (1<<(b)))
/* x=target variable, y=mask */ /* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y)) #define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y))) #define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y)) #define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK(x,y) ((x) & (y)) #define BITMASK_CHECK(x,y) ((x) & (y))
#endif #endif
+330 -331
View File
@@ -1,331 +1,330 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacstr.h" #include "bacstr.h"
#include "bacenum.h" #include "bacenum.h"
#include "apdu.h" #include "apdu.h"
#include "dcc.h" #include "dcc.h"
#include "dlmstp.h" #include "dlmstp.h"
#include "rs485.h" #include "rs485.h"
#include "version.h" #include "version.h"
/* objects */ /* objects */
#include "device.h" #include "device.h"
#include "av.h" #include "av.h"
/* note: you really only need to define variables for /* note: you really only need to define variables for
properties that are writable or that may change. properties that are writable or that may change.
The properties that are constant can be hard coded The properties that are constant can be hard coded
into the read-property encoding. */ into the read-property encoding. */
static uint32_t Object_Instance_Number = 260001; static uint32_t Object_Instance_Number = 260001;
static char *Object_Name = "My Device"; static char *Object_Name = "My Device";
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL; static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
void Device_Init( void Device_Init(
void) void)
{ {
/* Reinitialize_State = REINITIALIZED_STATE_IDLE; */ /* Reinitialize_State = REINITIALIZED_STATE_IDLE; */
/* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */ /* dcc_set_status_duration(COMMUNICATION_ENABLE, 0); */
/* FIXME: Get the data from the eeprom */ /* FIXME: Get the data from the eeprom */
/* I2C_Read_Block(EEPROM_DEVICE_ADDRESS, /* I2C_Read_Block(EEPROM_DEVICE_ADDRESS,
(char *)&Object_Instance_Number, (char *)&Object_Instance_Number,
sizeof(Object_Instance_Number), sizeof(Object_Instance_Number),
EEPROM_BACNET_ID_ADDR); */ EEPROM_BACNET_ID_ADDR); */
} }
/* methods to manipulate the data */ /* methods to manipulate the data */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(
void) void)
{ {
return Object_Instance_Number; return Object_Instance_Number;
} }
bool Device_Set_Object_Instance_Number( bool Device_Set_Object_Instance_Number(
uint32_t object_id) uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
if (object_id <= BACNET_MAX_INSTANCE) { if (object_id <= BACNET_MAX_INSTANCE) {
Object_Instance_Number = object_id; Object_Instance_Number = object_id;
/* FIXME: Write the data to the eeprom */ /* FIXME: Write the data to the eeprom */
/* I2C_Write_Block( /* I2C_Write_Block(
EEPROM_DEVICE_ADDRESS, EEPROM_DEVICE_ADDRESS,
(char *)&Object_Instance_Number, (char *)&Object_Instance_Number,
sizeof(Object_Instance_Number), sizeof(Object_Instance_Number),
EEPROM_BACNET_ID_ADDR); */ EEPROM_BACNET_ID_ADDR); */
} else } else
status = false; status = false;
return status; return status;
} }
bool Device_Valid_Object_Instance_Number( bool Device_Valid_Object_Instance_Number(
uint32_t object_id) uint32_t object_id)
{ {
/* BACnet allows for a wildcard instance number */ /* BACnet allows for a wildcard instance number */
return ((Object_Instance_Number == object_id) || return ((Object_Instance_Number == object_id) ||
(object_id == BACNET_MAX_INSTANCE)); (object_id == BACNET_MAX_INSTANCE));
} }
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(
void) void)
{ {
return BACNET_VENDOR_ID; return BACNET_VENDOR_ID;
} }
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(
void) void)
{ {
unsigned count = 1; /* at least 1 for device object */ unsigned count = 1; /* at least 1 for device object */
#if MAX_ANALOG_VALUES #if MAX_ANALOG_VALUES
/* FIXME: add objects as needed */ /* FIXME: add objects as needed */
count += Analog_Value_Count(); count += Analog_Value_Count();
#endif #endif
#if MAX_BINARY_VALUES #if MAX_BINARY_VALUES
/* FIXME: add objects as needed */ /* FIXME: add objects as needed */
count += Binary_Value_Count(); count += Binary_Value_Count();
#endif #endif
return count; return count;
} }
bool Device_Object_List_Identifier( bool Device_Object_List_Identifier(
unsigned array_index, unsigned array_index,
int *object_type, int *object_type,
uint32_t * instance) uint32_t * instance)
{ {
bool status = false; bool status = false;
unsigned object_index = 0; unsigned object_index = 0;
unsigned object_count = 0; unsigned object_count = 0;
/* device object */ /* device object */
if (array_index == 1) { if (array_index == 1) {
*object_type = OBJECT_DEVICE; *object_type = OBJECT_DEVICE;
*instance = Object_Instance_Number; *instance = Object_Instance_Number;
status = true; status = true;
} }
/* normalize the index since /* normalize the index since
we know it is not the previous objects */ we know it is not the previous objects */
/* array index starts at 1 */ /* array index starts at 1 */
object_index = array_index - 1; object_index = array_index - 1;
/* 1 for the device object */ /* 1 for the device object */
object_count = 1; object_count = 1;
/* FIXME: add objects as needed */ /* FIXME: add objects as needed */
#if MAX_ANALOG_VALUES #if MAX_ANALOG_VALUES
/* analog value objects */ /* analog value objects */
if (!status) { if (!status) {
/* array index starts at 1, and 1 for the device object */ /* array index starts at 1, and 1 for the device object */
object_index -= object_count; object_index -= object_count;
object_count = Analog_Value_Count(); object_count = Analog_Value_Count();
if (object_index < object_count) { if (object_index < object_count) {
*object_type = OBJECT_ANALOG_VALUE; *object_type = OBJECT_ANALOG_VALUE;
*instance = Analog_Value_Index_To_Instance(object_index); *instance = Analog_Value_Index_To_Instance(object_index);
status = true; status = true;
} }
} }
#endif #endif
#if MAX_BINARY_VALUES #if MAX_BINARY_VALUES
/* binary value objects */ /* binary value objects */
if (!status) { if (!status) {
object_index -= object_count; object_index -= object_count;
object_count = Binary_Value_Count(); object_count = Binary_Value_Count();
/* is it a valid index for this object? */ /* is it a valid index for this object? */
if (object_index < object_count) { if (object_index < object_count) {
*object_type = OBJECT_BINARY_VALUE; *object_type = OBJECT_BINARY_VALUE;
*instance = Binary_Value_Index_To_Instance(object_index); *instance = Binary_Value_Index_To_Instance(object_index);
status = true; status = true;
} }
} }
#endif #endif
return status; return status;
} }
/* return the length of the apdu encoded or -1 for error */ /* return the length of the apdu encoded or -1 for error */
int Device_Encode_Property_APDU( int Device_Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
BACNET_PROPERTY_ID property, BACNET_PROPERTY_ID property,
int32_t array_index, int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */ int len = 0; /* apdu len intermediate value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
unsigned i = 0; unsigned i = 0;
int object_type = 0; int object_type = 0;
uint32_t instance = 0; uint32_t instance = 0;
unsigned count = 0; unsigned count = 0;
/* FIXME: change the hardcoded names to suit your application */ /* FIXME: change the hardcoded names to suit your application */
switch (property) { switch (property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], OBJECT_DEVICE, encode_application_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance_Number); Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, Object_Name); characterstring_init_ansi(&char_string, Object_Name);
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE); apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
break; break;
case PROP_SYSTEM_STATUS: case PROP_SYSTEM_STATUS:
apdu_len = encode_application_enumerated(&apdu[0], System_Status); apdu_len = encode_application_enumerated(&apdu[0], System_Status);
break; break;
case PROP_VENDOR_NAME: case PROP_VENDOR_NAME:
characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME); characterstring_init_ansi(&char_string, BACNET_VENDOR_NAME);
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_VENDOR_IDENTIFIER: case PROP_VENDOR_IDENTIFIER:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0],
Device_Vendor_Identifier()); Device_Vendor_Identifier());
break; break;
case PROP_MODEL_NAME: case PROP_MODEL_NAME:
characterstring_init_ansi(&char_string, "GNU Demo"); characterstring_init_ansi(&char_string, "GNU Demo");
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_FIRMWARE_REVISION: case PROP_FIRMWARE_REVISION:
characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT); characterstring_init_ansi(&char_string, BACNET_VERSION_TEXT);
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_APPLICATION_SOFTWARE_VERSION: case PROP_APPLICATION_SOFTWARE_VERSION:
characterstring_init_ansi(&char_string, "1.0"); characterstring_init_ansi(&char_string, "1.0");
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_PROTOCOL_VERSION: case PROP_PROTOCOL_VERSION:
apdu_len = encode_application_unsigned(&apdu[0], 1); apdu_len = encode_application_unsigned(&apdu[0], 1);
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = encode_application_unsigned(&apdu[0], 5); apdu_len = encode_application_unsigned(&apdu[0], 5);
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
/* Note: list of services that are executed, not initiated. */ /* Note: list of services that are executed, not initiated. */
bitstring_init(&bit_string); bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */ /* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t) i, bitstring_set_bit(&bit_string, (uint8_t) i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED) i)); apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
} }
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED: case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
/* Note: this is the list of objects that can be in this device, /* Note: this is the list of objects that can be in this device,
not a list of objects that this device can access */ not a list of objects that this device can access */
bitstring_init(&bit_string); bitstring_init(&bit_string);
/* must have the bit string as big as it can be */ /* must have the bit string as big as it can be */
for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) { for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
/* initialize all the object types to not-supported */ /* initialize all the object types to not-supported */
bitstring_set_bit(&bit_string, (uint8_t) i, false); bitstring_set_bit(&bit_string, (uint8_t) i, false);
} }
/* FIXME: indicate the objects that YOU support */ /* FIXME: indicate the objects that YOU support */
bitstring_set_bit(&bit_string, OBJECT_DEVICE, true); bitstring_set_bit(&bit_string, OBJECT_DEVICE, true);
#if MAX_ANALOG_VALUES #if MAX_ANALOG_VALUES
bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true); bitstring_set_bit(&bit_string, OBJECT_ANALOG_VALUE, true);
#endif #endif
#if MAX_BINARY_VALUES #if MAX_BINARY_VALUES
bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true); bitstring_set_bit(&bit_string, OBJECT_BINARY_VALUE, true);
#endif #endif
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
count = Device_Object_List_Count(); count = Device_Object_List_Count();
/* Array element zero is the number of objects in the list */ /* Array element zero is the number of objects in the list */
if (array_index == 0) if (array_index == 0)
apdu_len = encode_application_unsigned(&apdu[0], count); apdu_len = encode_application_unsigned(&apdu[0], count);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. Note that more than likely you will have */ /* into one packet. Note that more than likely you will have */
/* to return an error if the number of encoded objects exceeds */ /* to return an error if the number of encoded objects exceeds */
/* your maximum APDU size. */ /* your maximum APDU size. */
else if (array_index == BACNET_ARRAY_ALL) { else if (array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
Device_Object_List_Identifier(i, &object_type, &instance); Device_Object_List_Identifier(i, &object_type, &instance);
len = len =
encode_application_object_id(&apdu[apdu_len], encode_application_object_id(&apdu[apdu_len],
object_type, instance); object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? */ /* can we all fit into the APDU? */
if ((apdu_len + len) >= MAX_APDU) { if ((apdu_len + len) >= MAX_APDU) {
*error_class = ERROR_CLASS_SERVICES; *error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT; *error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1; apdu_len = -1;
break; break;
} }
} }
} else { } else {
if (Device_Object_List_Identifier(array_index, &object_type, if (Device_Object_List_Identifier(array_index, &object_type,
&instance)) &instance))
apdu_len = apdu_len =
encode_application_object_id(&apdu[0], object_type, encode_application_object_id(&apdu[0], object_type,
instance); instance);
else { else {
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX; *error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1; apdu_len = -1;
} }
} }
break; break;
case PROP_MAX_APDU_LENGTH_ACCEPTED: case PROP_MAX_APDU_LENGTH_ACCEPTED:
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break; break;
case PROP_SEGMENTATION_SUPPORTED: case PROP_SEGMENTATION_SUPPORTED:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], SEGMENTATION_NONE); encode_application_enumerated(&apdu[0], SEGMENTATION_NONE);
break; break;
case PROP_APDU_TIMEOUT: case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], 60000); apdu_len = encode_application_unsigned(&apdu[0], 60000);
break; break;
case PROP_NUMBER_OF_APDU_RETRIES: case PROP_NUMBER_OF_APDU_RETRIES:
apdu_len = encode_application_unsigned(&apdu[0], 0); apdu_len = encode_application_unsigned(&apdu[0], 0);
break; break;
case PROP_DEVICE_ADDRESS_BINDING: case PROP_DEVICE_ADDRESS_BINDING:
/* FIXME: encode the list here, if it exists */ /* FIXME: encode the list here, if it exists */
break; break;
case PROP_DATABASE_REVISION: case PROP_DATABASE_REVISION:
apdu_len = encode_application_unsigned(&apdu[0], 0); apdu_len = encode_application_unsigned(&apdu[0], 0);
break; break;
default: default:
*error_class = ERROR_CLASS_PROPERTY; *error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY; *error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1; apdu_len = -1;
break; break;
} }
return apdu_len; return apdu_len;
} }
File diff suppressed because it is too large Load Diff
+173 -173
View File
@@ -1,173 +1,173 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "rp.h" #include "rp.h"
/* demo objects */ /* demo objects */
#include "device.h" #include "device.h"
#if MAX_ANALOG_VALUES #if MAX_ANALOG_VALUES
#include "av.h" #include "av.h"
#endif #endif
#if MAX_BINARY_VALUES #if MAX_BINARY_VALUES
#include "bv.h" #include "bv.h"
#endif #endif
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */ or sets the error, and returns -1 */
int Encode_Property_APDU( int Encode_Property_APDU(
uint8_t * apdu, uint8_t * apdu,
BACNET_READ_PROPERTY_DATA * rp_data, BACNET_READ_PROPERTY_DATA * rp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code) BACNET_ERROR_CODE * error_code)
{ {
int apdu_len = -1; int apdu_len = -1;
/* handle each object type */ /* handle each object type */
switch (rp_data->object_type) { switch (rp_data->object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) { if (Device_Valid_Object_Instance_Number(rp_data->object_instance)) {
apdu_len = apdu_len =
Device_Encode_Property_APDU(&apdu[0], Device_Encode_Property_APDU(&apdu[0],
rp_data->object_property, rp_data->array_index, rp_data->object_property, rp_data->array_index,
error_class, error_code); error_class, error_code);
} }
break; break;
#if MAX_ANALOG_VALUES #if MAX_ANALOG_VALUES
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Valid_Instance(rp_data->object_instance)) { if (Analog_Value_Valid_Instance(rp_data->object_instance)) {
apdu_len = apdu_len =
Analog_Value_Encode_Property_APDU(&apdu[0], Analog_Value_Encode_Property_APDU(&apdu[0],
rp_data->object_instance, rp_data->object_property, rp_data->object_instance, rp_data->object_property,
rp_data->array_index, error_class, error_code); rp_data->array_index, error_class, error_code);
} }
break; break;
#endif #endif
#if MAX_BINARY_VALUES #if MAX_BINARY_VALUES
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Valid_Instance(rp_data->object_instance)) { if (Binary_Value_Valid_Instance(rp_data->object_instance)) {
apdu_len = apdu_len =
Binary_Value_Encode_Property_APDU(&apdu[0], Binary_Value_Encode_Property_APDU(&apdu[0],
rp_data->object_instance, rp_data->object_property, rp_data->object_instance, rp_data->object_property,
rp_data->array_index, error_class, error_code); rp_data->array_index, error_class, error_code);
} }
break; break;
#endif #endif
default: default:
*error_class = ERROR_CLASS_OBJECT; *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE; *error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
break; break;
} }
return apdu_len; return apdu_len;
} }
void handler_read_property( void handler_read_property(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
BACNET_READ_PROPERTY_DATA data; BACNET_READ_PROPERTY_DATA data;
int len = 0; int len = 0;
int ack_len = 0; int ack_len = 0;
int property_len = 0; int property_len = 0;
int pdu_len = 0; int pdu_len = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
goto RP_ABORT; goto RP_ABORT;
} }
len = rp_decode_service_request(service_request, service_len, &data); len = rp_decode_service_request(service_request, service_len, &data);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RP_ABORT; goto RP_ABORT;
} }
/* most cases will be error */ /* most cases will be error */
ack_len = ack_len =
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
/* FIXME: add buffer len as passed into function or use smart buffer */ /* FIXME: add buffer len as passed into function or use smart buffer */
property_len = property_len =
Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len], Encode_Property_APDU(&Handler_Transmit_Buffer[pdu_len + ack_len],
&data, &error_class, &error_code); &data, &error_class, &error_code);
if (property_len >= 0) { if (property_len >= 0) {
len = len =
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer
[pdu_len + property_len + ack_len]); [pdu_len + property_len + ack_len]);
len += ack_len + property_len; len += ack_len + property_len;
} else { } else {
switch (property_len) { switch (property_len) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is Abort */
case -2: case -2:
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
break; break;
default: default:
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY,
error_class, error_code); error_class, error_code);
break; break;
} }
} }
RP_ABORT: RP_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
return; return;
} }
+71 -71
View File
@@ -1,71 +1,71 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "whois.h" #include "whois.h"
#include "iam.h" #include "iam.h"
#include "device.h" #include "device.h"
#include "client.h" #include "client.h"
#include "txbuf.h" #include "txbuf.h"
bool Send_I_Am = true; bool Send_I_Am = true;
void handler_who_is( void handler_who_is(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src) BACNET_ADDRESS * src)
{ {
int len = 0; int len = 0;
int32_t low_limit = 0; int32_t low_limit = 0;
int32_t high_limit = 0; int32_t high_limit = 0;
int32_t target_device; int32_t target_device;
(void) src; (void) src;
len = len =
whois_decode_service_request(service_request, service_len, &low_limit, whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit); &high_limit);
if (len == 0) { if (len == 0) {
Send_I_Am = true; Send_I_Am = true;
} else if (len != -1) { } else if (len != -1) {
/* is my device id within the limits? */ /* is my device id within the limits? */
target_device = Device_Object_Instance_Number(); target_device = Device_Object_Instance_Number();
if (((target_device >= low_limit) && (target_device <= high_limit)) if (((target_device >= low_limit) && (target_device <= high_limit))
|| ||
/* BACnet wildcard is the max instance number - everyone responds */ /* BACnet wildcard is the max instance number - everyone responds */
((BACNET_MAX_INSTANCE >= (uint32_t) low_limit) && ((BACNET_MAX_INSTANCE >= (uint32_t) low_limit) &&
(BACNET_MAX_INSTANCE <= (uint32_t) high_limit))) { (BACNET_MAX_INSTANCE <= (uint32_t) high_limit))) {
Send_I_Am = true; Send_I_Am = true;
} }
} }
return; return;
} }
+139 -139
View File
@@ -1,139 +1,139 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include "config.h" #include "config.h"
#include "txbuf.h" #include "txbuf.h"
#include "bacdef.h" #include "bacdef.h"
#include "bacdcode.h" #include "bacdcode.h"
#include "bacerror.h" #include "bacerror.h"
#include "apdu.h" #include "apdu.h"
#include "npdu.h" #include "npdu.h"
#include "abort.h" #include "abort.h"
#include "wp.h" #include "wp.h"
/* demo objects */ /* demo objects */
#include "device.h" #include "device.h"
#include "av.h" #include "av.h"
#include "bv.h" #include "bv.h"
/* too big to reside on stack frame for PIC */ /* too big to reside on stack frame for PIC */
static BACNET_WRITE_PROPERTY_DATA wp_data; static BACNET_WRITE_PROPERTY_DATA wp_data;
void handler_write_property( void handler_write_property(
uint8_t * service_request, uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS * src, BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data) BACNET_CONFIRMED_SERVICE_DATA * service_data)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT; BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT; BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
/* decode the service request only */ /* decode the service request only */
len = wp_decode_service_request(service_request, service_len, &wp_data); len = wp_decode_service_request(service_request, service_len, &wp_data);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address, npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true); service_data->invoke_id, ABORT_REASON_OTHER, true);
} else if (service_data->segmented_message) { } else if (service_data->segmented_message) {
len = len =
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true); true);
} else { } else {
switch (wp_data.object_type) { switch (wp_data.object_type) {
case OBJECT_DEVICE: case OBJECT_DEVICE:
if (Device_Write_Property(&wp_data, &error_class, &error_code)) { if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
len = len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code); error_code);
} }
break; break;
case OBJECT_ANALOG_VALUE: case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property(&wp_data, &error_class, if (Analog_Value_Write_Property(&wp_data, &error_class,
&error_code)) { &error_code)) {
len = len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code); error_code);
} }
break; break;
case OBJECT_BINARY_VALUE: case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property(&wp_data, &error_class, if (Binary_Value_Write_Property(&wp_data, &error_class,
&error_code)) { &error_code)) {
len = len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
} else { } else {
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code); error_code);
} }
break; break;
default: default:
len = len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code); error_class, error_code);
break; break;
} }
} }
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent =
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0], datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
return; return;
} }
+54 -54
View File
@@ -1,54 +1,54 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef HARDWARE_H #ifndef HARDWARE_H
#define HARDWARE_H #define HARDWARE_H
#if !defined(F_CPU) #if !defined(F_CPU)
/* The processor clock frequency */ /* The processor clock frequency */
#define F_CPU 7372800UL #define F_CPU 7372800UL
#endif #endif
#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) #if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__)
#include <iom168.h> #include <iom168.h>
#else #else
#if !defined(__AVR_ATmega168__) #if !defined(__AVR_ATmega168__)
#error Firmware is configured for ATmega168 only (-mmcu=atmega168) #error Firmware is configured for ATmega168 only (-mmcu=atmega168)
#endif #endif
#endif #endif
#include "iar2gcc.h" #include "iar2gcc.h"
#include "avr035.h" #include "avr035.h"
#define LED_NPDU_INIT() BIT_SET(DDRD, DDD5) #define LED_NPDU_INIT() BIT_SET(DDRD, DDD5)
#define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5) #define LED_NPDU_ON() BIT_CLEAR(PORTD, PD5)
#define LED_NPDU_OFF() BIT_SET(PORTD, PD5) #define LED_NPDU_OFF() BIT_SET(PORTD, PD5)
/* #define LED_NPDU PORTD_Bit5 */ /* #define LED_NPDU PORTD_Bit5 */
/* #define LED_NPDU_OFF() {LED_NPDU = false;} */ /* #define LED_NPDU_OFF() {LED_NPDU = false;} */
/* #define LED_NPDU_ON() {LED_NPDU = true;} */ /* #define LED_NPDU_ON() {LED_NPDU = true;} */
#define LED_GREEN_INIT() BIT_SET(DDRD, DDD4) #define LED_GREEN_INIT() BIT_SET(DDRD, DDD4)
#define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4) #define LED_GREEN_ON() BIT_CLEAR(PORTD, PD4)
#define LED_GREEN_OFF() BIT_SET(PORTD, PD4) #define LED_GREEN_OFF() BIT_SET(PORTD, PD4)
#endif #endif
+226 -226
View File
@@ -1,226 +1,226 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2007 Steve Karg Copyright (C) 2007 Steve Karg
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef IAR2GCC_H #ifndef IAR2GCC_H
#define IAR2GCC_H #define IAR2GCC_H
#if !defined(F_CPU) #if !defined(F_CPU)
#define F_CPU (7372800) #define F_CPU (7372800)
#endif #endif
/* IAR */ /* IAR */
#if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__) #if defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ASM__)
#include <inavr.h> #include <inavr.h>
#include <ioavr.h> #include <ioavr.h>
/* BitValue is used alot in GCC examples */ /* BitValue is used alot in GCC examples */
#define _BV(bit_num) (1 << (bit_num)) #define _BV(bit_num) (1 << (bit_num))
/* inline function */ /* inline function */
static inline void _delay_us( static inline void _delay_us(
uint8_t microseconds) uint8_t microseconds)
{ {
do { do {
__delay_cycles(F_CPU / 1000000UL); __delay_cycles(F_CPU / 1000000UL);
} while (microseconds--); } while (microseconds--);
} }
#endif #endif
/* Input/Output Registers */ /* Input/Output Registers */
#if defined(__GNUC__) #if defined(__GNUC__)
#include <avr/io.h> #include <avr/io.h>
typedef struct { typedef struct {
unsigned char bit0:1; unsigned char bit0:1;
unsigned char bit1:1; unsigned char bit1:1;
unsigned char bit2:1; unsigned char bit2:1;
unsigned char bit3:1; unsigned char bit3:1;
unsigned char bit4:1; unsigned char bit4:1;
unsigned char bit5:1; unsigned char bit5:1;
unsigned char bit6:1; unsigned char bit6:1;
unsigned char bit7:1; unsigned char bit7:1;
} BitRegisterType; } BitRegisterType;
#ifndef true #ifndef true
#define true 1 #define true 1
#endif #endif
#ifndef false #ifndef false
#define false 0 #define false 0
#endif #endif
#define GPIO_BITREG(port,bitnum) \ #define GPIO_BITREG(port,bitnum) \
((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \ ((volatile BitRegisterType*)_SFR_MEM_ADDR(port) \
)->bit ## bitnum )->bit ## bitnum
#define PINA_Bit0 GPIO_BITREG(PINA,0) #define PINA_Bit0 GPIO_BITREG(PINA,0)
#define PINA_Bit1 GPIO_BITREG(PINA,1) #define PINA_Bit1 GPIO_BITREG(PINA,1)
#define PINA_Bit2 GPIO_BITREG(PINA,2) #define PINA_Bit2 GPIO_BITREG(PINA,2)
#define PINA_Bit3 GPIO_BITREG(PINA,3) #define PINA_Bit3 GPIO_BITREG(PINA,3)
#define PINA_Bit4 GPIO_BITREG(PINA,4) #define PINA_Bit4 GPIO_BITREG(PINA,4)
#define PINA_Bit5 GPIO_BITREG(PINA,5) #define PINA_Bit5 GPIO_BITREG(PINA,5)
#define PINA_Bit6 GPIO_BITREG(PINA,6) #define PINA_Bit6 GPIO_BITREG(PINA,6)
#define PINA_Bit7 GPIO_BITREG(PINA,7) #define PINA_Bit7 GPIO_BITREG(PINA,7)
#define PORTA_Bit0 GPIO_BITREG(PORTA,0) #define PORTA_Bit0 GPIO_BITREG(PORTA,0)
#define PORTA_Bit1 GPIO_BITREG(PORTA,1) #define PORTA_Bit1 GPIO_BITREG(PORTA,1)
#define PORTA_Bit2 GPIO_BITREG(PORTA,2) #define PORTA_Bit2 GPIO_BITREG(PORTA,2)
#define PORTA_Bit3 GPIO_BITREG(PORTA,3) #define PORTA_Bit3 GPIO_BITREG(PORTA,3)
#define PORTA_Bit4 GPIO_BITREG(PORTA,4) #define PORTA_Bit4 GPIO_BITREG(PORTA,4)
#define PORTA_Bit5 GPIO_BITREG(PORTA,5) #define PORTA_Bit5 GPIO_BITREG(PORTA,5)
#define PORTA_Bit6 GPIO_BITREG(PORTA,6) #define PORTA_Bit6 GPIO_BITREG(PORTA,6)
#define PORTA_Bit7 GPIO_BITREG(PORTA,7) #define PORTA_Bit7 GPIO_BITREG(PORTA,7)
#define PINB_Bit0 GPIO_BITREG(PINB,0) #define PINB_Bit0 GPIO_BITREG(PINB,0)
#define PINB_Bit1 GPIO_BITREG(PINB,1) #define PINB_Bit1 GPIO_BITREG(PINB,1)
#define PINB_Bit2 GPIO_BITREG(PINB,2) #define PINB_Bit2 GPIO_BITREG(PINB,2)
#define PINB_Bit3 GPIO_BITREG(PINB,3) #define PINB_Bit3 GPIO_BITREG(PINB,3)
#define PINB_Bit4 GPIO_BITREG(PINB,4) #define PINB_Bit4 GPIO_BITREG(PINB,4)
#define PINB_Bit5 GPIO_BITREG(PINB,5) #define PINB_Bit5 GPIO_BITREG(PINB,5)
#define PINB_Bit6 GPIO_BITREG(PINB,6) #define PINB_Bit6 GPIO_BITREG(PINB,6)
#define PINB_Bit7 GPIO_BITREG(PINB,7) #define PINB_Bit7 GPIO_BITREG(PINB,7)
#define PORTB_Bit0 GPIO_BITREG(PORTB,0) #define PORTB_Bit0 GPIO_BITREG(PORTB,0)
#define PORTB_Bit1 GPIO_BITREG(PORTB,1) #define PORTB_Bit1 GPIO_BITREG(PORTB,1)
#define PORTB_Bit2 GPIO_BITREG(PORTB,2) #define PORTB_Bit2 GPIO_BITREG(PORTB,2)
#define PORTB_Bit3 GPIO_BITREG(PORTB,3) #define PORTB_Bit3 GPIO_BITREG(PORTB,3)
#define PORTB_Bit4 GPIO_BITREG(PORTB,4) #define PORTB_Bit4 GPIO_BITREG(PORTB,4)
#define PORTB_Bit5 GPIO_BITREG(PORTB,5) #define PORTB_Bit5 GPIO_BITREG(PORTB,5)
#define PORTB_Bit6 GPIO_BITREG(PORTB,6) #define PORTB_Bit6 GPIO_BITREG(PORTB,6)
#define PORTB_Bit7 GPIO_BITREG(PORTB,7) #define PORTB_Bit7 GPIO_BITREG(PORTB,7)
#define PINC_Bit0 GPIO_BITREG(PINC,0) #define PINC_Bit0 GPIO_BITREG(PINC,0)
#define PINC_Bit1 GPIO_BITREG(PINC,1) #define PINC_Bit1 GPIO_BITREG(PINC,1)
#define PINC_Bit2 GPIO_BITREG(PINC,2) #define PINC_Bit2 GPIO_BITREG(PINC,2)
#define PINC_Bit3 GPIO_BITREG(PINC,3) #define PINC_Bit3 GPIO_BITREG(PINC,3)
#define PINC_Bit4 GPIO_BITREG(PINC,4) #define PINC_Bit4 GPIO_BITREG(PINC,4)
#define PINC_Bit5 GPIO_BITREG(PINC,5) #define PINC_Bit5 GPIO_BITREG(PINC,5)
#define PINC_Bit6 GPIO_BITREG(PINC,6) #define PINC_Bit6 GPIO_BITREG(PINC,6)
#define PINC_Bit7 GPIO_BITREG(PINC,7) #define PINC_Bit7 GPIO_BITREG(PINC,7)
#define PORTC_Bit0 GPIO_BITREG(PORTC,0) #define PORTC_Bit0 GPIO_BITREG(PORTC,0)
#define PORTC_Bit1 GPIO_BITREG(PORTC,1) #define PORTC_Bit1 GPIO_BITREG(PORTC,1)
#define PORTC_Bit2 GPIO_BITREG(PORTC,2) #define PORTC_Bit2 GPIO_BITREG(PORTC,2)
#define PORTC_Bit3 GPIO_BITREG(PORTC,3) #define PORTC_Bit3 GPIO_BITREG(PORTC,3)
#define PORTC_Bit4 GPIO_BITREG(PORTC,4) #define PORTC_Bit4 GPIO_BITREG(PORTC,4)
#define PORTC_Bit5 GPIO_BITREG(PORTC,5) #define PORTC_Bit5 GPIO_BITREG(PORTC,5)
#define PORTC_Bit6 GPIO_BITREG(PORTC,6) #define PORTC_Bit6 GPIO_BITREG(PORTC,6)
#define PORTC_Bit7 GPIO_BITREG(PORTC,7) #define PORTC_Bit7 GPIO_BITREG(PORTC,7)
#define PIND_Bit0 GPIO_BITREG(PIND,0) #define PIND_Bit0 GPIO_BITREG(PIND,0)
#define PIND_Bit1 GPIO_BITREG(PIND,1) #define PIND_Bit1 GPIO_BITREG(PIND,1)
#define PIND_Bit2 GPIO_BITREG(PIND,2) #define PIND_Bit2 GPIO_BITREG(PIND,2)
#define PIND_Bit3 GPIO_BITREG(PIND,3) #define PIND_Bit3 GPIO_BITREG(PIND,3)
#define PIND_Bit4 GPIO_BITREG(PIND,4) #define PIND_Bit4 GPIO_BITREG(PIND,4)
#define PIND_Bit5 GPIO_BITREG(PIND,5) #define PIND_Bit5 GPIO_BITREG(PIND,5)
#define PIND_Bit6 GPIO_BITREG(PIND,6) #define PIND_Bit6 GPIO_BITREG(PIND,6)
#define PIND_Bit7 GPIO_BITREG(PIND,7) #define PIND_Bit7 GPIO_BITREG(PIND,7)
#define PORTD_Bit0 GPIO_BITREG(PORTD,0) #define PORTD_Bit0 GPIO_BITREG(PORTD,0)
#define PORTD_Bit1 GPIO_BITREG(PORTD,1) #define PORTD_Bit1 GPIO_BITREG(PORTD,1)
#define PORTD_Bit2 GPIO_BITREG(PORTD,2) #define PORTD_Bit2 GPIO_BITREG(PORTD,2)
#define PORTD_Bit3 GPIO_BITREG(PORTD,3) #define PORTD_Bit3 GPIO_BITREG(PORTD,3)
#define PORTD_Bit4 GPIO_BITREG(PORTD,4) #define PORTD_Bit4 GPIO_BITREG(PORTD,4)
#define PORTD_Bit5 GPIO_BITREG(PORTD,5) #define PORTD_Bit5 GPIO_BITREG(PORTD,5)
#define PORTD_Bit6 GPIO_BITREG(PORTD,6) #define PORTD_Bit6 GPIO_BITREG(PORTD,6)
#define PORTD_Bit7 GPIO_BITREG(PORTD,7) #define PORTD_Bit7 GPIO_BITREG(PORTD,7)
#define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0) #define GPIOR0_Bit0 GPIO_BITREG(GPIOR0,0)
#define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1) #define GPIOR0_Bit1 GPIO_BITREG(GPIOR0,1)
#define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2) #define GPIOR0_Bit2 GPIO_BITREG(GPIOR0,2)
#define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3) #define GPIOR0_Bit3 GPIO_BITREG(GPIOR0,3)
#define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4) #define GPIOR0_Bit4 GPIO_BITREG(GPIOR0,4)
#define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5) #define GPIOR0_Bit5 GPIO_BITREG(GPIOR0,5)
#define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6) #define GPIOR0_Bit6 GPIO_BITREG(GPIOR0,6)
#define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7) #define GPIOR0_Bit7 GPIO_BITREG(GPIOR0,7)
#define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0) #define GPIOR1_Bit0 GPIO_BITREG(GPIOR1,0)
#define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1) #define GPIOR1_Bit1 GPIO_BITREG(GPIOR1,1)
#define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2) #define GPIOR1_Bit2 GPIO_BITREG(GPIOR1,2)
#define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3) #define GPIOR1_Bit3 GPIO_BITREG(GPIOR1,3)
#define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4) #define GPIOR1_Bit4 GPIO_BITREG(GPIOR1,4)
#define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5) #define GPIOR1_Bit5 GPIO_BITREG(GPIOR1,5)
#define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6) #define GPIOR1_Bit6 GPIO_BITREG(GPIOR1,6)
#define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7) #define GPIOR1_Bit7 GPIO_BITREG(GPIOR1,7)
#define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0) #define GPIOR2_Bit0 GPIO_BITREG(GPIOR2,0)
#define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1) #define GPIOR2_Bit1 GPIO_BITREG(GPIOR2,1)
#define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2) #define GPIOR2_Bit2 GPIO_BITREG(GPIOR2,2)
#define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3) #define GPIOR2_Bit3 GPIO_BITREG(GPIOR2,3)
#define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4) #define GPIOR2_Bit4 GPIO_BITREG(GPIOR2,4)
#define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5) #define GPIOR2_Bit5 GPIO_BITREG(GPIOR2,5)
#define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6) #define GPIOR2_Bit6 GPIO_BITREG(GPIOR2,6)
#define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7) #define GPIOR2_Bit7 GPIO_BITREG(GPIOR2,7)
#endif #endif
/* Global Interrupts */ /* Global Interrupts */
#if defined(__GNUC__) #if defined(__GNUC__)
#define __enable_interrupt() sei() #define __enable_interrupt() sei()
#define __disable_interrupt() cli() #define __disable_interrupt() cli()
#endif #endif
/* Interrupts */ /* Interrupts */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#define PRAGMA(x) _Pragma( #x ) #define PRAGMA(x) _Pragma( #x )
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void) #define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#include <avr/interrupt.h> #include <avr/interrupt.h>
#endif #endif
/* Flash */ /* Flash */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#define FLASH_DECLARE(x) __flash x #define FLASH_DECLARE(x) __flash x
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#define FLASH_DECLARE(x) x __attribute__((__progmem__)) #define FLASH_DECLARE(x) x __attribute__((__progmem__))
#endif #endif
/* EEPROM */ /* EEPROM */
#if defined(__ICCAVR__) #if defined(__ICCAVR__)
#define EEPROM_DECLARE(x) __eeprom x #define EEPROM_DECLARE(x) __eeprom x
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#include <avr/eeprom.h> #include <avr/eeprom.h>
#define EEPROM_DECLARE(x) x __attribute__((section (".eeprom"))) #define EEPROM_DECLARE(x) x __attribute__((section (".eeprom")))
#endif #endif
/* IAR intrinsic routines */ /* IAR intrinsic routines */
#if defined(__GNUC__) #if defined(__GNUC__)
/* FIXME: intrinsic routines: map to assembler for size/speed */ /* FIXME: intrinsic routines: map to assembler for size/speed */
#define __multiply_unsigned(x,y) ((x)*(y)) #define __multiply_unsigned(x,y) ((x)*(y))
/* FIXME: __root means to not optimize or strip */ /* FIXME: __root means to not optimize or strip */
#define __root #define __root
#endif #endif
#endif #endif
+122 -122
View File
@@ -1,122 +1,122 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
#include "rs485.h" #include "rs485.h"
#include "datalink.h" #include "datalink.h"
#include "npdu.h" #include "npdu.h"
#include "txbuf.h" #include "txbuf.h"
#include "iam.h" #include "iam.h"
#include "device.h" #include "device.h"
#include "av.h" #include "av.h"
#include "handlers.h" #include "handlers.h"
/* local version override */ /* local version override */
const char *BACnet_Version = "1.0"; const char *BACnet_Version = "1.0";
/* For porting to IAR, see: /* For porting to IAR, see:
http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/ http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC/IarToAvrgcc*/
/* dummy function - so we can use default demo handlers */ /* dummy function - so we can use default demo handlers */
bool dcc_communication_enabled( bool dcc_communication_enabled(
void) void)
{ {
return true; return true;
} }
static void init( static void init(
void) void)
{ {
/* FIXME: Initialize the Clock Prescaler for ATmega8 */ /* FIXME: Initialize the Clock Prescaler for ATmega8 */
#if defined(__AVR_ATmega168__) #if defined(__AVR_ATmega168__)
/* The default CLKPSx bits are factory set to 0011 */ /* The default CLKPSx bits are factory set to 0011 */
/* Enbable the Clock Prescaler */ /* Enbable the Clock Prescaler */
CLKPR = _BV(CLKPCE); CLKPR = _BV(CLKPCE);
/* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor /* CLKPS3 CLKPS2 CLKPS1 CLKPS0 Clock Division Factor
------ ------ ------ ------ --------------------- ------ ------ ------ ------ ---------------------
0 0 0 0 1 0 0 0 0 1
0 0 0 1 2 0 0 0 1 2
0 0 1 0 4 0 0 1 0 4
0 0 1 1 8 0 0 1 1 8
0 1 0 0 16 0 1 0 0 16
0 1 0 1 32 0 1 0 1 32
0 1 1 0 64 0 1 1 0 64
0 1 1 1 128 0 1 1 1 128
1 0 0 0 256 1 0 0 0 256
1 x x x Reserved 1 x x x Reserved
*/ */
/* Set the CLKPS3..0 bits to Prescaler of 1 */ /* Set the CLKPS3..0 bits to Prescaler of 1 */
CLKPR = 0; CLKPR = 0;
#endif #endif
/* Initialize I/O ports */ /* Initialize I/O ports */
/* For Port DDRx (Data Direction) Input=0, Output=1 */ /* For Port DDRx (Data Direction) Input=0, Output=1 */
/* For Port PORTx (Bit Value) TriState=0, High=1 */ /* For Port PORTx (Bit Value) TriState=0, High=1 */
DDRB = 0; DDRB = 0;
PORTB = 0; PORTB = 0;
DDRC = 0; DDRC = 0;
PORTC = 0; PORTC = 0;
DDRD = 0; DDRD = 0;
PORTD = 0; PORTD = 0;
/* Configure the watchdog timer - Disabled for testing */ /* Configure the watchdog timer - Disabled for testing */
#if defined(__AVR_ATmega168__) #if defined(__AVR_ATmega168__)
BIT_CLEAR(MCUSR, WDRF); BIT_CLEAR(MCUSR, WDRF);
WDTCSR = 0; WDTCSR = 0;
#else #else
BIT_CLEAR(MCUCSR, WDRF); BIT_CLEAR(MCUCSR, WDRF);
WDTCR = 0; WDTCR = 0;
#endif #endif
/* Configure Specialized Hardware */ /* Configure Specialized Hardware */
RS485_Initialize(); RS485_Initialize();
RS485_Set_Baud_Rate(38400); RS485_Set_Baud_Rate(38400);
/* Configure Timer0 for millisecond timer */ /* Configure Timer0 for millisecond timer */
timer_init(); timer_init();
/* Enable global interrupts */ /* Enable global interrupts */
__enable_interrupt(); __enable_interrupt();
} }
static uint8_t PDUBuffer[MAX_MPDU]; static uint8_t PDUBuffer[MAX_MPDU];
int main( int main(
void) void)
{ {
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
BACNET_ADDRESS src; /* source address */ BACNET_ADDRESS src; /* source address */
init(); init();
datalink_init(NULL); datalink_init(NULL);
for (;;) { for (;;) {
/* other tasks */ /* other tasks */
/* BACnet handling */ /* BACnet handling */
pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0); pdu_len = datalink_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0);
if (pdu_len) { if (pdu_len) {
npdu_handler(&src, &PDUBuffer[0], pdu_len); npdu_handler(&src, &PDUBuffer[0], pdu_len);
} }
} }
} }
+292 -292
View File
@@ -1,292 +1,292 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
/* The module handles sending data out the RS-485 port */ /* The module handles sending data out the RS-485 port */
/* and handles receiving data from the RS-485 port. */ /* and handles receiving data from the RS-485 port. */
/* Customize this file for your specific hardware */ /* Customize this file for your specific hardware */
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
/*#include "mstp.h" */ /*#include "mstp.h" */
/* This file has been customized for use with ATMEGA168 */ /* This file has been customized for use with ATMEGA168 */
#if defined(__AVR_ATmega168__) #if defined(__AVR_ATmega168__)
/* USART defines for RS-485 port */ /* USART defines for RS-485 port */
#define UCSRB UCSR0B #define UCSRB UCSR0B
#define TXEN TXEN0 #define TXEN TXEN0
#define RXEN RXEN0 #define RXEN RXEN0
#define UCSRC UCSR0C #define UCSRC UCSR0C
#define UCSZ1 UCSZ01 #define UCSZ1 UCSZ01
#define UCSZ0 UCSZ00 #define UCSZ0 UCSZ00
#define UCSRA UCSR0A #define UCSRA UCSR0A
#define U2X U2X0 #define U2X U2X0
#define UBRRL UBRR0 #define UBRRL UBRR0
#define UCSRA UCSR0A #define UCSRA UCSR0A
#define UDRE UDRE0 #define UDRE UDRE0
#define UDR UDR0 #define UDR UDR0
#define TXC TXC0 #define TXC TXC0
#define FE FE0 #define FE FE0
#define DOR DOR0 #define DOR DOR0
#define UPE UPE0 #define UPE UPE0
#define DOR DOR0 #define DOR DOR0
#define RXC RXC0 #define RXC RXC0
#endif #endif
#include "hardware.h" #include "hardware.h"
#include "timer.h" #include "timer.h"
/* baud rate */ /* baud rate */
static uint32_t RS485_Baud; static uint32_t RS485_Baud;
/* The minimum time after the end of the stop bit of the final octet of a */ /* 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. */ /* 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 9600 baud, 40 bit times would be about 4.166 milliseconds */
/* At 19200 baud, 40 bit times would be about 2.083 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 38400 baud, 40 bit times would be about 1.041 milliseconds */
/* At 57600 baud, 40 bit times would be about 0.694 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 76800 baud, 40 bit times would be about 0.520 milliseconds */
/* At 115200 baud, 40 bit times would be about 0.347 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 */ /* 40 bits is 4 octets including a start and stop bit with each octet */
#define Tturnaround (40UL) #define Tturnaround (40UL)
/* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */ /* turnaround_time_milliseconds = (Tturnaround*1000UL)/RS485_Baud; */
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in * DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode. * receive mode.
* RETURN: none * RETURN: none
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Initialize( void RS485_Initialize(
void) void)
{ {
/* enable Transmit and Receive */ /* enable Transmit and Receive */
UCSRB = _BV(TXEN) | _BV(RXEN); UCSRB = _BV(TXEN) | _BV(RXEN);
/* Set USART Control and Status Register n C */ /* Set USART Control and Status Register n C */
/* Asynchronous USART 8-bit data, No parity, 1 stop */ /* Asynchronous USART 8-bit data, No parity, 1 stop */
/* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */ /* Set USART Mode Select: UMSELn1 UMSELn0 = 00 for Asynchronous USART */
/* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */ /* Set Parity Mode: UPMn1 UPMn0 = 00 for Parity Disabled */
/* Set Stop Bit Select: USBSn = 0 for 1 stop bit */ /* Set Stop Bit Select: USBSn = 0 for 1 stop bit */
/* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */ /* Set Character Size: UCSZn2 UCSZn1 UCSZn0 = 011 for 8-bit */
/* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */ /* Clock Polarity: UCPOLn = 0 when asynchronous mode is used. */
UCSRC = _BV(UCSZ1) | _BV(UCSZ0); UCSRC = _BV(UCSZ1) | _BV(UCSZ0);
#if defined(__AVR_ATmega168__) #if defined(__AVR_ATmega168__)
/* Clear Power Reduction USART0 */ /* Clear Power Reduction USART0 */
BIT_CLEAR(PRR, PRUSART0); BIT_CLEAR(PRR, PRUSART0);
#endif #endif
/* Use port PD2 for RTS - enable and disable of Transceiver Tx/Rx */ /* Use port PD2 for RTS - enable and disable of Transceiver Tx/Rx */
/* Set port bit as Output - initially receiving */ /* Set port bit as Output - initially receiving */
BIT_CLEAR(PORTD, PD2); BIT_CLEAR(PORTD, PD2);
BIT_SET(DDRD, DDD2); BIT_SET(DDRD, DDD2);
return; return;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Returns the baud rate that we are currently running at * DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none * RETURN: none
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(
void) void)
{ {
return RS485_Baud; return RS485_Baud;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Sets the baud rate for the chip USART * DESCRIPTION: Sets the baud rate for the chip USART
* RETURN: true if valid baud rate * RETURN: true if valid baud rate
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(
uint32_t baud) uint32_t baud)
{ {
bool valid = true; bool valid = true;
switch (baud) { switch (baud) {
case 9600: case 9600:
case 19200: case 19200:
case 38400: case 38400:
case 57600: case 57600:
case 76800: case 76800:
case 115200: case 115200:
RS485_Baud = baud; RS485_Baud = baud;
/* 2x speed mode */ /* 2x speed mode */
BIT_SET(UCSRA, U2X); BIT_SET(UCSRA, U2X);
/* configure baud rate */ /* configure baud rate */
UBRRL = (F_CPU / (8UL * RS485_Baud)) - 1; UBRRL = (F_CPU / (8UL * RS485_Baud)) - 1;
/* FIXME: store the baud rate */ /* FIXME: store the baud rate */
break; break;
default: default:
valid = false; valid = false;
break; break;
} }
return valid; return valid;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Waits on the SilenceTimer for 40 bits. * DESCRIPTION: Waits on the SilenceTimer for 40 bits.
* RETURN: none * RETURN: none
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Turnaround_Delay( void RS485_Turnaround_Delay(
void) void)
{ {
uint16_t turnaround_time; uint16_t turnaround_time;
/* delay after reception before trasmitting - per MS/TP spec */ /* delay after reception before trasmitting - per MS/TP spec */
/* wait a minimum 40 bit times since reception */ /* wait a minimum 40 bit times since reception */
/* at least 1 ms for errors: rounding, clock tick */ /* at least 1 ms for errors: rounding, clock tick */
turnaround_time = 1 + ((Tturnaround * 1000UL) / RS485_Baud); turnaround_time = 1 + ((Tturnaround * 1000UL) / RS485_Baud);
while (!timer_silence_elapsed(turnaround_time)) { while (!timer_silence_elapsed(turnaround_time)) {
/* do nothing - wait for timer to increment */ /* do nothing - wait for timer to increment */
}; };
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Enable or disable the transmitter * DESCRIPTION: Enable or disable the transmitter
* RETURN: none * RETURN: none
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Transmitter_Enable( void RS485_Transmitter_Enable(
bool enable) bool enable)
{ {
if (enable) { if (enable) {
BIT_SET(PORTD, PD2); BIT_SET(PORTD, PD2);
} else { } else {
BIT_CLEAR(PORTD, PD2); BIT_CLEAR(PORTD, PD2);
} }
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Send some data and wait until it is sent * DESCRIPTION: Send some data and wait until it is sent
* RETURN: none * RETURN: none
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
void RS485_Send_Data( void RS485_Send_Data(
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
uint16_t nbytes) uint16_t nbytes)
{ /* number of bytes of data */ { /* number of bytes of data */
while (nbytes) { while (nbytes) {
while (!BIT_CHECK(UCSRA, UDRE)) { while (!BIT_CHECK(UCSRA, UDRE)) {
/* do nothing - wait until Tx buffer is empty */ /* do nothing - wait until Tx buffer is empty */
} }
/* Send the data byte */ /* Send the data byte */
UDR = *buffer; UDR = *buffer;
buffer++; buffer++;
nbytes--; nbytes--;
} }
/* was the frame sent? */ /* was the frame sent? */
while (!BIT_CHECK(UCSRA, TXC)) { while (!BIT_CHECK(UCSRA, TXC)) {
/* do nothing - wait until the entire frame in the /* do nothing - wait until the entire frame in the
Transmit Shift Register has been shifted out */ Transmit Shift Register has been shifted out */
} }
/* Clear the Transmit Complete flag by writing a one to it. */ /* Clear the Transmit Complete flag by writing a one to it. */
BIT_SET(UCSRA, TXC); BIT_SET(UCSRA, TXC);
/* per MSTP spec, sort of */ /* per MSTP spec, sort of */
timer_silence_reset(); timer_silence_reset();
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Return true if a framing or overrun error is present * DESCRIPTION: Return true if a framing or overrun error is present
* RETURN: true if error * RETURN: true if error
* ALGORITHM: autobaud - if there are a lot of errors, switch baud rate * ALGORITHM: autobaud - if there are a lot of errors, switch baud rate
* NOTES: Clears any error flags. * NOTES: Clears any error flags.
*****************************************************************************/ *****************************************************************************/
bool RS485_ReceiveError( bool RS485_ReceiveError(
void) void)
{ {
bool ReceiveError = false; bool ReceiveError = false;
uint8_t dummy_data; uint8_t dummy_data;
/* check for framing error */ /* check for framing error */
#if 0 #if 0
if (BIT_CHECK(UCSRA, FE0)) { if (BIT_CHECK(UCSRA, FE0)) {
/* FIXME: how do I clear the error flags? */ /* FIXME: how do I clear the error flags? */
BITMASK_CLEAR(UCSRA, (_BV(FE) | _BV(DOR) | _BV(UPE))); BITMASK_CLEAR(UCSRA, (_BV(FE) | _BV(DOR) | _BV(UPE)));
ReceiveError = true; ReceiveError = true;
} }
#endif #endif
/* check for overrun error */ /* check for overrun error */
if (BIT_CHECK(UCSRA, DOR)) { if (BIT_CHECK(UCSRA, DOR)) {
/* flush the receive buffer */ /* flush the receive buffer */
do { do {
dummy_data = UDR; dummy_data = UDR;
} while (BIT_CHECK(UCSRA, RXC)); } while (BIT_CHECK(UCSRA, RXC));
ReceiveError = true; ReceiveError = true;
} }
return ReceiveError; return ReceiveError;
} }
/**************************************************************************** /****************************************************************************
* DESCRIPTION: Return true if data is available * DESCRIPTION: Return true if data is available
* RETURN: true if data is available, with the data in the parameter set * RETURN: true if data is available, with the data in the parameter set
* ALGORITHM: none * ALGORITHM: none
* NOTES: none * NOTES: none
*****************************************************************************/ *****************************************************************************/
bool RS485_DataAvailable( bool RS485_DataAvailable(
uint8_t * data) uint8_t * data)
{ {
bool DataAvailable = false; bool DataAvailable = false;
/* check for data */ /* check for data */
if (BIT_CHECK(UCSRA, RXC)) { if (BIT_CHECK(UCSRA, RXC)) {
*data = UDR; *data = UDR;
DataAvailable = true; DataAvailable = true;
} }
return DataAvailable; return DataAvailable;
} }
#ifdef TEST_RS485 #ifdef TEST_RS485
int main( int main(
void) void)
{ {
unsigned i = 0; unsigned i = 0;
uint8_t DataRegister; uint8_t DataRegister;
RS485_Set_Baud_Rate(38400); RS485_Set_Baud_Rate(38400);
RS485_Initialize(); RS485_Initialize();
/* receive task */ /* receive task */
for (;;) { for (;;) {
if (RS485_ReceiveError()) { if (RS485_ReceiveError()) {
fprintf(stderr, "ERROR "); fprintf(stderr, "ERROR ");
} else if (RS485_DataAvailable(&DataRegister)) { } else if (RS485_DataAvailable(&DataRegister)) {
fprintf(stderr, "%02X ", DataRegister); fprintf(stderr, "%02X ", DataRegister);
} }
} }
} }
#endif /* TEST_RS485 */ #endif /* TEST_RS485 */
+70 -70
View File
@@ -1,70 +1,70 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2004 Steve Karg Copyright (C) 2004 Steve Karg
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307 Boston, MA 02111-1307
USA. USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#ifndef RS485_H #ifndef RS485_H
#define RS485_H #define RS485_H
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void RS485_Initialize( void RS485_Initialize(
void); void);
void RS485_Transmitter_Enable( void RS485_Transmitter_Enable(
bool enable); bool enable);
void RS485_Send_Data( void RS485_Send_Data(
uint8_t * buffer, /* data to send */ uint8_t * buffer, /* data to send */
uint16_t nbytes); /* number of bytes of data */ uint16_t nbytes); /* number of bytes of data */
bool RS485_ReceiveError( bool RS485_ReceiveError(
void); void);
bool RS485_DataAvailable( bool RS485_DataAvailable(
uint8_t * data); uint8_t * data);
void RS485_Turnaround_Delay( void RS485_Turnaround_Delay(
void); void);
uint32_t RS485_Get_Baud_Rate( uint32_t RS485_Get_Baud_Rate(
void); void);
bool RS485_Set_Baud_Rate( bool RS485_Set_Baud_Rate(
uint32_t baud); uint32_t baud);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+28 -28
View File
@@ -1,28 +1,28 @@
#ifndef STDBOOL_H #ifndef STDBOOL_H
#define STDBOOL_H #define STDBOOL_H
/* C99 Boolean types for compilers without C99 support */ /* C99 Boolean types for compilers without C99 support */
#ifndef __cplusplus #ifndef __cplusplus
/* typedef char _Bool; */ /* typedef char _Bool; */
#ifndef bool #ifndef bool
#define bool _Bool #define bool _Bool
#endif #endif
#ifndef true #ifndef true
#define true 1 #define true 1
#endif #endif
#ifndef false #ifndef false
#define false 0 #define false 0
#endif #endif
#define __bool_true_false_are_defined 1 #define __bool_true_false_are_defined 1
#endif #endif
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#endif #endif
#endif #endif
+15 -15
View File
@@ -1,15 +1,15 @@
/* Defines the standard integer types that are used in code */ /* Defines the standard integer types that are used in code */
#ifndef STDINT_H #ifndef STDINT_H
#define STDINT_H 1 #define STDINT_H 1
#include <stddef.h> #include <stddef.h>
typedef unsigned char uint8_t; /* 1 byte 0 to 255 */ typedef unsigned char uint8_t; /* 1 byte 0 to 255 */
typedef signed char int8_t; /* 1 byte -127 to 127 */ typedef signed char int8_t; /* 1 byte -127 to 127 */
typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */ typedef unsigned short uint16_t; /* 2 bytes 0 to 65535 */
typedef signed short int16_t; /* 2 bytes -32767 to 32767 */ typedef signed short int16_t; /* 2 bytes -32767 to 32767 */
typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */ typedef unsigned long uint32_t; /* 4 bytes 0 to 4294967295 */
typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */ typedef signed long int32_t; /* 4 bytes -2147483647 to 2147483647 */
#endif /* STDINT_H */ #endif /* STDINT_H */
+110 -109
View File
@@ -1,109 +1,110 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "hardware.h" #include "hardware.h"
/* This module is a 1 millisecond timer */ /* This module is a 1 millisecond timer */
/* Prescaling: 1, 8, 64, 256, 1024 */ /* Prescaling: 1, 8, 64, 256, 1024 */
#define TIMER_PRESCALER 64 #define TIMER_PRESCALER 64
/* Count: Timer0 counts up to 0xFF and then signals overflow */ /* Count: Timer0 counts up to 0xFF and then signals overflow */
#define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000) #define TIMER_TICKS (F_CPU/TIMER_PRESCALER/1000)
#if (TIMER_TICKS > 0xFF) #if (TIMER_TICKS > 0xFF)
#error Timer Prescaler value is too small #error Timer Prescaler value is too small
#endif #endif
#define TIMER_COUNT (0xFF-TIMER_TICKS) #define TIMER_COUNT (0xFF-TIMER_TICKS)
/* millisecond timer count */ /* millisecond timer count */
static volatile uint16_t Timer_Silence; static volatile uint16_t Timer_Silence;
/* FIXME: Configure the Timer */ /* FIXME: Configure the Timer */
void timer_init( void timer_init(
void) void)
{ {
/* Normal Operation */ /* Normal Operation */
TCCR1A = 0; TCCR1A = 0;
/* CSn2 CSn1 CSn0 Description /* CSn2 CSn1 CSn0 Description
---- ---- ---- ----------- ---- ---- ---- -----------
0 0 0 No Clock Source 0 0 0 No Clock Source
0 0 1 No prescaling 0 0 1 No prescaling
0 1 0 CLKio/8 0 1 0 CLKio/8
0 1 1 CLKio/64 0 1 1 CLKio/64
1 0 0 CLKio/256 1 0 0 CLKio/256
1 0 1 CLKio/1024 1 0 1 CLKio/1024
1 1 0 Falling Edge of T0 (external) 1 1 0 Falling Edge of T0 (external)
1 1 1 Rising Edge of T0 (external) 1 1 1 Rising Edge of T0 (external)
*/ */
#if defined(__AVR_ATmega168__) #if defined(__AVR_ATmega168__)
TCCR0B = _BV(CS01) | _BV(CS00); TCCR0B = _BV(CS01) | _BV(CS00);
/* Clear any TOV1 Flag set when the timer overflowed */ /* Clear any TOV1 Flag set when the timer overflowed */
BIT_CLEAR(TIFR0, TOV0); BIT_CLEAR(TIFR0, TOV0);
/* Initial value */ /* Initial value */
TCNT0 = TIMER_COUNT; TCNT0 = TIMER_COUNT;
/* Enable the overflow interrupt */ /* Enable the overflow interrupt */
BIT_SET(TIMSK0, TOIE0); BIT_SET(TIMSK0, TOIE0);
/* Clear the Power Reduction Timer/Counter0 */ /* Clear the Power Reduction Timer/Counter0 */
BIT_CLEAR(PRR, PRTIM0); BIT_CLEAR(PRR, PRTIM0);
#endif #endif
} }
/* Timer interupt */ /* Timer interupt */
/* note: Global interupts must be enabled - sei() */ /* note: Global interupts must be enabled - sei() */
/* Timer Overflowed! Increment the time. */ /* Timer Overflowed! Increment the time. */
ISR(TIMER0_OVF_vect) ISR(TIMER0_OVF_vect)
{ {
/* Set the counter for the next interrupt */ /* Set the counter for the next interrupt */
TCNT0 = TIMER_COUNT; TCNT0 = TIMER_COUNT;
/* Overflow Flag is automatically cleared */ /* Overflow Flag is automatically cleared */
/* Update the global timer */ /* Update the global timer */
Timer_Silence++; Timer_Silence++;
} }
/* return true if time has expired */ /* return true if time has expired */
bool timer_silence_elapsed( bool timer_silence_elapsed(
uint16_t value) uint16_t value)
{ {
bool status = false; bool status = false;
uint8_t sreg; uint8_t sreg;
sreg = SREG; sreg = SREG;
__disable_interrupt(); __disable_interrupt();
if (Timer_Silence >= value) { if (Timer_Silence >= value) {
status = true; status = true;
} }
SREG = sreg; SREG = sreg;
return status; return status;
} }
void timer_silence_reset(void) void timer_silence_reset(
{ void)
uint8_t sreg; {
uint8_t sreg;
sreg = SREG;
__disable_interrupt(); sreg = SREG;
Timer_Silence = 0; __disable_interrupt();
SREG = sreg; Timer_Silence = 0;
} SREG = sreg;
}
+42 -42
View File
@@ -1,42 +1,42 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
* *
* Permission is hereby granted, free of charge, to any person obtaining * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including * "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, * without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to * distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to * permit persons to whom the Software is furnished to do so, subject to
* the following conditions: * the following conditions:
* *
* The above copyright notice and this permission notice shall be included * The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software. * in all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* *
*********************************************************************/ *********************************************************************/
#ifndef TIMER_H #ifndef TIMER_H
#define TIMER_H #define TIMER_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void timer_init( void timer_init(
void); void);
bool timer_silence_elapsed( bool timer_silence_elapsed(
uint16_t value); uint16_t value);
void timer_silence_reset( void timer_silence_reset(
void); void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif #endif
+3 -3
View File
@@ -170,7 +170,7 @@ static void snap_received_packet(
{ {
uint16_t mtu_len = 0; /* number of octets of packet saved in file */ uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */ unsigned i = 0; /* counter */
static uint8_t mtu[1500] = { 0 }; static uint8_t mtu[1500] = { 0 };
uint16_t max_data = 0; uint16_t max_data = 0;
mtu[0] = 0; mtu[0] = 0;
@@ -204,8 +204,8 @@ static void snap_received_packet(
mtu[29] = LO_BYTE(mstp_port->DataLength); mtu[29] = LO_BYTE(mstp_port->DataLength);
mtu[30] = mstp_port->HeaderCRCActual; mtu[30] = mstp_port->HeaderCRCActual;
mtu_len = 31; mtu_len = 31;
if (mstp_port->DataLength) { if (mstp_port->DataLength) {
max_data = min(mstp_port->InputBufferSize,mstp_port->DataLength); max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength);
for (i = 0; i < max_data; i++) { for (i = 0; i < max_data; i++) {
mtu[31 + i] = mstp_port->InputBuffer[i]; mtu[31 + i] = mstp_port->InputBuffer[i];
} }
+2 -2
View File
@@ -217,8 +217,8 @@ static void write_received_packet(
fwrite(header, sizeof(header), 1, pFile); fwrite(header, sizeof(header), 1, pFile);
if (mstp_port->DataLength) { if (mstp_port->DataLength) {
fwrite(mstp_port->InputBuffer, max_data, 1, pFile); fwrite(mstp_port->InputBuffer, max_data, 1, pFile);
fwrite((char *)&(mstp_port->DataCRCActualMSB), 1, 1, pFile); fwrite((char *) &(mstp_port->DataCRCActualMSB), 1, 1, pFile);
fwrite((char *)&(mstp_port->DataCRCActualLSB), 1, 1, pFile); fwrite((char *) &(mstp_port->DataCRCActualLSB), 1, 1, pFile);
} }
} else { } else {
fprintf(stderr, "rx_fsm: failed to open %s: %s\n", Capture_Filename, fprintf(stderr, "rx_fsm: failed to open %s: %s\n", Capture_Filename,
+1 -1
View File
@@ -381,7 +381,7 @@ bool bip_init(
bip_set_socket(-1); bip_set_socket(-1);
return false; 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, rv = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, (char *) &value,
sizeof(value)); sizeof(value));
if (rv < 0) { if (rv < 0) {
+5 -6
View File
@@ -294,14 +294,13 @@ static void Init_DataLink(
#endif #endif
} }
int main( int main(int argc, char *argv[]) {
int argc, BACNET_ADDRESS src = {
char *argv[]) 0}; /* address where message came from */
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */ unsigned timeout = 100; /* milliseconds */
BACNET_ADDRESS my_address, broadcast_address; BACNET_ADDRESS my_address,
broadcast_address;
(void) argc; (void) argc;
(void) argv; (void) argv;
+1 -1
View File
@@ -245,7 +245,7 @@ static void write_received_packet(
fwrite(&ts_sec, sizeof(ts_sec), 1, pFile); fwrite(&ts_sec, sizeof(ts_sec), 1, pFile);
fwrite(&ts_usec, sizeof(ts_usec), 1, pFile); fwrite(&ts_usec, sizeof(ts_usec), 1, pFile);
if (mstp_port->DataLength) { 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; incl_len = orig_len = 8 + max_data + 2;
} else { } else {
incl_len = orig_len = 8; incl_len = orig_len = 8;
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef _STDBOOL_H #ifndef _STDBOOL_H
#define _STDBOOL_H #define _STDBOOL_H
#include <stdint.h> #include <stdint.h>
/* C99 Boolean types for compilers without C99 support */ /* C99 Boolean types for compilers without C99 support */
/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */ /* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */
@@ -14,7 +14,7 @@
the values 0 and 1. */ the values 0 and 1. */
/* We choose 8 bit to match C++ */ /* We choose 8 bit to match C++ */
/* It must also promote to integer */ /* It must also promote to integer */
typedef int8_t _Bool; typedef int8_t _Bool;
#endif #endif
/* ISO C Standard: 7.16 Boolean type */ /* ISO C Standard: 7.16 Boolean type */
+1 -1
View File
@@ -95,7 +95,7 @@ int arf_decode_service_request(
int tag_len = 0; int tag_len = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value_type = 0; uint32_t len_value_type = 0;
uint16_t type = 0; /* for decoding */ uint16_t type = 0; /* for decoding */
/* check for value pointers */ /* check for value pointers */
if (apdu_len && data) { if (apdu_len && data) {
+1 -1
View File
@@ -100,7 +100,7 @@ int awf_decode_service_request(
uint32_t len_value_type = 0; uint32_t len_value_type = 0;
int32_t signed_value = 0; int32_t signed_value = 0;
uint32_t unsigned_value = 0; uint32_t unsigned_value = 0;
uint16_t type = 0; /* for decoding */ uint16_t type = 0; /* for decoding */
/* check for value pointers */ /* check for value pointers */
if (apdu_len && data) { if (apdu_len && data) {
File diff suppressed because it is too large Load Diff
+235 -243
View File
@@ -1,243 +1,235 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#include <assert.h> #include <assert.h>
#include "bacdcode.h" #include "bacdcode.h"
#include "npdu.h" #include "npdu.h"
#include "device.h" #include "device.h"
#include "datalink.h" #include "datalink.h"
#include "timestamp.h" #include "timestamp.h"
#include "bacdevobjpropref.h" #include "bacdevobjpropref.h"
int bacapp_encode_context_device_obj_property_ref( int bacapp_encode_context_device_obj_property_ref(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value)
{ {
int len; int len;
int apdu_len = 0; int apdu_len = 0;
len = encode_opening_tag(&apdu[apdu_len], tag_number); len = encode_opening_tag(&apdu[apdu_len], tag_number);
apdu_len += len; apdu_len += len;
len = bacapp_encode_device_obj_property_ref(&apdu[apdu_len], value); len = bacapp_encode_device_obj_property_ref(&apdu[apdu_len], value);
apdu_len += len; apdu_len += len;
len = encode_closing_tag(&apdu[apdu_len], tag_number); len = encode_closing_tag(&apdu[apdu_len], tag_number);
apdu_len += len; apdu_len += len;
return apdu_len; return apdu_len;
} }
int bacapp_encode_device_obj_property_ref( int bacapp_encode_device_obj_property_ref(
uint8_t * apdu, uint8_t * apdu,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value)
{ {
int len; int len;
int apdu_len = 0; int apdu_len = 0;
len = encode_context_object_id(&apdu[apdu_len], 0, len =
value->objectIdentifier.type, encode_context_object_id(&apdu[apdu_len], 0,
value->objectIdentifier.instance); value->objectIdentifier.type, value->objectIdentifier.instance);
apdu_len += len; apdu_len += len;
len = encode_context_enumerated(&apdu[apdu_len], 1, len =
value->propertyIdentifier); encode_context_enumerated(&apdu[apdu_len], 1,
apdu_len += len; value->propertyIdentifier);
apdu_len += len;
if ( value->arrayIndex > 0 )
{ if (value->arrayIndex > 0) {
len = encode_context_unsigned(&apdu[apdu_len], 2, len = encode_context_unsigned(&apdu[apdu_len], 2, value->arrayIndex);
value->arrayIndex); apdu_len += len;
apdu_len += len; }
} len =
len = encode_context_object_id(&apdu[apdu_len], 3, encode_context_object_id(&apdu[apdu_len], 3,
value->deviceIndentifier.type, value->deviceIndentifier.type, value->deviceIndentifier.instance);
value->deviceIndentifier.instance); apdu_len += len;
apdu_len += len;
return apdu_len;
return apdu_len; }
}
int bacapp_decode_device_obj_property_ref(
int bacapp_decode_device_obj_property_ref( uint8_t * apdu,
uint8_t * apdu, BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value)
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) {
{ int len;
int len; int apdu_len = 0;
int apdu_len = 0;
if (-1 == (len =
if ( -1 == ( len = decode_context_object_id(&apdu[apdu_len], 0, decode_context_object_id(&apdu[apdu_len], 0,
&value->objectIdentifier.type, &value->objectIdentifier.type,
&value->objectIdentifier.instance)) ) &value->objectIdentifier.instance))) {
{ return -1;
return -1; }
} apdu_len += len;
apdu_len += len;
if (-1 == (len =
if ( -1 == ( len = decode_context_enumerated(&apdu[apdu_len], 1, decode_context_enumerated(&apdu[apdu_len], 1,
&value->propertyIdentifier))) &value->propertyIdentifier))) {
{ return -1;
return -1; }
} apdu_len += len;
apdu_len += len;
if (decode_is_context_tag(&apdu[apdu_len], 2)) {
if ( decode_is_context_tag(&apdu[apdu_len], 2 )) if (-1 == (len =
{ decode_context_unsigned(&apdu[apdu_len], 2,
if ( -1 == ( len = decode_context_unsigned(&apdu[apdu_len], 2, &value->arrayIndex))) {
&value->arrayIndex))) return -1;
{ }
return -1; apdu_len += len;
} } else {
apdu_len += len; value->arrayIndex = 0;
} }
else
{ if (decode_is_context_tag(&apdu[apdu_len], 3)) {
value->arrayIndex = 0; if (-1 == (len =
} decode_context_object_id(&apdu[apdu_len], 3,
&value->deviceIndentifier.type,
if ( decode_is_context_tag(&apdu[apdu_len], 3 )) &value->deviceIndentifier.instance))) {
{ return -1;
if ( -1 == ( len = decode_context_object_id(&apdu[apdu_len], 3, }
&value->deviceIndentifier.type, apdu_len += len;
&value->deviceIndentifier.instance)) ) } else {
{ value->deviceIndentifier.instance = 0;
return -1; value->deviceIndentifier.type = 0;
} }
apdu_len += len;
} return apdu_len;
else }
{
value->deviceIndentifier.instance = 0; int bacapp_decode_context_device_obj_property_ref(
value->deviceIndentifier.type = 0; uint8_t * apdu,
} uint8_t tag_number,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value)
return apdu_len; {
} int len = 0;
int section_length;
int bacapp_decode_context_device_obj_property_ref(
uint8_t * apdu, if (decode_is_opening_tag_number(&apdu[len], tag_number)) {
uint8_t tag_number, len++;
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * value) section_length =
{ bacapp_decode_device_obj_property_ref(&apdu[len], value);
int len = 0;
int section_length; if (section_length == -1) {
len = -1;
if (decode_is_opening_tag_number(&apdu[len], tag_number)) { } else {
len++; len += section_length;
section_length = bacapp_decode_device_obj_property_ref( if (decode_is_closing_tag_number(&apdu[len], tag_number)) {
&apdu[len], value); len++;
} else {
if ( section_length == -1 ) len = -1;
{ }
len = -1; }
} } else {
else len = -1;
{ }
len += section_length; return len;
if (decode_is_closing_tag_number(&apdu[len], tag_number)) { }
len++;
} #ifdef TEST
else
{ void testDevIdPropRef(
len = -1; Test * pTest)
} {
} BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE inData;
} BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE outData;
else uint8_t buffer[MAX_APDU];
{ int inLen;
len = -1; int outLen;
}
return len;
} inData.objectIdentifier.instance = 0x1234;
inData.objectIdentifier.type = 15;
#ifdef TEST
inData.propertyIdentifier = 25;
void testDevIdPropRef(
Test * pTest) inData.arrayIndex = 0x5678;
{
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE inData; inData.deviceIndentifier.instance = 0x4343;
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE outData; inData.deviceIndentifier.type = 28;
uint8_t buffer[MAX_APDU];
int inLen; inLen = bacapp_encode_device_obj_property_ref(buffer, &inData);
int outLen; outLen = bacapp_decode_device_obj_property_ref(buffer, &outData);
ct_test(pTest, outLen == inLen);
inData.objectIdentifier.instance = 0x1234;
inData.objectIdentifier.type = 15; ct_test(pTest,
inData.objectIdentifier.instance == outData.objectIdentifier.instance);
inData.propertyIdentifier = 25; ct_test(pTest,
inData.objectIdentifier.type == outData.objectIdentifier.type);
inData.arrayIndex = 0x5678;
ct_test(pTest, inData.propertyIdentifier == outData.propertyIdentifier);
inData.deviceIndentifier.instance = 0x4343;
inData.deviceIndentifier.type = 28; ct_test(pTest, inData.arrayIndex == outData.arrayIndex);
inLen = bacapp_encode_device_obj_property_ref(buffer, &inData); ct_test(pTest,
outLen = bacapp_decode_device_obj_property_ref(buffer, &outData); inData.deviceIndentifier.instance ==
outData.deviceIndentifier.instance);
ct_test(pTest, outLen == inLen); ct_test(pTest,
inData.deviceIndentifier.type == outData.deviceIndentifier.type);
ct_test(pTest, inData.objectIdentifier.instance == outData.objectIdentifier.instance); }
ct_test(pTest, inData.objectIdentifier.type == outData.objectIdentifier.type);
#ifdef TEST_DEV_ID_PROP_REF
ct_test(pTest, inData.propertyIdentifier == outData.propertyIdentifier);
int main(
ct_test(pTest, inData.arrayIndex == outData.arrayIndex); void)
{
ct_test(pTest, inData.deviceIndentifier.instance == outData.deviceIndentifier.instance); Test *pTest;
ct_test(pTest, inData.deviceIndentifier.type == outData.deviceIndentifier.type); bool rc;
}
#ifdef TEST_DEV_ID_PROP_REF pTest = ct_create("BACnet Prop Ref", NULL);
/* individual tests */
int main( rc = ct_addTestFunction(pTest, testDevIdPropRef);
void) assert(rc);
{
Test *pTest; ct_setStream(pTest, stdout);
bool rc; ct_run(pTest);
(void) ct_report(pTest);
pTest = ct_create("BACnet Prop Ref", NULL); ct_destroy(pTest);
/* individual tests */
rc = ct_addTestFunction(pTest, testDevIdPropRef); return 0;
assert(rc); }
ct_setStream(pTest, stdout); #endif // TEST_DEV_ID_PROP_REF
ct_run(pTest); #endif // TEST
(void) ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif // TEST_DEV_ID_PROP_REF
#endif // TEST
+432 -403
View File
@@ -1,403 +1,432 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#include <assert.h> #include <assert.h>
#include "bacdcode.h" #include "bacdcode.h"
#include "npdu.h" #include "npdu.h"
#include "device.h" #include "device.h"
#include "datalink.h" #include "datalink.h"
#include "timestamp.h" #include "timestamp.h"
#include "bacpropstates.h" #include "bacpropstates.h"
int bacapp_decode_property_state( int bacapp_decode_property_state(
uint8_t * apdu, uint8_t * apdu,
BACNET_PROPERTY_STATE * value) BACNET_PROPERTY_STATE * value)
{ {
int len = 0; int len = 0;
uint32_t len_value_type; uint32_t len_value_type;
int section_length; int section_length;
section_length = section_length =
decode_tag_number_and_value(&apdu[len], (uint8_t*)&value->tag, decode_tag_number_and_value(&apdu[len], (uint8_t *) & value->tag,
&len_value_type); &len_value_type);
if ( -1 == section_length ) if (-1 == section_length) {
{ return -1;
return -1; }
}
len += section_length;
len += section_length; switch (value->tag) {
switch(value->tag) case BOOLEAN_VALUE:
{ value->state.booleanValue = decode_boolean(len_value_type);
case BOOLEAN_VALUE: break;
value->state.booleanValue = decode_boolean(len_value_type);
break; case BINARY_VALUE:
if (-1 == (section_length =
case BINARY_VALUE: decode_enumerated(&apdu[len], len_value_type,
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.binaryValue))) &value->state.binaryValue))) {
{ return -1;
return -1; }
} break;
break;
case EVENT_TYPE:
case EVENT_TYPE: if (-1 == (section_length =
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.eventType))) decode_enumerated(&apdu[len], len_value_type,
{ &value->state.eventType))) {
return -1; return -1;
} }
break; break;
case POLARITY: case POLARITY:
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.polarity))) if (-1 == (section_length =
{ decode_enumerated(&apdu[len], len_value_type,
return -1; &value->state.polarity))) {
} return -1;
break; }
break;
case PROGRAM_CHANGE:
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.programChange))) case PROGRAM_CHANGE:
{ if (-1 == (section_length =
return -1; decode_enumerated(&apdu[len], len_value_type,
} &value->state.programChange))) {
break; return -1;
}
case PROGRAM_STATE: break;
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.programState)))
{ case PROGRAM_STATE:
return -1; if (-1 == (section_length =
} decode_enumerated(&apdu[len], len_value_type,
break; &value->state.programState))) {
return -1;
case REASON_FOR_HALT: }
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.programError))) break;
{
return -1; case REASON_FOR_HALT:
} if (-1 == (section_length =
break; decode_enumerated(&apdu[len], len_value_type,
&value->state.programError))) {
case RELIABILITY: return -1;
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.reliability))) }
{ break;
return -1;
} case RELIABILITY:
break; if (-1 == (section_length =
decode_enumerated(&apdu[len], len_value_type,
case STATE: &value->state.reliability))) {
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.state))) return -1;
{ }
return -1; break;
}
break; case STATE:
if (-1 == (section_length =
case SYSTEM_STATUS: decode_enumerated(&apdu[len], len_value_type,
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.systemStatus))) &value->state.state))) {
{ return -1;
return -1; }
} break;
break;
case SYSTEM_STATUS:
case UNITS: if (-1 == (section_length =
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.units))) decode_enumerated(&apdu[len], len_value_type,
{ &value->state.systemStatus))) {
return -1; return -1;
} }
break; break;
case UNSIGNED_VALUE: case UNITS:
if ( -1 == ( section_length = decode_unsigned(&apdu[len], len_value_type, &value->state.unsignedValue))) if (-1 == (section_length =
{ decode_enumerated(&apdu[len], len_value_type,
return -1; &value->state.units))) {
} return -1;
break; }
break;
case LIFE_SAFETY_MODE:
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.lifeSafetyMode))) case UNSIGNED_VALUE:
{ if (-1 == (section_length =
return -1; decode_unsigned(&apdu[len], len_value_type,
} &value->state.unsignedValue))) {
break; return -1;
}
case LIFE_SAFETY_STATE: break;
if ( -1 == ( section_length = decode_enumerated(&apdu[len], len_value_type, &value->state.lifeSafetyState)))
{ case LIFE_SAFETY_MODE:
return -1; if (-1 == (section_length =
} decode_enumerated(&apdu[len], len_value_type,
break; &value->state.lifeSafetyMode))) {
return -1;
default: }
return -1; break;
}
len += section_length; case LIFE_SAFETY_STATE:
if (-1 == (section_length =
return len; decode_enumerated(&apdu[len], len_value_type,
} &value->state.lifeSafetyState))) {
return -1;
int bacapp_decode_context_property_state( }
uint8_t * apdu, break;
uint8_t tag_number,
BACNET_PROPERTY_STATE * value) default:
{ return -1;
int len = 0; }
int section_length; len += section_length;
if (decode_is_opening_tag_number(&apdu[len], tag_number)) { return len;
len++; }
section_length = bacapp_decode_property_state(
&apdu[len], value); int bacapp_decode_context_property_state(
uint8_t * apdu,
if ( section_length == -1 ) uint8_t tag_number,
{ BACNET_PROPERTY_STATE * value)
len = -1; {
} int len = 0;
else int section_length;
{
len += section_length; if (decode_is_opening_tag_number(&apdu[len], tag_number)) {
if (decode_is_closing_tag_number(&apdu[len], tag_number)) { len++;
len++; section_length = bacapp_decode_property_state(&apdu[len], value);
}
else if (section_length == -1) {
{ len = -1;
len = -1; } else {
} len += section_length;
} if (decode_is_closing_tag_number(&apdu[len], tag_number)) {
} len++;
else } else {
{ len = -1;
len = -1; }
} }
return len; } else {
} len = -1;
}
int bacapp_encode_property_state( return len;
uint8_t * apdu, }
BACNET_PROPERTY_STATE * value)
{ int bacapp_encode_property_state(
int len = 0; /* length of each encoding */ uint8_t * apdu,
if (value && apdu) { BACNET_PROPERTY_STATE * value)
switch(value->tag) {
{ int len = 0; /* length of each encoding */
case BOOLEAN_VALUE: if (value && apdu) {
len = encode_context_boolean(&apdu[0], 0, value->state.booleanValue); switch (value->tag) {
break; case BOOLEAN_VALUE:
len =
case BINARY_VALUE: encode_context_boolean(&apdu[0], 0,
len = encode_context_enumerated(&apdu[0], 1, value->state.binaryValue); value->state.booleanValue);
break; break;
case EVENT_TYPE: case BINARY_VALUE:
len = encode_context_enumerated(&apdu[0], 2, value->state.eventType); len =
break; encode_context_enumerated(&apdu[0], 1,
value->state.binaryValue);
case POLARITY: break;
len = encode_context_enumerated(&apdu[0], 3, value->state.polarity);
break; case EVENT_TYPE:
len =
case PROGRAM_CHANGE: encode_context_enumerated(&apdu[0], 2,
len = encode_context_enumerated(&apdu[0], 4, value->state.programChange); value->state.eventType);
break; break;
case PROGRAM_STATE: case POLARITY:
len = encode_context_enumerated(&apdu[0], 5, value->state.programState); len =
break; encode_context_enumerated(&apdu[0], 3,
value->state.polarity);
case REASON_FOR_HALT: break;
len = encode_context_enumerated(&apdu[0], 6, value->state.programError);
break; case PROGRAM_CHANGE:
len =
case RELIABILITY: encode_context_enumerated(&apdu[0], 4,
len = encode_context_enumerated(&apdu[0], 7, value->state.reliability); value->state.programChange);
break; break;
case STATE: case PROGRAM_STATE:
len = encode_context_enumerated(&apdu[0], 8, value->state.state); len =
break; encode_context_enumerated(&apdu[0], 5,
value->state.programState);
case SYSTEM_STATUS: break;
len = encode_context_enumerated(&apdu[0], 9, value->state.systemStatus);
break; case REASON_FOR_HALT:
len =
case UNITS: encode_context_enumerated(&apdu[0], 6,
len = encode_context_enumerated(&apdu[0], 10, value->state.units); value->state.programError);
break; break;
case UNSIGNED_VALUE: case RELIABILITY:
len = encode_context_unsigned(&apdu[0], 11, value->state.unsignedValue); len =
break; encode_context_enumerated(&apdu[0], 7,
value->state.reliability);
case LIFE_SAFETY_MODE: break;
len = encode_context_enumerated(&apdu[0], 12, value->state.lifeSafetyMode);
break; case STATE:
len =
case LIFE_SAFETY_STATE: encode_context_enumerated(&apdu[0], 8, value->state.state);
len = encode_context_enumerated(&apdu[0], 13, value->state.lifeSafetyState); break;
break;
case SYSTEM_STATUS:
default: len =
assert(0); encode_context_enumerated(&apdu[0], 9,
break; value->state.systemStatus);
} break;
}
return len; case UNITS:
} len =
encode_context_enumerated(&apdu[0], 10,
#ifdef TEST value->state.units);
break;
void testPropStates(
Test * pTest) case UNSIGNED_VALUE:
{ len =
BACNET_PROPERTY_STATE inData; encode_context_unsigned(&apdu[0], 11,
BACNET_PROPERTY_STATE outData; value->state.unsignedValue);
uint8_t appMsg[MAX_APDU]; break;
int inLen;
int outLen; case LIFE_SAFETY_MODE:
len =
inData.tag = BOOLEAN_VALUE; encode_context_enumerated(&apdu[0], 12,
inData.state.booleanValue = true; value->state.lifeSafetyMode);
break;
inLen = bacapp_encode_property_state(appMsg, &inData);
case LIFE_SAFETY_STATE:
memset(&outData, 0, sizeof(outData)); len =
encode_context_enumerated(&apdu[0], 13,
outLen = bacapp_decode_property_state(appMsg, &outData); value->state.lifeSafetyState);
break;
ct_test(pTest, outLen == inLen);
ct_test(pTest, inData.tag == outData.tag ); default:
ct_test(pTest, inData.state.booleanValue == outData.state.booleanValue ); assert(0);
break;
/**************** }
***************** }
****************/ return len;
inData.tag = BINARY_VALUE; }
inData.state.binaryValue = BINARY_ACTIVE;
#ifdef TEST
inLen = bacapp_encode_property_state(appMsg, &inData);
void testPropStates(
memset(&outData, 0, sizeof(outData)); Test * pTest)
{
outLen = bacapp_decode_property_state(appMsg, &outData); BACNET_PROPERTY_STATE inData;
BACNET_PROPERTY_STATE outData;
ct_test(pTest, outLen == inLen); uint8_t appMsg[MAX_APDU];
ct_test(pTest, inData.tag == outData.tag ); int inLen;
ct_test(pTest, inData.state.binaryValue == outData.state.binaryValue ); int outLen;
/**************** inData.tag = BOOLEAN_VALUE;
***************** inData.state.booleanValue = true;
****************/
inData.tag = EVENT_TYPE; inLen = bacapp_encode_property_state(appMsg, &inData);
inData.state.eventType = EVENT_BUFFER_READY;
memset(&outData, 0, sizeof(outData));
inLen = bacapp_encode_property_state(appMsg, &inData);
outLen = bacapp_decode_property_state(appMsg, &outData);
memset(&outData, 0, sizeof(outData));
ct_test(pTest, outLen == inLen);
outLen = bacapp_decode_property_state(appMsg, &outData); ct_test(pTest, inData.tag == outData.tag);
ct_test(pTest, inData.state.booleanValue == outData.state.booleanValue);
ct_test(pTest, outLen == inLen);
ct_test(pTest, inData.tag == outData.tag ); /****************
ct_test(pTest, inData.state.eventType == outData.state.eventType ); *****************
****************/
/**************** inData.tag = BINARY_VALUE;
***************** inData.state.binaryValue = BINARY_ACTIVE;
****************/
inData.tag = POLARITY; inLen = bacapp_encode_property_state(appMsg, &inData);
inData.state.polarity = POLARITY_REVERSE;
memset(&outData, 0, sizeof(outData));
inLen = bacapp_encode_property_state(appMsg, &inData);
outLen = bacapp_decode_property_state(appMsg, &outData);
memset(&outData, 0, sizeof(outData));
ct_test(pTest, outLen == inLen);
outLen = bacapp_decode_property_state(appMsg, &outData); ct_test(pTest, inData.tag == outData.tag);
ct_test(pTest, inData.state.binaryValue == outData.state.binaryValue);
ct_test(pTest, outLen == inLen);
ct_test(pTest, inData.tag == outData.tag ); /****************
ct_test(pTest, inData.state.polarity == outData.state.polarity ); *****************
****************/
/**************** inData.tag = EVENT_TYPE;
***************** inData.state.eventType = EVENT_BUFFER_READY;
****************/
inData.tag = PROGRAM_CHANGE; inLen = bacapp_encode_property_state(appMsg, &inData);
inData.state.programChange = PROGRAM_REQUEST_RESTART;
memset(&outData, 0, sizeof(outData));
inLen = bacapp_encode_property_state(appMsg, &inData);
outLen = bacapp_decode_property_state(appMsg, &outData);
memset(&outData, 0, sizeof(outData));
ct_test(pTest, outLen == inLen);
outLen = bacapp_decode_property_state(appMsg, &outData); ct_test(pTest, inData.tag == outData.tag);
ct_test(pTest, inData.state.eventType == outData.state.eventType);
ct_test(pTest, outLen == inLen);
ct_test(pTest, inData.tag == outData.tag ); /****************
ct_test(pTest, inData.state.programChange == outData.state.programChange ); *****************
****************/
/**************** inData.tag = POLARITY;
***************** inData.state.polarity = POLARITY_REVERSE;
****************/
inData.tag = UNSIGNED_VALUE; inLen = bacapp_encode_property_state(appMsg, &inData);
inData.state.unsignedValue = 0xdeadbeef;
memset(&outData, 0, sizeof(outData));
inLen = bacapp_encode_property_state(appMsg, &inData);
outLen = bacapp_decode_property_state(appMsg, &outData);
memset(&outData, 0, sizeof(outData));
ct_test(pTest, outLen == inLen);
outLen = bacapp_decode_property_state(appMsg, &outData); ct_test(pTest, inData.tag == outData.tag);
ct_test(pTest, inData.state.polarity == outData.state.polarity);
ct_test(pTest, outLen == inLen);
ct_test(pTest, inData.tag == outData.tag ); /****************
ct_test(pTest, inData.state.unsignedValue == outData.state.unsignedValue ); *****************
****************/
} inData.tag = PROGRAM_CHANGE;
inData.state.programChange = PROGRAM_REQUEST_RESTART;
#ifdef TEST_PROP_STATES
inLen = bacapp_encode_property_state(appMsg, &inData);
int main(
void) memset(&outData, 0, sizeof(outData));
{
Test *pTest; outLen = bacapp_decode_property_state(appMsg, &outData);
bool rc;
ct_test(pTest, outLen == inLen);
pTest = ct_create("BACnet Event", NULL); ct_test(pTest, inData.tag == outData.tag);
/* individual tests */ ct_test(pTest, inData.state.programChange == outData.state.programChange);
rc = ct_addTestFunction(pTest, testPropStates);
assert(rc); /****************
*****************
ct_setStream(pTest, stdout); ****************/
ct_run(pTest); inData.tag = UNSIGNED_VALUE;
(void) ct_report(pTest); inData.state.unsignedValue = 0xdeadbeef;
ct_destroy(pTest);
inLen = bacapp_encode_property_state(appMsg, &inData);
return 0;
} memset(&outData, 0, sizeof(outData));
#endif // TEST_PROP_STATES outLen = bacapp_decode_property_state(appMsg, &outData);
#endif // TEST
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
+11 -12
View File
@@ -78,23 +78,22 @@ int decode_real(
int decode_context_real( int decode_context_real(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
float *real_value) float *real_value)
{ {
uint32_t len_value; uint32_t len_value;
int len = 0; int len = 0;
if (decode_is_context_tag(&apdu[len], tag_number)) { if (decode_is_context_tag(&apdu[len], tag_number)) {
len += decode_tag_number_and_value(&apdu[len], &tag_number, len +=
&len_value); decode_tag_number_and_value(&apdu[len], &tag_number, &len_value);
len += decode_real(&apdu[len], real_value); len += decode_real(&apdu[len], real_value);
} } else {
else len = -1;
{ }
len = -1; return len;
}
return len;
} }
/* from clause 20.2.6 Encoding of a Real Number Value */ /* from clause 20.2.6 Encoding of a Real Number Value */
/* returns the number of apdu bytes consumed */ /* returns the number of apdu bytes consumed */
int encode_bacnet_real( int encode_bacnet_real(
+2 -2
View File
@@ -99,7 +99,7 @@ uint8_t bitstring_bits_used(
uint8_t bitstring_bytes_used( uint8_t bitstring_bytes_used(
BACNET_BIT_STRING * bit_string) BACNET_BIT_STRING * bit_string)
{ {
uint8_t len = 0; /* return value */ uint8_t len = 0; /* return value */
uint8_t used_bytes = 0; uint8_t used_bytes = 0;
uint8_t last_bit = 0; uint8_t last_bit = 0;
@@ -544,7 +544,7 @@ bool octetstring_value_same(
BACNET_OCTET_STRING * octet_string1, BACNET_OCTET_STRING * octet_string1,
BACNET_OCTET_STRING * octet_string2) 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 && octet_string2) {
if ((octet_string1->length == octet_string2->length) && if ((octet_string1->length == octet_string2->length) &&
+3 -3
View File
@@ -174,7 +174,7 @@ int cov_notify_decode_service_request(
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint32_t decoded_value = 0; /* for decoding */ 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 */ int property = 0; /* for decoding */
BACNET_PROPERTY_VALUE *value = NULL; /* value in list */ BACNET_PROPERTY_VALUE *value = NULL; /* value in list */
@@ -373,7 +373,7 @@ int cov_subscribe_decode_service_request(
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint32_t decoded_value = 0; /* for decoding */ 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) { if (apdu_len && data) {
/* tag 0 - subscriberProcessIdentifier */ /* tag 0 - subscriberProcessIdentifier */
@@ -519,7 +519,7 @@ int cov_subscribe_property_decode_service_request(
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint32_t decoded_value = 0; /* for decoding */ 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 */ int property = 0; /* for decoding */
if (apdu_len && data) { if (apdu_len && data) {
+70 -80
View File
@@ -75,7 +75,7 @@ static uint8_t month_days(
if ((month == 2) && is_leap_year(year)) if ((month == 2) && is_leap_year(year))
return 29; return 29;
else if (month >= 1 && month <= 12) else if (month >= 1 && month <= 12)
return (uint8_t)month_days[month]; return (uint8_t) month_days[month];
else else
return 0; return 0;
} }
@@ -435,48 +435,47 @@ int bacapp_encode_context_datetime(
uint8_t tag_number, uint8_t tag_number,
BACNET_DATE_TIME * value) BACNET_DATE_TIME * value)
{ {
int len = 0; int len = 0;
int apdu_len = 0; int apdu_len = 0;
if ( apdu && value ) if (apdu && value) {
{ len = encode_opening_tag(&apdu[apdu_len], tag_number);
len = encode_opening_tag(&apdu[apdu_len], tag_number); apdu_len += len;
apdu_len += len;
len = encode_application_date(&apdu[apdu_len], &value->date); len = encode_application_date(&apdu[apdu_len], &value->date);
apdu_len += len; apdu_len += len;
len = encode_application_time(&apdu[apdu_len], &value->time); len = encode_application_time(&apdu[apdu_len], &value->time);
apdu_len += len; apdu_len += len;
len = encode_closing_tag(&apdu[apdu_len], tag_number); len = encode_closing_tag(&apdu[apdu_len], tag_number);
apdu_len += len; apdu_len += len;
} }
return apdu_len; return apdu_len;
} }
int bacapp_decode_datetime( int bacapp_decode_datetime(
uint8_t * apdu, uint8_t * apdu,
BACNET_DATE_TIME * value) BACNET_DATE_TIME * value)
{ {
int len = 0; int len = 0;
int section_len; int section_len;
if ( -1 == ( section_len = decode_application_date(&apdu[len], &value->date) ) ) if (-1 == (section_len =
{ decode_application_date(&apdu[len], &value->date))) {
return -1; return -1;
} }
len += section_len; len += section_len;
if ( -1 == ( section_len = decode_application_time(&apdu[len], &value->time) ) ) if (-1 == (section_len =
{ decode_application_time(&apdu[len], &value->time))) {
return -1; return -1;
} }
len += section_len; len += section_len;
return len; return len;
} }
int bacapp_decode_context_datetime( int bacapp_decode_context_datetime(
@@ -484,35 +483,27 @@ int bacapp_decode_context_datetime(
uint8_t tag_number, uint8_t tag_number,
BACNET_DATE_TIME * value) BACNET_DATE_TIME * value)
{ {
int apdu_len = 0; int apdu_len = 0;
int len; int len;
if (decode_is_opening_tag_number(&apdu[apdu_len], tag_number)) { if (decode_is_opening_tag_number(&apdu[apdu_len], tag_number)) {
apdu_len++; apdu_len++;
} } else {
else return -1;
{ }
return -1;
}
if ( -1 == (len = bacapp_decode_datetime(&apdu[apdu_len], value))) if (-1 == (len = bacapp_decode_datetime(&apdu[apdu_len], value))) {
{ return -1;
return -1; } else {
} apdu_len += len;
else }
{
apdu_len += len;
}
if (decode_is_closing_tag_number(&apdu[apdu_len], tag_number)) if (decode_is_closing_tag_number(&apdu[apdu_len], tag_number)) {
{ apdu_len++;
apdu_len++; } else {
} return -1;
else }
{ return apdu_len;
return -1;
}
return apdu_len;
} }
@@ -836,36 +827,36 @@ void testBACnetDayOfWeek(
void testDatetimeCodec( void testDatetimeCodec(
Test * pTest) Test * pTest)
{ {
uint8_t apdu[MAX_APDU]; uint8_t apdu[MAX_APDU];
BACNET_DATE_TIME datetimeIn; BACNET_DATE_TIME datetimeIn;
BACNET_DATE_TIME datetimeOut; BACNET_DATE_TIME datetimeOut;
int inLen; int inLen;
int outLen; int outLen;
datetimeIn.date.day = 1; datetimeIn.date.day = 1;
datetimeIn.date.month = 2; datetimeIn.date.month = 2;
datetimeIn.date.wday = 3; datetimeIn.date.wday = 3;
datetimeIn.date.year = 1904; datetimeIn.date.year = 1904;
datetimeIn.time.hour = 5; datetimeIn.time.hour = 5;
datetimeIn.time.min = 6; datetimeIn.time.min = 6;
datetimeIn.time.sec = 7; datetimeIn.time.sec = 7;
datetimeIn.time.hundredths = 8; datetimeIn.time.hundredths = 8;
inLen = bacapp_encode_context_datetime(apdu, 10, &datetimeIn); inLen = bacapp_encode_context_datetime(apdu, 10, &datetimeIn);
outLen = bacapp_decode_context_datetime(apdu, 10, &datetimeOut); 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.day == datetimeOut.date.day);
ct_test(pTest, datetimeIn.date.month == datetimeOut.date.month); ct_test(pTest, datetimeIn.date.month == datetimeOut.date.month);
ct_test(pTest, datetimeIn.date.wday == datetimeOut.date.wday); ct_test(pTest, datetimeIn.date.wday == datetimeOut.date.wday);
ct_test(pTest, datetimeIn.date.year == datetimeOut.date.year); ct_test(pTest, datetimeIn.date.year == datetimeOut.date.year);
ct_test(pTest, datetimeIn.time.hour == datetimeOut.time.hour); ct_test(pTest, datetimeIn.time.hour == datetimeOut.time.hour);
ct_test(pTest, datetimeIn.time.min == datetimeOut.time.min); ct_test(pTest, datetimeIn.time.min == datetimeOut.time.min);
ct_test(pTest, datetimeIn.time.sec == datetimeOut.time.sec); ct_test(pTest, datetimeIn.time.sec == datetimeOut.time.sec);
ct_test(pTest, datetimeIn.time.hundredths == datetimeOut.time.hundredths); ct_test(pTest, datetimeIn.time.hundredths == datetimeOut.time.hundredths);
} }
@@ -909,4 +900,3 @@ int main(
#endif /* TEST_DATE_TIME */ #endif /* TEST_DATE_TIME */
#endif /* TEST */ #endif /* TEST */
+1534 -1387
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -37,7 +37,7 @@
char *filename_remove_path( char *filename_remove_path(
const char *filename_in) const char *filename_in)
{ {
char *filename_out = (char *)filename_in; char *filename_out = (char *) filename_in;
/* allow the device ID to be set */ /* allow the device ID to be set */
if (filename_in) { if (filename_in) {
+1 -1
View File
@@ -80,7 +80,7 @@ int iam_decode_service_request(
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* total length of the apdu, return value */ 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; uint32_t object_instance = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
+1 -1
View File
@@ -77,7 +77,7 @@ int ihave_decode_service_request(
int len = 0; int len = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint16_t decoded_type = 0; /* for decoding */ uint16_t decoded_type = 0; /* for decoding */
if (apdu_len && data) { if (apdu_len && data) {
/* deviceIdentifier */ /* deviceIdentifier */
+10 -11
View File
@@ -36,12 +36,12 @@
/* copy len bytes from src to offset of dest if there is enough space. */ /* 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. */ /* returns 0 if there is not enough space, or the number of bytes copied. */
size_t memcopy( size_t memcopy(
void * dest, void *dest,
void * src, void *src,
size_t offset, /* where in dest to put the data */ size_t offset, /* where in dest to put the data */
size_t len, /* amount of data to copy */ 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 i;
size_t copy_len = 0; size_t copy_len = 0;
char *s1, *s2; char *s1, *s2;
@@ -73,15 +73,14 @@ void test_memcopy(
char big_buffer[480] = ""; char big_buffer[480] = "";
size_t len = 0; size_t len = 0;
len = memcopy(&buffer[0], &data1[0], 0, len = memcopy(&buffer[0], &data1[0], 0, sizeof(data1), sizeof(buffer));
sizeof(data1), sizeof(buffer));
ct_test(pTest, len == sizeof(data1)); ct_test(pTest, len == sizeof(data1));
ct_test(pTest, memcmp(&buffer[0], &data1[0], len) == 0); ct_test(pTest, memcmp(&buffer[0], &data1[0], len) == 0);
len = memcopy(&buffer[0], &data2[0], len, len = memcopy(&buffer[0], &data2[0], len, sizeof(data2), sizeof(buffer));
sizeof(data2), sizeof(buffer));
ct_test(pTest, len == sizeof(data2)); ct_test(pTest, len == sizeof(data2));
len = memcopy(&buffer[0], &big_buffer[0], 1, len =
sizeof(big_buffer), sizeof(buffer)); memcopy(&buffer[0], &big_buffer[0], 1, sizeof(big_buffer),
sizeof(buffer));
ct_test(pTest, len == 0); ct_test(pTest, len == 0);
} }
+3 -3
View File
@@ -81,7 +81,7 @@ int rp_decode_service_request(
unsigned len = 0; unsigned len = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value_type = 0; uint32_t len_value_type = 0;
uint16_t type = 0; /* for decoding */ uint16_t type = 0; /* for decoding */
int property = 0; /* for decoding */ int property = 0; /* for decoding */
uint32_t array_value = 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; uint32_t len_value_type = 0;
int tag_len = 0; /* length of tag decode */ int tag_len = 0; /* length of tag decode */
int len = 0; /* total length of decodes */ int len = 0; /* total length of decodes */
uint16_t object = 0; /* object type */ uint16_t object = 0; /* object type */
int property = 0; /* for decoding */ int property = 0; /* for decoding */
uint32_t array_value = 0; /* for decoding */ uint32_t array_value = 0; /* for decoding */
/* FIXME: check apdu_len against the len during decode */ /* FIXME: check apdu_len against the len during decode */
+16 -13
View File
@@ -110,13 +110,13 @@ int rpm_encode_apdu(
uint8_t * apdu, uint8_t * apdu,
size_t max_apdu, size_t max_apdu,
uint8_t invoke_id, 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 apdu_len = 0; /* total length of the apdu, return value */
int len = 0; /* length of the data */ int len = 0; /* length of the data */
BACNET_READ_ACCESS_DATA *rpm_object; /* current object */ BACNET_READ_ACCESS_DATA *rpm_object; /* current object */
uint8_t apdu_temp[16]; /* temp for data before copy */ uint8_t apdu_temp[16]; /* temp for data before copy */
BACNET_PROPERTY_REFERENCE *rpm_property; /* current property */ BACNET_PROPERTY_REFERENCE *rpm_property; /* current property */
len = rpm_encode_apdu_init(&apdu_temp[0], invoke_id); len = rpm_encode_apdu_init(&apdu_temp[0], invoke_id);
len = memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu); len = memcopy(&apdu[0], &apdu_temp[0], apdu_len, len, max_apdu);
@@ -126,9 +126,9 @@ int rpm_encode_apdu(
apdu_len += len; apdu_len += len;
rpm_object = read_access_data; rpm_object = read_access_data;
while (rpm_object) { while (rpm_object) {
len = encode_context_object_id(&apdu_temp[0], 0, len =
rpm_object->object_type, encode_context_object_id(&apdu_temp[0], 0, rpm_object->object_type,
rpm_object->object_instance); rpm_object->object_instance);
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) { if (len == 0) {
return 0; return 0;
@@ -144,7 +144,8 @@ int rpm_encode_apdu(
rpm_property = rpm_object->listOfProperties; rpm_property = rpm_object->listOfProperties;
while (rpm_property) { while (rpm_property) {
/* stuff as many properties into it as APDU length will allow */ /* 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); rpm_property->propertyIdentifier);
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) { if (len == 0) {
@@ -153,9 +154,11 @@ int rpm_encode_apdu(
apdu_len += len; apdu_len += len;
/* optional array index */ /* optional array index */
if (rpm_property->propertyArrayIndex != BACNET_ARRAY_ALL) { 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); 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) { if (len == 0) {
return 0; return 0;
} }
@@ -183,7 +186,7 @@ int rpm_decode_object_id(
uint32_t * object_instance) uint32_t * object_instance)
{ {
unsigned len = 0; unsigned len = 0;
uint16_t type = 0; /* for decoding */ uint16_t type = 0; /* for decoding */
/* check for value pointers */ /* check for value pointers */
if (apdu && apdu_len && object_type && object_instance) { if (apdu && apdu_len && object_type && object_instance) {
@@ -383,7 +386,7 @@ int rpm_ack_decode_object_id(
uint32_t * object_instance) uint32_t * object_instance)
{ {
unsigned len = 0; unsigned len = 0;
uint16_t type = 0; /* for decoding */ uint16_t type = 0; /* for decoding */
/* check for value pointers */ /* check for value pointers */
if (apdu && apdu_len && object_type && object_instance) { if (apdu && apdu_len && object_type && object_instance) {
+2 -2
View File
@@ -43,8 +43,8 @@
void sbuf_init( void sbuf_init(
STATIC_BUFFER * b, /* static buffer structure */ STATIC_BUFFER * b, /* static buffer structure */
char *data, /* data block */ 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) { if (b) {
b->data = data; b->data = data;
b->size = size; b->size = size;
+301 -283
View File
@@ -1,283 +1,301 @@
/*####COPYRIGHTBEGIN#### /*####COPYRIGHTBEGIN####
------------------------------------------- -------------------------------------------
Copyright (C) 2008 John Minack Copyright (C) 2008 John Minack
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to: along with this program; if not, write to:
The Free Software Foundation, Inc. The Free Software Foundation, Inc.
59 Temple Place - Suite 330 59 Temple Place - Suite 330
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
As a special exception, if other files instantiate templates or As a special exception, if other files instantiate templates or
use macros or inline functions from this file, or you compile use macros or inline functions from this file, or you compile
this file and link it with other works to produce a work based 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 on this file, this file does not by itself cause the resulting
work to be covered by the GNU General Public License. However work to be covered by the GNU General Public License. However
the source code for this file must still be made available in the source code for this file must still be made available in
accordance with section (3) of the GNU General Public License. accordance with section (3) of the GNU General Public License.
This exception does not invalidate any other reasons why a work This exception does not invalidate any other reasons why a work
based on this file might be covered by the GNU General Public based on this file might be covered by the GNU General Public
License. License.
------------------------------------------- -------------------------------------------
####COPYRIGHTEND####*/ ####COPYRIGHTEND####*/
#include "assert.h" #include "assert.h"
#include "timestamp.h" #include "timestamp.h"
int bacapp_encode_context_timestamp( int bacapp_encode_context_timestamp(
uint8_t * apdu, uint8_t * apdu,
uint8_t tag_number, uint8_t tag_number,
BACNET_TIMESTAMP * value) BACNET_TIMESTAMP * value)
{ {
int len = 0; /* length of each encoding */ int len = 0; /* length of each encoding */
int apdu_len = 0; int apdu_len = 0;
if (value && apdu) { if (value && apdu) {
len = encode_opening_tag(&apdu[apdu_len], tag_number); len = encode_opening_tag(&apdu[apdu_len], tag_number);
apdu_len += len; apdu_len += len;
switch(value->tag) switch (value->tag) {
{ case TIME_STAMP_TIME:
case TIME_STAMP_TIME: len =
len = encode_context_time(&apdu[apdu_len], 0, &value->value.time); encode_context_time(&apdu[apdu_len], 0,
break; &value->value.time);
break;
case TIME_STAMP_SEQUENCE:
len = encode_context_unsigned(&apdu[apdu_len], 1, value->value.sequenceNum); case TIME_STAMP_SEQUENCE:
break; len =
encode_context_unsigned(&apdu[apdu_len], 1,
case TIME_STAMP_DATETIME: value->value.sequenceNum);
len = bacapp_encode_context_datetime(&apdu[apdu_len], 2, &value->value.dateTime); break;
break;
case TIME_STAMP_DATETIME:
default: len =
len = 0; bacapp_encode_context_datetime(&apdu[apdu_len], 2,
assert(0); &value->value.dateTime);
break; break;
}
apdu_len += len; default:
len = 0;
len = encode_closing_tag(&apdu[apdu_len], tag_number); assert(0);
apdu_len += len; break;
} }
return apdu_len; apdu_len += len;
}
len = encode_closing_tag(&apdu[apdu_len], tag_number);
int bacapp_decode_context_timestamp( apdu_len += len;
uint8_t * apdu, }
uint8_t tag_number, return apdu_len;
BACNET_TIMESTAMP * value) }
{
int len = 0; int bacapp_decode_context_timestamp(
int section_len; uint8_t * apdu,
uint32_t len_value_type; uint8_t tag_number,
uint32_t sequenceNum; BACNET_TIMESTAMP * value)
{
int len = 0;
if (decode_is_opening_tag_number(&apdu[len], tag_number)) { int section_len;
len++; uint32_t len_value_type;
uint32_t sequenceNum;
section_len =
decode_tag_number_and_value(&apdu[len], &value->tag,
&len_value_type); if (decode_is_opening_tag_number(&apdu[len], tag_number)) {
len++;
if ( -1 == section_len )
{ section_len =
return -1; decode_tag_number_and_value(&apdu[len], &value->tag,
} &len_value_type);
switch( value->tag )
{ if (-1 == section_len) {
case TIME_STAMP_TIME: return -1;
if ( (section_len = decode_context_bacnet_time(&apdu[len], TIME_STAMP_TIME, &value->value.time)) == -1 ) }
{ switch (value->tag) {
return -1; case TIME_STAMP_TIME:
} if ((section_len =
else decode_context_bacnet_time(&apdu[len], TIME_STAMP_TIME,
{ &value->value.time)) == -1) {
len += section_len; return -1;
} } else {
break; len += section_len;
}
case TIME_STAMP_SEQUENCE: break;
if ( (section_len = decode_context_unsigned(&apdu[len], TIME_STAMP_SEQUENCE, &sequenceNum)) == -1 )
{ case TIME_STAMP_SEQUENCE:
return -1; if ((section_len =
} decode_context_unsigned(&apdu[len],
else TIME_STAMP_SEQUENCE, &sequenceNum)) == -1) {
{ return -1;
if ( sequenceNum <= 0xffff ) } else {
{ if (sequenceNum <= 0xffff) {
len += section_len; len += section_len;
value->value.sequenceNum = (uint16_t)sequenceNum; value->value.sequenceNum = (uint16_t) sequenceNum;
} } else {
else return -1;
{ }
return -1; }
} break;
}
break; case TIME_STAMP_DATETIME:
if ((section_len =
case TIME_STAMP_DATETIME: bacapp_decode_context_datetime(&apdu[len],
if ( (section_len = bacapp_decode_context_datetime(&apdu[len], TIME_STAMP_DATETIME, &value->value.dateTime)) == -1 ) TIME_STAMP_DATETIME,
{ &value->value.dateTime)) == -1) {
return -1; return -1;
} } else {
else len += section_len;
{ }
len += section_len; break;
}
break; default:
return -1;
default: }
return -1; if (decode_is_closing_tag_number(&apdu[len], tag_number)) {
} len++;
if (decode_is_closing_tag_number(&apdu[len], tag_number)) { } else {
len++; return -1;
} }
else }
{ return len;
return -1; }
}
} #ifdef TEST
return len;
} #include <assert.h>
#include <string.h>
#ifdef TEST #include "ctest.h"
#include <assert.h>
#include <string.h> void testTimestampSequence(
#include "ctest.h" Test * pTest)
{
BACNET_TIMESTAMP testTimestampIn;
void testTimestampSequence( BACNET_TIMESTAMP testTimestampOut;
Test * pTest) uint8_t buffer[MAX_APDU];
{ int inLen;
BACNET_TIMESTAMP testTimestampIn; int outLen;
BACNET_TIMESTAMP testTimestampOut;
uint8_t buffer[MAX_APDU]; testTimestampIn.tag = TIME_STAMP_SEQUENCE;
int inLen; testTimestampIn.value.sequenceNum = 0x1234;
int outLen;
memset(&testTimestampOut, 0, sizeof(testTimestampOut));
testTimestampIn.tag = TIME_STAMP_SEQUENCE;
testTimestampIn.value.sequenceNum = 0x1234;
inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn);
memset(&testTimestampOut, 0, sizeof(testTimestampOut)); outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut);
ct_test(pTest, inLen == outLen);
inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn); ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag);
outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); ct_test(pTest,
testTimestampIn.value.sequenceNum ==
ct_test(pTest, inLen == outLen); testTimestampOut.value.sequenceNum);
ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); }
ct_test(pTest, testTimestampIn.value.sequenceNum == testTimestampOut.value.sequenceNum);
} void testTimestampTime(
Test * pTest)
void testTimestampTime( {
Test * pTest) BACNET_TIMESTAMP testTimestampIn;
{ BACNET_TIMESTAMP testTimestampOut;
BACNET_TIMESTAMP testTimestampIn; uint8_t buffer[MAX_APDU];
BACNET_TIMESTAMP testTimestampOut; int inLen;
uint8_t buffer[MAX_APDU]; int outLen;
int inLen;
int outLen; testTimestampIn.tag = TIME_STAMP_TIME;
testTimestampIn.value.time.hour = 1;
testTimestampIn.tag = TIME_STAMP_TIME; testTimestampIn.value.time.min = 2;
testTimestampIn.value.time.hour = 1; testTimestampIn.value.time.sec = 3;
testTimestampIn.value.time.min = 2; testTimestampIn.value.time.hundredths = 4;
testTimestampIn.value.time.sec = 3;
testTimestampIn.value.time.hundredths = 4; memset(&testTimestampOut, 0, sizeof(testTimestampOut));
memset(&testTimestampOut, 0, sizeof(testTimestampOut));
inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn);
outLen = bacapp_decode_context_timestamp(buffer, 2, &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, inLen == outLen); ct_test(pTest,
ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); testTimestampIn.value.time.hour == testTimestampOut.value.time.hour);
ct_test(pTest, testTimestampIn.value.time.hour == testTimestampOut.value.time.hour); ct_test(pTest,
ct_test(pTest, testTimestampIn.value.time.min == testTimestampOut.value.time.min); testTimestampIn.value.time.min == testTimestampOut.value.time.min);
ct_test(pTest, testTimestampIn.value.time.sec == testTimestampOut.value.time.sec); ct_test(pTest,
ct_test(pTest, testTimestampIn.value.time.hundredths == testTimestampOut.value.time.hundredths); testTimestampIn.value.time.sec == testTimestampOut.value.time.sec);
} ct_test(pTest,
testTimestampIn.value.time.hundredths ==
void testTimestampTimeDate( testTimestampOut.value.time.hundredths);
Test * pTest) }
{
BACNET_TIMESTAMP testTimestampIn; void testTimestampTimeDate(
BACNET_TIMESTAMP testTimestampOut; Test * pTest)
uint8_t buffer[MAX_APDU]; {
int inLen; BACNET_TIMESTAMP testTimestampIn;
int outLen; BACNET_TIMESTAMP testTimestampOut;
uint8_t buffer[MAX_APDU];
testTimestampIn.tag = TIME_STAMP_DATETIME; int inLen;
testTimestampIn.value.dateTime.time.hour = 1; int outLen;
testTimestampIn.value.dateTime.time.min = 2;
testTimestampIn.value.dateTime.time.sec = 3; testTimestampIn.tag = TIME_STAMP_DATETIME;
testTimestampIn.value.dateTime.time.hundredths = 4; testTimestampIn.value.dateTime.time.hour = 1;
testTimestampIn.value.dateTime.time.min = 2;
testTimestampIn.value.dateTime.date.year = 1901; testTimestampIn.value.dateTime.time.sec = 3;
testTimestampIn.value.dateTime.date.month = 1; testTimestampIn.value.dateTime.time.hundredths = 4;
testTimestampIn.value.dateTime.date.wday = 2;
testTimestampIn.value.dateTime.date.day = 3; testTimestampIn.value.dateTime.date.year = 1901;
testTimestampIn.value.dateTime.date.month = 1;
memset(&testTimestampOut, 0, sizeof(testTimestampOut)); testTimestampIn.value.dateTime.date.wday = 2;
testTimestampIn.value.dateTime.date.day = 3;
inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn);
outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut); memset(&testTimestampOut, 0, sizeof(testTimestampOut));
ct_test(pTest, inLen == outLen); inLen = bacapp_encode_context_timestamp(buffer, 2, &testTimestampIn);
ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag); outLen = bacapp_decode_context_timestamp(buffer, 2, &testTimestampOut);
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, inLen == outLen);
ct_test(pTest, testTimestampIn.value.dateTime.time.sec == testTimestampOut.value.dateTime.time.sec); ct_test(pTest, testTimestampIn.tag == testTimestampOut.tag);
ct_test(pTest, testTimestampIn.value.dateTime.time.hundredths == testTimestampOut.value.dateTime.time.hundredths); ct_test(pTest,
testTimestampIn.value.dateTime.time.hour ==
ct_test(pTest, testTimestampIn.value.dateTime.date.year == testTimestampOut.value.dateTime.date.year); testTimestampOut.value.dateTime.time.hour);
ct_test(pTest, testTimestampIn.value.dateTime.date.month == testTimestampOut.value.dateTime.date.month); ct_test(pTest,
ct_test(pTest, testTimestampIn.value.dateTime.date.wday == testTimestampOut.value.dateTime.date.wday); testTimestampIn.value.dateTime.time.min ==
ct_test(pTest, testTimestampIn.value.dateTime.date.day == testTimestampOut.value.dateTime.date.day); testTimestampOut.value.dateTime.time.min);
ct_test(pTest,
} testTimestampIn.value.dateTime.time.sec ==
testTimestampOut.value.dateTime.time.sec);
#ifdef TEST_TIME_STAMP ct_test(pTest,
testTimestampIn.value.dateTime.time.hundredths ==
int main( testTimestampOut.value.dateTime.time.hundredths);
void)
{ ct_test(pTest,
Test *pTest; testTimestampIn.value.dateTime.date.year ==
bool rc; testTimestampOut.value.dateTime.date.year);
ct_test(pTest,
pTest = ct_create("BACnet Time Stamp", NULL); testTimestampIn.value.dateTime.date.month ==
/* individual tests */ testTimestampOut.value.dateTime.date.month);
rc = ct_addTestFunction(pTest, testTimestampSequence); ct_test(pTest,
assert(rc); testTimestampIn.value.dateTime.date.wday ==
testTimestampOut.value.dateTime.date.wday);
rc = ct_addTestFunction(pTest, testTimestampTime); ct_test(pTest,
assert(rc); testTimestampIn.value.dateTime.date.day ==
testTimestampOut.value.dateTime.date.day);
rc = ct_addTestFunction(pTest, testTimestampTimeDate);
assert(rc); }
ct_setStream(pTest, stdout); #ifdef TEST_TIME_STAMP
ct_run(pTest);
(void) ct_report(pTest); int main(
ct_destroy(pTest); void)
{
return 0; Test *pTest;
} bool rc;
#endif // TEST_TIME_STAMP pTest = ct_create("BACnet Time Stamp", NULL);
#endif // TEST /* 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
+1 -1
View File
@@ -88,7 +88,7 @@ int whohas_decode_service_request(
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value = 0; uint32_t len_value = 0;
uint32_t decoded_value = 0; /* for decoding */ 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) { if (apdu_len && data) {
/* optional limits - must be used as a pair */ /* optional limits - must be used as a pair */
+1 -1
View File
@@ -99,7 +99,7 @@ int wp_decode_service_request(
int tag_len = 0; int tag_len = 0;
uint8_t tag_number = 0; uint8_t tag_number = 0;
uint32_t len_value_type = 0; uint32_t len_value_type = 0;
uint16_t type = 0; /* for decoding */ uint16_t type = 0; /* for decoding */
int property = 0; /* for decoding */ int property = 0; /* for decoding */
uint32_t unsigned_value = 0; uint32_t unsigned_value = 0;
int i = 0; /* loop counter */ int i = 0; /* loop counter */