diff --git a/bacnet-stack/demo/dcc/Makefile b/bacnet-stack/demo/dcc/Makefile
index 3060b9d3..1ddc8981 100644
--- a/bacnet-stack/demo/dcc/Makefile
+++ b/bacnet-stack/demo/dcc/Makefile
@@ -8,7 +8,8 @@ TARGET = bacdcc
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/dcc/main.c b/bacnet-stack/demo/dcc/main.c
index d2266801..cf1f57bd 100644
--- a/bacnet-stack/demo/dcc/main.c
+++ b/bacnet-stack/demo/dcc/main.c
@@ -51,13 +51,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -123,7 +116,7 @@ void MyDeviceCommunicationControlSimpleAckHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/dcc/makefile.b32 b/bacnet-stack/demo/dcc/makefile.b32
index b5a28e87..9baddb54 100644
--- a/bacnet-stack/demo/dcc/makefile.b32
+++ b/bacnet-stack/demo/dcc/makefile.b32
@@ -12,7 +12,7 @@ BORLAND_DIR_Not_Defined:
!endif
# target
-PRODUCT = bacdcc
+PRODUCT = bacdcc ..\handler\device-client.c
PRODUCT_EXE = $(PRODUCT).exe
# tools
@@ -42,7 +42,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/epics/bacepics.cbp b/bacnet-stack/demo/epics/bacepics.cbp
index db1331bb..3733fdeb 100644
--- a/bacnet-stack/demo/epics/bacepics.cbp
+++ b/bacnet-stack/demo/epics/bacepics.cbp
@@ -48,6 +48,9 @@
+
+
+
diff --git a/bacnet-stack/demo/epics/main.c b/bacnet-stack/demo/epics/main.c
index 4e5c3d0a..f1070883 100644
--- a/bacnet-stack/demo/epics/main.c
+++ b/bacnet-stack/demo/epics/main.c
@@ -23,7 +23,7 @@
*
*********************************************************************/
-/** @file epics/bacepics.c Command line tool to build a full VTS3 EPICS file,
+/** @file epics/bacepics.c Command line tool to build a full VTS3 EPICS file,
* including the heading information. */
#include
@@ -69,13 +69,6 @@
* 3) Postpends the tail information to complete the EPICS file.
*/
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -299,7 +292,7 @@ void MyReadPropertyMultipleAckHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
#if BAC_ROUTING
uint32_t Object_Instance;
@@ -335,12 +328,12 @@ static void Init_Service_Handlers(
}
-/** Determine if this is a writable property, and, if so,
+/** Determine if this is a writable property, and, if so,
* note that in the EPICS output.
- * This function may need a lot of customization for different implementations;
+ * This function may need a lot of customization for different implementations;
* but as a starting point, take the Device object-instance and -name as writable.
- * For the EPICS output to VTS3, printing 'w' after the property is sufficient,
- * but to aid readability for human eyes, printing as "Writable".
+ * For the EPICS output to VTS3, printing 'w' after the property is sufficient,
+ * but to aid readability for human eyes, printing as "Writable".
*
* @param object_type [in] The BACnet Object type of this object.
* @note object_instance [in] The ID number for this object.
@@ -348,7 +341,7 @@ static void Init_Service_Handlers(
* Value, and Error information.
*/
void CheckIsWritableProperty(
- BACNET_OBJECT_TYPE object_type,
+ BACNET_OBJECT_TYPE object_type,
/* uint32_t object_instance, */
BACNET_PROPERTY_REFERENCE * rpm_property)
{
@@ -639,11 +632,11 @@ void PrintReadPropertyData(
break;
default:
- /* First, if this is a date type, it needs a different format
+ /* First, if this is a date type, it needs a different format
* for VTS, so pretty print it. */
if (ShowValues && (object_value.value->tag == BACNET_APPLICATION_TAG_DATE))
{
- /* This would be PROP_LOCAL_DATE, or OBJECT_DATETIME_VALUE,
+ /* This would be PROP_LOCAL_DATE, or OBJECT_DATETIME_VALUE,
* or OBJECT_DATE_VALUE */
PrettyPrintPropertyValue(stdout, &object_value);
} else {
@@ -684,7 +677,7 @@ void PrintReadPropertyData(
/* Closing brace for this multi-valued array */
fprintf(stdout, " }");
}
- CheckIsWritableProperty(object_type, /* object_instance, */
+ CheckIsWritableProperty(object_type, /* object_instance, */
rpm_property);
fprintf(stdout, "\r\n");
}
@@ -714,7 +707,7 @@ void Print_Property_Identifier(
/** Build a list of properties to request with RPM.
* @param rpm_object [out] The structure holding our linked list of properties to request.
- * @param propList [in] Simple list of properties (ptr to array), terminated with -1
+ * @param propList [in] Simple list of properties (ptr to array), terminated with -1
*/
void BuildPropRequest( BACNET_READ_ACCESS_DATA *rpm_object, int32_t *propList )
{
@@ -870,8 +863,8 @@ EPICS_STATES ProcessRPMData(
free(old_value);
}
} else if ( myState == GET_HEADING_RESPONSE ) {
- InitIdValues[i++] = rpm_property->value;
- /* copy this pointer.
+ InitIdValues[i++] = rpm_property->value;
+ /* copy this pointer.
* On error, the pointer will be null
* We won't free these values*/
} else {
@@ -892,7 +885,7 @@ EPICS_STATES ProcessRPMData(
/* Now determine the next state */
if ( myState == GET_HEADING_RESPONSE )
- nextState = PRINT_HEADING;
+ nextState = PRINT_HEADING;
/* press ahead with or without the data */
else if (bSuccess && (myState == GET_ALL_RESPONSE))
nextState = NEXT_OBJECT;
@@ -1038,7 +1031,7 @@ void PrintHeading( )
char *relation = "for"; /* Text for Gateways */
if ( Target_Address.net != 0 )
relation = "provided by"; /* Text for child routed devices */
-
+
printf("PICS 0\r\n");
printf("BACnet Protocol Implementation Conformance Statement\r\n\r\n");
@@ -1046,14 +1039,14 @@ void PrintHeading( )
printf("-- BACnet/IP Interface for BACnet-stack Devices\r\n");
printf("-- http://sourceforge.net/projects/bacnet/ \r\n");
printf("-- \r\n-- \r\n\r\n");
-/* InitIdValues , , , */
-
+/* InitIdValues , , , */
+
value = InitIdValues[INIT_VENDOR_NAME];
if ( value != NULL )
printf("Vendor Name: \"%s\"\r\n", characterstring_value( &value->type.Character_String) );
else
printf("Vendor Name: \"bacnet-stack\"\r\n");
-
+
value = InitIdValues[INIT_MODEL_NAME];
/* Best we can do with Product Name and Model Number is use the same text */
if ( value != NULL ) {
@@ -1079,11 +1072,11 @@ void PrintHeading( )
printf(" DM-DOB-B\r\n");
printf(" DM-DCC-B\r\n");
printf(" DM-RD-B\r\n");
-#ifdef BAC_ROUTING
+#ifdef BAC_ROUTING
/* Next line only for the gateway (ie, if not addressing a subNet) */
if ( Target_Address.net == 0 )
printf(" NM-RC-B\r\n");
-#endif
+#endif
printf("}\r\n\r\n");
/* You might add some of:
* -- DS-COV-A DS-COV-B
@@ -1104,7 +1097,7 @@ void PrintHeading( )
printf(" Who-Is Initiate Execute\r\n");
printf(" I-Am Initiate\r\n");
printf(" ReinitializeDevice Execute\r\n");
-#ifdef BAC_ROUTING
+#ifdef BAC_ROUTING
if ( Target_Address.net == 0 )
{
printf(" -- Note: The following Routing Services are Supported:\r\n");
@@ -1113,7 +1106,7 @@ void PrintHeading( )
printf(" -- Initialize-Routing-Table Execute\r\n");
printf(" -- Initialize-Routing-Table-Ack Initiate\r\n");
}
-#endif
+#endif
printf("}\r\n\r\n");
/* You might want to add some of:
* -- AcknowledgeAlarm Initiate Execute
@@ -1132,10 +1125,10 @@ void PrintHeading( )
printf("Standard Object-Types Supported:\r\n");
printf("{\r\n");
value = InitIdValues[INIT_OBJ_TYPES];
- /* We have to process this bit string and determine which Object Types we have,
+ /* We have to process this bit string and determine which Object Types we have,
* and show them
*/
- if ( ( value != NULL ) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) )
+ if ( ( value != NULL ) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) )
{
int i, len = bitstring_bits_used(&value->type.Bit_String);
for ( i = 0; i < len; i++) {
@@ -1148,8 +1141,8 @@ void PrintHeading( )
printf(" Binary Input\r\n");
printf(" Binary Value\r\n");
printf(" Device\r\n");
- printf(" Multi-state Input\r\n");
- printf(" Multi-state Value\r\n");
+ printf(" Multi-state Input\r\n");
+ printf(" Multi-state Value\r\n");
printf(" Structured View\r\n");
printf(" Characterstring Value\r\n");
printf(" Datetime Value\r\n");
@@ -1163,7 +1156,7 @@ void PrintHeading( )
* -- Multi-state Output
* -- Trend Log Createable Deleteable
* -- Load Control
- * -- Bitstring Value
+ * -- Bitstring Value
* -- Date Pattern Value
* -- Date Value
* -- Datetime Pattern Value
@@ -1172,7 +1165,7 @@ void PrintHeading( )
* -- Time Pattern Value
* -- Time Value
*/
-
+
printf("Data Link Layer Option:\r\n");
printf("{\r\n");
printf(" BACnet/IP, 'DIX' Ethernet\r\n");
@@ -1187,8 +1180,8 @@ void PrintHeading( )
printf("{\r\n");
printf(" Maximum APDU size in octets: 1476\r\n");
printf("}\r\n\r\n");
-
- printf("List of Objects in Test Device:\r\n");
+
+ printf("List of Objects in Test Device:\r\n");
/* Print Opening brace, then kick off the Device Object */
printf("{\r\n");
printf(" {\r\n"); /* And opening brace for the first object */
@@ -1342,7 +1335,7 @@ int main(
myState = GET_HEADING_INFO;
}
break;
-
+
case GET_HEADING_INFO:
last_seconds = current_seconds;
StartNextObject(rpm_object, &myObject);
@@ -1414,7 +1407,7 @@ int main(
elapsed_seconds = 0;
invoke_id = 0;
if ( myState == GET_HEADING_RESPONSE )
- myState = PRINT_HEADING;
+ myState = PRINT_HEADING;
/* just press ahead without the data */
else if (Error_Detected) {
/* The normal case for Device Object */
@@ -1442,7 +1435,7 @@ int main(
invoke_id = 0;
elapsed_seconds = 0;
if ( myState == GET_HEADING_RESPONSE )
- myState = PRINT_HEADING;
+ myState = PRINT_HEADING;
/* just press ahead without the data */
else
myState = GET_ALL_REQUEST; /* Let's try again */
@@ -1451,7 +1444,7 @@ int main(
elapsed_seconds = 0;
invoke_id = 0;
if ( myState == GET_HEADING_RESPONSE )
- myState = PRINT_HEADING;
+ myState = PRINT_HEADING;
/* just press ahead without the data */
else
myState = NEXT_OBJECT; /* Give up and move on to the next. */
diff --git a/bacnet-stack/demo/gateway/main.c b/bacnet-stack/demo/gateway/main.c
index 68376abc..8e97c566 100644
--- a/bacnet-stack/demo/gateway/main.c
+++ b/bacnet-stack/demo/gateway/main.c
@@ -59,20 +59,6 @@
#ifdef BACNET_TEST_VMAC
#include "vmac.h"
#endif
-#include "ai.h"
-#include "ao.h"
-#include "av.h"
-#include "bi.h"
-#include "bo.h"
-#include "bv.h"
-#include "lc.h"
-#include "lsp.h"
-#include "mso.h"
-#include "ms-input.h"
-#include "trendlog.h"
-#if defined(BACFILE)
-#include "bacfile.h"
-#endif
/** @file gateway/main.c Example virtual gateway application using the BACnet Stack. */
@@ -139,10 +125,10 @@ static void Init_Service_Handlers(
Routing_Device_Init(first_object_instance);
/* we need to handle who-is to support dynamic device binding
- * For the gateway, we will use the unicast variety so we can
- * get back through switches to different subnets.
+ * For the gateway, we will use the unicast variety so we can
+ * get back through switches to different subnets.
* Don't need the routed versions, since the npdu handler calls
- * each device in turn.
+ * each device in turn.
*/
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is_unicast);
diff --git a/bacnet-stack/demo/handler/h_cov.c b/bacnet-stack/demo/handler/h_cov.c
index 56f054ab..7a498b90 100644
--- a/bacnet-stack/demo/handler/h_cov.c
+++ b/bacnet-stack/demo/handler/h_cov.c
@@ -53,6 +53,7 @@ typedef struct BACnet_COV_Subscription {
uint32_t subscriberProcessIdentifier;
BACNET_OBJECT_ID monitoredObjectIdentifier;
bool issueConfirmedNotifications; /* optional */
+ uint8_t invokeID; /* for confirmed COV */
uint32_t lifetime; /* optional */
bool send_requested;
} BACNET_COV_SUBSCRIPTION;
@@ -223,6 +224,7 @@ void handler_cov_init(
OBJECT_ANALOG_INPUT;
COV_Subscriptions[index].monitoredObjectIdentifier.instance = 0;
COV_Subscriptions[index].issueConfirmedNotifications = false;
+ COV_Subscriptions[index].invokeID = 0;
COV_Subscriptions[index].lifetime = 0;
COV_Subscriptions[index].send_requested = false;
}
@@ -261,6 +263,10 @@ static bool cov_list_subscribe(
COV_Subscriptions[index].lifetime = cov_data->lifetime;
COV_Subscriptions[index].send_requested = true;
}
+ if (COV_Subscriptions[index].invokeID) {
+ tsm_free_invoke_id(COV_Subscriptions[index].invokeID);
+ COV_Subscriptions[index].invokeID = 0;
+ }
break;
}
} else {
@@ -283,6 +289,7 @@ static bool cov_list_subscribe(
cov_data->subscriberProcessIdentifier;
COV_Subscriptions[index].issueConfirmedNotifications =
cov_data->issueConfirmedNotifications;
+ COV_Subscriptions[index].invokeID = 0;
COV_Subscriptions[index].lifetime = cov_data->lifetime;
COV_Subscriptions[index].send_requested = true;
} else if (!existing_entry) {
@@ -335,6 +342,7 @@ static bool cov_send_request(
if (cov_subscription->issueConfirmedNotifications) {
invoke_id = tsm_next_free_invokeID();
if (invoke_id) {
+ cov_subscription->invokeID = invoke_id;
len =
ccov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, &cov_data);
@@ -385,19 +393,13 @@ static bool cov_send_request(
*
* @param elapsed_seconds [in] How many seconds have elapsed since last called.
*/
-void handler_cov_task(
+void handler_cov_timer_seconds(
uint32_t elapsed_seconds)
{
- int index = 0, index2 = 0;
+ int index = 0;
uint32_t lifetime_seconds = 0;
- uint16_t object_type = 0, object_type2 = 0;
- uint32_t object_instance = 0, object_instance2 = 0;
- bool status = false;
- BACNET_PROPERTY_VALUE value_list[2];
- value_list[0].next = &value_list[1];
- value_list[1].next = NULL;
- /* existing? - match Object ID and Process ID */
+ /* handle the subscription timeouts */
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
if (COV_Subscriptions[index].valid) {
/* handle timeouts */
@@ -413,44 +415,102 @@ void handler_cov_task(
}
if (COV_Subscriptions[index].lifetime == 0) {
COV_Subscriptions[index].valid = false;
+ if (COV_Subscriptions[index].issueConfirmedNotifications) {
+ if (COV_Subscriptions[index].invokeID) {
+ tsm_free_invoke_id(COV_Subscriptions[index].invokeID);
+ COV_Subscriptions[index].invokeID = 0;
+ }
+ }
}
- /* handle COV notifications */
- object_type =
+ }
+ }
+}
+
+void handler_cov_task(void)
+{
+ int index = 0;
+ BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
+ uint32_t object_instance = 0;
+ bool status = false;
+ BACNET_PROPERTY_VALUE value_list[2];
+
+ /* configure the linked list for the two properties */
+ value_list[0].next = &value_list[1];
+ value_list[1].next = NULL;
+ /* mark any subscriptions where the value has changed */
+ for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
+ if (COV_Subscriptions[index].valid) {
+ object_type = (BACNET_OBJECT_TYPE)
COV_Subscriptions[index].monitoredObjectIdentifier.type;
object_instance =
COV_Subscriptions[index].monitoredObjectIdentifier.instance;
- status =
- Device_Encode_Value_List(object_type, object_instance,
- &value_list[0]);
+ status = Device_COV(object_type, object_instance);
if (status) {
COV_Subscriptions[index].send_requested = true;
}
- if (COV_Subscriptions[index].send_requested) {
- cov_send_request(&COV_Subscriptions[index], &value_list[0]);
- COV_Subscriptions[index].send_requested = false;
+ }
+ }
+ /* clear the COV flag after checking all subscriptions (dup objects) */
+ for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
+ if (COV_Subscriptions[index].valid) {
+ object_type = (BACNET_OBJECT_TYPE)
+ COV_Subscriptions[index].monitoredObjectIdentifier.type;
+ object_instance =
+ COV_Subscriptions[index].monitoredObjectIdentifier.instance;
+ status = Device_COV(object_type, object_instance);
+ if (status) {
+ Device_COV_Clear(object_type, object_instance);
}
- if (status && ((index + 1) < MAX_COV_SUBCRIPTIONS)) {
- /* if more than one subscription for this object instance */
- for (index2 = index + 1; index2 < MAX_COV_SUBCRIPTIONS;
- index2++) {
- object_type2 =
- COV_Subscriptions[index2].monitoredObjectIdentifier.
- type;
- object_instance2 =
- COV_Subscriptions[index2].monitoredObjectIdentifier.
- instance;
- if ((COV_Subscriptions[index].lifetime) &&
- (COV_Subscriptions[index].valid) &&
- (object_type == object_type2) &&
- (object_instance == object_instance2)) {
- cov_send_request(&COV_Subscriptions[index2],
- &value_list[0]);
- COV_Subscriptions[index2].send_requested = false;
+ }
+ }
+ /* confirmed notification house keeping */
+ for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
+ if (COV_Subscriptions[index].valid) {
+ if (COV_Subscriptions[index].issueConfirmedNotifications) {
+ if (COV_Subscriptions[index].invokeID) {
+ if (tsm_invoke_id_free(COV_Subscriptions[index].invokeID)) {
+ COV_Subscriptions[index].invokeID = 0;
+ } else if (tsm_invoke_id_failed(
+ COV_Subscriptions[index].invokeID)) {
+ tsm_free_invoke_id(COV_Subscriptions[index].invokeID);
+ COV_Subscriptions[index].invokeID = 0;
}
}
}
}
}
+ /* send any COVs that are requested */
+ for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
+ if (COV_Subscriptions[index].valid) {
+ if (COV_Subscriptions[index].send_requested) {
+ if (COV_Subscriptions[index].issueConfirmedNotifications) {
+ if (COV_Subscriptions[index].invokeID != 0) {
+ /* already sending - be patient! */
+ continue;
+ }
+ if (!tsm_transaction_available()) {
+ /* no free transactions - be patient! */
+ continue;
+ }
+ }
+ object_type = (BACNET_OBJECT_TYPE)
+ COV_Subscriptions[index].monitoredObjectIdentifier.type;
+ object_instance =
+ COV_Subscriptions[index].monitoredObjectIdentifier.instance;
+ (void)Device_Encode_Value_List(object_type, object_instance,
+ &value_list[0]);
+ status = cov_send_request(
+ &COV_Subscriptions[index],
+ &value_list[0]);
+ if (status) {
+ COV_Subscriptions[index].send_requested = false;
+ } else {
+ /* must be out of PDU space - stop for now */
+ break;
+ }
+ }
+ }
+ }
}
static bool cov_subscribe(
@@ -460,10 +520,10 @@ static bool cov_subscribe(
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
- uint16_t object_type = 0;
+ BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
uint32_t object_instance = 0;
- object_type = cov_data->monitoredObjectIdentifier.type;
+ object_type = (BACNET_OBJECT_TYPE)cov_data->monitoredObjectIdentifier.type;
object_instance = cov_data->monitoredObjectIdentifier.instance;
status = Device_Valid_Object_Id(object_type, object_instance);
if (status) {
@@ -518,7 +578,7 @@ void handler_cov_subscribe(
bool error = false;
/* initialize a common abort code */
- cov_data.error_code = ABORT_REASON_SEGMENTATION_NOT_SUPPORTED;
+ cov_data.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
diff --git a/bacnet-stack/demo/handler/h_upt.c b/bacnet-stack/demo/handler/h_upt.c
index 8ce97311..adb8bb71 100644
--- a/bacnet-stack/demo/handler/h_upt.c
+++ b/bacnet-stack/demo/handler/h_upt.c
@@ -45,20 +45,66 @@ void handler_unconfirmed_private_transfer(
BACNET_ADDRESS * src)
{
BACNET_PRIVATE_TRANSFER_DATA private_data;
+ BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
+ BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
int len = 0;
+ uint8_t *application_data;
+ int application_data_len;
+ bool first_value = true;
+ bool print_brace = false;
#if PRINT_ENABLED
fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n");
#endif
- (void) src;
- len =
- ptransfer_decode_service_request(service_request, service_len,
- &private_data);
+ len = ptransfer_decode_service_request(
+ service_request, service_len, &private_data);
if (len >= 0) {
#if PRINT_ENABLED
- fprintf(stderr,
- "UnconfirmedPrivateTransfer: " "vendorID=%u serviceNumber=%u\n",
- private_data.vendorID, private_data.serviceNumber);
+ printf("PrivateTransfer:vendorID=%u\r\n",
+ (unsigned)private_data.vendorID);
+ printf("PrivateTransfer:serviceNumber=%lu\r\n",
+ (unsigned long)private_data.serviceNumber);
+#endif
+ application_data = private_data.serviceParameters;
+ application_data_len = private_data.serviceParametersLen;
+ for (;;) {
+ len =
+ bacapp_decode_application_data(application_data,
+ (uint8_t) application_data_len, &value);
+ if (first_value && (len < application_data_len)) {
+ first_value = false;
+#if PRINT_ENABLED
+ fprintf(stdout, "{");
+#endif
+ print_brace = true;
+ }
+ /* private transfer doesn't provide any clues */
+ object_value.object_type = MAX_BACNET_OBJECT_TYPE;
+ object_value.object_instance = BACNET_MAX_INSTANCE;
+ object_value.object_property = MAX_BACNET_PROPERTY_ID;
+ object_value.array_index = BACNET_ARRAY_ALL;
+ object_value.value = &value;
+ bacapp_print_value(stdout, &object_value);
+ if (len > 0) {
+ if (len < application_data_len) {
+ application_data += len;
+ application_data_len -= len;
+ /* there's more! */
+#if PRINT_ENABLED
+ fprintf(stdout, ",");
+#endif
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+#if PRINT_ENABLED
+ if (print_brace)
+ fprintf(stdout, "}");
+ fprintf(stdout, "\r\n");
#endif
}
}
+
diff --git a/bacnet-stack/demo/iamrouter/Makefile b/bacnet-stack/demo/iamrouter/Makefile
index a20b6fb2..5b342c1d 100644
--- a/bacnet-stack/demo/iamrouter/Makefile
+++ b/bacnet-stack/demo/iamrouter/Makefile
@@ -8,7 +8,8 @@ TARGET = baciamr
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/iamrouter/main.c b/bacnet-stack/demo/iamrouter/main.c
index 7d8d3853..716c402a 100644
--- a/bacnet-stack/demo/iamrouter/main.c
+++ b/bacnet-stack/demo/iamrouter/main.c
@@ -46,15 +46,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-};
-
-/* buffer used for receive */
-/* static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; */
-
/* global variables used in this file */
#define MAX_ROUTER_DNETS 64
static int Target_Router_Networks[MAX_ROUTER_DNETS] = { -1 };
@@ -90,7 +81,7 @@ void MyRejectHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/iamrouter/makefile.b32 b/bacnet-stack/demo/iamrouter/makefile.b32
index 2f09819f..72cc4b15 100644
--- a/bacnet-stack/demo/iamrouter/makefile.b32
+++ b/bacnet-stack/demo/iamrouter/makefile.b32
@@ -42,7 +42,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/initrouter/Makefile b/bacnet-stack/demo/initrouter/Makefile
index 8bf952ce..e48e8b16 100644
--- a/bacnet-stack/demo/initrouter/Makefile
+++ b/bacnet-stack/demo/initrouter/Makefile
@@ -8,7 +8,8 @@ TARGET = bacinitr
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/initrouter/main.c b/bacnet-stack/demo/initrouter/main.c
index 6205788d..03e1b10d 100644
--- a/bacnet-stack/demo/initrouter/main.c
+++ b/bacnet-stack/demo/initrouter/main.c
@@ -48,12 +48,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -220,7 +214,7 @@ static void My_NPDU_Handler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/initrouter/makefile.b32 b/bacnet-stack/demo/initrouter/makefile.b32
index 52839306..8c7b7871 100644
--- a/bacnet-stack/demo/initrouter/makefile.b32
+++ b/bacnet-stack/demo/initrouter/makefile.b32
@@ -42,7 +42,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/object/ai.h b/bacnet-stack/demo/object/ai.h
index 23daf740..0bd3c4fb 100644
--- a/bacnet-stack/demo/object/ai.h
+++ b/bacnet-stack/demo/object/ai.h
@@ -143,9 +143,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define ANALOG_INPUT_OBJ_FUNCTIONS \
- OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count, \
- Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance, \
- Analog_Input_Object_Name, Analog_Input_Read_Property, NULL, \
- Analog_Input_Property_Lists, NULL, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/ao.h b/bacnet-stack/demo/object/ao.h
index b2c2bf9b..688120a8 100644
--- a/bacnet-stack/demo/object/ao.h
+++ b/bacnet-stack/demo/object/ao.h
@@ -100,10 +100,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define ANALOG_OUTPUT_OBJ_FUNCTIONS \
- OBJECT_ANALOG_OUTPUT, Analog_Output_Init, Analog_Output_Count, \
- Analog_Output_Index_To_Instance, Analog_Output_Valid_Instance, \
- Analog_Output_Object_Name, Analog_Output_Read_Property, \
- Analog_Output_Write_Property, Analog_Output_Property_Lists, \
- NULL, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/av.h b/bacnet-stack/demo/object/av.h
index e05f8886..08a62575 100644
--- a/bacnet-stack/demo/object/av.h
+++ b/bacnet-stack/demo/object/av.h
@@ -132,10 +132,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define ANALOG_VALUE_OBJ_FUNCTIONS \
- OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count, \
- Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance, \
- Analog_Value_Object_Name, Analog_Value_Read_Property, \
- Analog_Value_Write_Property, Analog_Value_Property_Lists, NULL, \
- NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/bacfile.h b/bacnet-stack/demo/object/bacfile.h
index 5285512e..4cd53a13 100644
--- a/bacnet-stack/demo/object/bacfile.h
+++ b/bacnet-stack/demo/object/bacfile.h
@@ -98,8 +98,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define FILE_OBJ_FUNCTIONS \
- OBJECT_FILE, bacfile_init, bacfile_count, bacfile_index_to_instance, \
- bacfile_valid_instance, bacfile_object_name, bacfile_read_property, \
- bacfile_write_property, BACfile_Property_Lists, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/bi.c b/bacnet-stack/demo/object/bi.c
index 827e8bea..3c0828cc 100644
--- a/bacnet-stack/demo/object/bi.c
+++ b/bacnet-stack/demo/object/bi.c
@@ -183,7 +183,7 @@ bool Binary_Input_Out_Of_Service(
return value;
}
-static bool Binary_Input_Change_Of_Value(
+bool Binary_Input_Change_Of_Value(
uint32_t object_instance)
{
bool status = false;
@@ -197,7 +197,7 @@ static bool Binary_Input_Change_Of_Value(
return status;
}
-static void Binary_Input_Change_Of_Value_Clear(
+void Binary_Input_Change_Of_Value_Clear(
uint32_t object_instance)
{
unsigned index;
@@ -249,7 +249,6 @@ bool Binary_Input_Encode_Value_List(
value_list->priority = BACNET_NO_PRIORITY;
}
status = Binary_Input_Change_Of_Value(object_instance);
- Binary_Input_Change_Of_Value_Clear(object_instance);
return status;
}
diff --git a/bacnet-stack/demo/object/bi.h b/bacnet-stack/demo/object/bi.h
index 8a9862ab..dd0a9c9f 100644
--- a/bacnet-stack/demo/object/bi.h
+++ b/bacnet-stack/demo/object/bi.h
@@ -86,6 +86,10 @@ extern "C" {
bool Binary_Input_Encode_Value_List(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list);
+ bool Binary_Input_Change_Of_Value(
+ uint32_t instance);
+ void Binary_Input_Change_Of_Value_Clear(
+ uint32_t instance);
int Binary_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata);
@@ -110,9 +114,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define BINARY_INPUT_OBJ_FUNCTIONS \
- OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count, \
- Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance, \
- Binary_Input_Object_Name, Binary_Input_Read_Property, NULL, \
- Binary_Input_Property_Lists, NULL, NULL, Binary_Input_Encode_Value_List
+
#endif
diff --git a/bacnet-stack/demo/object/bo.h b/bacnet-stack/demo/object/bo.h
index 90224350..f3c95c94 100644
--- a/bacnet-stack/demo/object/bo.h
+++ b/bacnet-stack/demo/object/bo.h
@@ -109,10 +109,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define BINARY_OUTPUT_OBJ_FUNCTIONS \
- OBJECT_BINARY_OUTPUT, Binary_Output_Init, Binary_Output_Count, \
- Binary_Output_Index_To_Instance, Binary_Output_Valid_Instance, \
- Binary_Output_Object_Name, Binary_Output_Read_Property, \
- Binary_Output_Write_Property, Binary_Output_Property_Lists, \
- NULL, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/bv.h b/bacnet-stack/demo/object/bv.h
index dcb33904..8d437ac2 100644
--- a/bacnet-stack/demo/object/bv.h
+++ b/bacnet-stack/demo/object/bv.h
@@ -71,10 +71,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define BINARY_VALUE_OBJ_FUNCTIONS \
- OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count, \
- Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance, \
- Binary_Value_Object_Name, Binary_Value_Read_Property, \
- Binary_Value_Write_Property, Binary_Value_Property_Lists, NULL, \
- NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/device-client.c b/bacnet-stack/demo/object/device-client.c
new file mode 100644
index 00000000..4a32e7ad
--- /dev/null
+++ b/bacnet-stack/demo/object/device-client.c
@@ -0,0 +1,908 @@
+/**************************************************************************
+*
+* Copyright (C) 2011 Steve Karg
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*
+*********************************************************************/
+
+/** @file device-client.c Lightweight base "class" for handling all
+ * BACnet objects belonging to a BACnet device, as well as
+ * Device-specific properties. This Device instance is designed to
+ * meet minimal functionality for simple clients. */
+
+#include
+#include
+#include /* for memmove */
+#include /* for timezone, localtime */
+#include "bacdef.h"
+#include "bacdcode.h"
+#include "bacenum.h"
+#include "bacapp.h"
+#include "config.h" /* the custom stuff */
+#include "apdu.h"
+#include "rp.h" /* ReadProperty handling */
+#include "version.h"
+#include "handlers.h"
+#include "datalink.h"
+#include "address.h"
+/* include the device object */
+#include "device.h" /* me */
+
+/* note: you really only need to define variables for
+ properties that are writable or that may change.
+ The properties that are constant can be hard coded
+ into the read-property encoding. */
+
+static uint32_t Object_Instance_Number = 260001;
+static BACNET_CHARACTER_STRING My_Object_Name;
+static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
+static char *Vendor_Name = BACNET_VENDOR_NAME;
+static uint16_t Vendor_Identifier = BACNET_VENDOR_ID;
+static char *Model_Name = "GNU";
+static char *Application_Software_Version = "1.0";
+static char *Location = "USA";
+static char *Description = "command line client";
+/* static uint8_t Protocol_Version = 1; - constant, not settable */
+/* static uint8_t Protocol_Revision = 4; - constant, not settable */
+/* Protocol_Services_Supported - dynamically generated */
+/* Protocol_Object_Types_Supported - in RP encoding */
+/* Object_List - dynamically generated */
+/* static BACNET_SEGMENTATION Segmentation_Supported = SEGMENTATION_NONE; */
+/* static uint8_t Max_Segments_Accepted = 0; */
+/* VT_Classes_Supported */
+/* Active_VT_Sessions */
+/* static BACNET_TIME Local_Time; rely on OS, if there is one */
+/* static BACNET_DATE Local_Date; rely on OS, if there is one */
+/* NOTE: BACnet UTC Offset is inverse of common practice.
+ If your UTC offset is -5hours of GMT,
+ then BACnet UTC offset is +5hours.
+ BACnet UTC offset is expressed in minutes. */
+/* static int32_t UTC_Offset = 5 * 60; */
+/* static bool Daylight_Savings_Status = false; rely on OS */
+/* List_Of_Session_Keys */
+/* Time_Synchronization_Recipients */
+/* Max_Master - rely on MS/TP subsystem, if there is one */
+/* Max_Info_Frames - rely on MS/TP subsystem, if there is one */
+/* Device_Address_Binding - required, but relies on binding cache */
+static uint32_t Database_Revision = 0;
+/* Configuration_Files */
+/* Last_Restore_Time */
+/* Backup_Failure_Timeout */
+/* Active_COV_Subscriptions */
+/* Slave_Proxy_Enable */
+/* Manual_Slave_Address_Binding */
+/* Auto_Slave_Discovery */
+/* Slave_Address_Binding */
+/* Profile_Name */
+
+/* local forward (semi-private) and external prototypes */
+int Device_Read_Property_Local(
+ BACNET_READ_PROPERTY_DATA * rpdata);
+
+/* All included BACnet objects */
+static object_functions_t Object_Table[] = {
+ {OBJECT_DEVICE,
+ NULL /* Init - don't init Device or it will recourse! */,
+ Device_Count,
+ Device_Index_To_Instance,
+ Device_Valid_Object_Instance_Number,
+ Device_Object_Name,
+ Device_Read_Property_Local,
+ NULL /* Write_Property */,
+ NULL /* Property_Lists */,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
+ {MAX_BACNET_OBJECT_TYPE,
+ NULL /* Init */,
+ NULL /* Count */,
+ NULL /* Index_To_Instance */,
+ NULL /* Valid_Instance */,
+ NULL /* Object_Name */,
+ NULL /* Read_Property */,
+ NULL /* Write_Property */,
+ NULL /* Property_Lists */,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */}
+};
+
+/** Glue function to let the Device object, when called by a handler,
+ * lookup which Object type needs to be invoked.
+ * @ingroup ObjHelpers
+ * @param Object_Type [in] The type of BACnet Object the handler wants to access.
+ * @return Pointer to the group of object helper functions that implement this
+ * type of Object.
+ */
+static struct object_functions *Device_Objects_Find_Functions(
+ BACNET_OBJECT_TYPE Object_Type)
+{
+ struct object_functions *pObject = NULL;
+
+ pObject = &Object_Table[0];
+ while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
+ /* handle each object type */
+ if (pObject->Object_Type == Object_Type) {
+ return (pObject);
+ }
+
+ pObject++;
+ }
+
+ return (NULL);
+}
+
+unsigned Device_Count(
+ void)
+{
+ return 1;
+}
+
+uint32_t Device_Index_To_Instance(
+ unsigned index)
+{
+ index = index;
+ return Object_Instance_Number;
+}
+
+/* methods to manipulate the data */
+
+/** Return the Object Instance number for our (single) Device Object.
+ * This is a key function, widely invoked by the handler code, since
+ * it provides "our" (ie, local) address.
+ * @ingroup ObjIntf
+ * @return The Instance number used in the BACNET_OBJECT_ID for the Device.
+ */
+uint32_t Device_Object_Instance_Number(
+ void)
+{
+#ifdef BAC_ROUTING
+ return Routed_Device_Object_Instance_Number();
+#else
+ return Object_Instance_Number;
+#endif
+}
+
+bool Device_Set_Object_Instance_Number(
+ uint32_t object_id)
+{
+ bool status = true; /* return value */
+
+ if (object_id <= BACNET_MAX_INSTANCE) {
+ /* Make the change and update the database revision */
+ Object_Instance_Number = object_id;
+ Device_Inc_Database_Revision();
+ } else
+ status = false;
+
+ return status;
+}
+
+bool Device_Valid_Object_Instance_Number(
+ uint32_t object_id)
+{
+ /* BACnet allows for a wildcard instance number */
+ return ((Object_Instance_Number == object_id) ||
+ (object_id == BACNET_MAX_INSTANCE));
+}
+
+bool Device_Object_Name(
+ uint32_t object_instance,
+ BACNET_CHARACTER_STRING * object_name)
+{
+ bool status = false;
+
+ if (object_instance == Object_Instance_Number) {
+ status = characterstring_copy(object_name, &My_Object_Name);
+ }
+
+ return status;
+}
+
+bool Device_Set_Object_Name(
+ BACNET_CHARACTER_STRING * object_name)
+{
+ bool status = false; /*return value */
+
+ if (!characterstring_same(&My_Object_Name, object_name)) {
+ /* Make the change and update the database revision */
+ status = characterstring_copy(&My_Object_Name, object_name);
+ Device_Inc_Database_Revision();
+ }
+
+ return status;
+}
+
+BACNET_DEVICE_STATUS Device_System_Status(
+ void)
+{
+ return System_Status;
+}
+
+int Device_Set_System_Status(
+ BACNET_DEVICE_STATUS status,
+ bool local)
+{
+ int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */
+
+ /* We limit the options available depending on whether the source is
+ * internal or external. */
+ if (local) {
+ switch (status) {
+ case STATUS_OPERATIONAL:
+ case STATUS_OPERATIONAL_READ_ONLY:
+ case STATUS_DOWNLOAD_REQUIRED:
+ case STATUS_DOWNLOAD_IN_PROGRESS:
+ case STATUS_NON_OPERATIONAL:
+ System_Status = status;
+ break;
+
+ /* Don't support backup at present so don't allow setting */
+ case STATUS_BACKUP_IN_PROGRESS:
+ result = -2;
+ break;
+
+ default:
+ result = -1;
+ break;
+ }
+ } else {
+ switch (status) {
+ /* Allow these for the moment as a way to easily alter
+ * overall device operation. The lack of password protection
+ * or other authentication makes allowing writes to this
+ * property a risky facility to provide.
+ */
+ case STATUS_OPERATIONAL:
+ case STATUS_OPERATIONAL_READ_ONLY:
+ case STATUS_NON_OPERATIONAL:
+ System_Status = status;
+ break;
+
+ /* Don't allow outsider set this - it should probably
+ * be set if the device config is incomplete or
+ * corrupted or perhaps after some sort of operator
+ * wipe operation.
+ */
+ case STATUS_DOWNLOAD_REQUIRED:
+ /* Don't allow outsider set this - it should be set
+ * internally at the start of a multi packet download
+ * perhaps indirectly via PT or WF to a config file.
+ */
+ case STATUS_DOWNLOAD_IN_PROGRESS:
+ /* Don't support backup at present so don't allow setting */
+ case STATUS_BACKUP_IN_PROGRESS:
+ result = -2;
+ break;
+
+ default:
+ result = -1;
+ break;
+ }
+ }
+
+ return (result);
+}
+
+const char *Device_Vendor_Name(
+ void)
+{
+ return Vendor_Name;
+}
+
+/** Returns the Vendor ID for this Device.
+ * See the assignments at http://www.bacnet.org/VendorID/BACnet%20Vendor%20IDs.htm
+ * @return The Vendor ID of this Device.
+ */
+uint16_t Device_Vendor_Identifier(
+ void)
+{
+ return Vendor_Identifier;
+}
+
+void Device_Set_Vendor_Identifier(
+ uint16_t vendor_id)
+{
+ Vendor_Identifier = vendor_id;
+}
+
+const char *Device_Model_Name(
+ void)
+{
+ return Model_Name;
+}
+
+bool Device_Set_Model_Name(
+ const char *name,
+ size_t length)
+{
+ bool status = false; /*return value */
+
+ if (length < sizeof(Model_Name)) {
+ memmove(Model_Name, name, length);
+ Model_Name[length] = 0;
+ status = true;
+ }
+
+ return status;
+}
+
+const char *Device_Firmware_Revision(
+ void)
+{
+ return BACnet_Version;
+}
+
+const char *Device_Application_Software_Version(
+ void)
+{
+ return Application_Software_Version;
+}
+
+bool Device_Set_Application_Software_Version(
+ const char *name,
+ size_t length)
+{
+ bool status = false; /*return value */
+
+ if (length < sizeof(Application_Software_Version)) {
+ memmove(Application_Software_Version, name, length);
+ Application_Software_Version[length] = 0;
+ status = true;
+ }
+
+ return status;
+}
+
+const char *Device_Description(
+ void)
+{
+ return Description;
+}
+
+bool Device_Set_Description(
+ const char *name,
+ size_t length)
+{
+ bool status = false; /*return value */
+
+ if (length < sizeof(Description)) {
+ memmove(Description, name, length);
+ Description[length] = 0;
+ status = true;
+ }
+
+ return status;
+}
+
+const char *Device_Location(
+ void)
+{
+ return Location;
+}
+
+bool Device_Set_Location(
+ const char *name,
+ size_t length)
+{
+ bool status = false; /*return value */
+
+ if (length < sizeof(Location)) {
+ memmove(Location, name, length);
+ Location[length] = 0;
+ status = true;
+ }
+
+ return status;
+}
+
+uint8_t Device_Protocol_Version(
+ void)
+{
+ return BACNET_PROTOCOL_VERSION;
+}
+
+uint8_t Device_Protocol_Revision(
+ void)
+{
+ return BACNET_PROTOCOL_REVISION;
+}
+
+BACNET_SEGMENTATION Device_Segmentation_Supported(
+ void)
+{
+ return SEGMENTATION_NONE;
+}
+
+uint32_t Device_Database_Revision(
+ void)
+{
+ return Database_Revision;
+}
+
+void Device_Set_Database_Revision(
+ uint32_t revision)
+{
+ Database_Revision = revision;
+}
+
+/*
+ * Shortcut for incrementing database revision as this is potentially
+ * the most common operation if changing object names and ids is
+ * implemented.
+ */
+void Device_Inc_Database_Revision(
+ void)
+{
+ Database_Revision++;
+}
+
+/** Get the total count of objects supported by this Device Object.
+ * @note Since many network clients depend on the object list
+ * for discovery, it must be consistent!
+ * @return The count of objects, for all supported Object types.
+ */
+unsigned Device_Object_List_Count(
+ void)
+{
+ unsigned count = 0; /* number of objects */
+ struct object_functions *pObject = NULL;
+
+ /* initialize the default return values */
+ pObject = &Object_Table[0];
+ while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
+ if (pObject->Object_Count) {
+ count += pObject->Object_Count();
+ }
+ pObject++;
+ }
+
+ return count;
+}
+
+/** Lookup the Object at the given array index in the Device's Object List.
+ * Even though we don't keep a single linear array of objects in the Device,
+ * this method acts as though we do and works through a virtual, concatenated
+ * array of all of our object type arrays.
+ *
+ * @param array_index [in] The desired array index (1 to N)
+ * @param object_type [out] The object's type, if found.
+ * @param instance [out] The object's instance number, if found.
+ * @return True if found, else false.
+ */
+bool Device_Object_List_Identifier(
+ unsigned array_index,
+ int *object_type,
+ uint32_t * instance)
+{
+ bool status = false;
+ unsigned count = 0;
+ unsigned object_index = 0;
+ unsigned temp_index = 0;
+ struct object_functions *pObject = NULL;
+
+ /* array index zero is length - so invalid */
+ if (array_index == 0) {
+ return status;
+ }
+ object_index = array_index - 1;
+ /* initialize the default return values */
+ pObject = &Object_Table[0];
+ while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
+ if (pObject->Object_Count) {
+ object_index -= count;
+ count = pObject->Object_Count();
+ if (object_index < count) {
+ /* Use the iterator function if available otherwise
+ * look for the index to instance to get the ID */
+ if (pObject->Object_Iterator) {
+ /* First find the first object */
+ temp_index = pObject->Object_Iterator(~(unsigned) 0);
+ /* Then step through the objects to find the nth */
+ while (object_index != 0) {
+ temp_index = pObject->Object_Iterator(temp_index);
+ object_index--;
+ }
+ /* set the object_index up before falling through to next bit */
+ object_index = temp_index;
+ }
+ if (pObject->Object_Index_To_Instance) {
+ *object_type = pObject->Object_Type;
+ *instance =
+ pObject->Object_Index_To_Instance(object_index);
+ status = true;
+ break;
+ }
+ }
+ }
+ pObject++;
+ }
+
+ return status;
+}
+
+/** Determine if we have an object with the given object_name.
+ * If the object_type and object_instance pointers are not null,
+ * and the lookup succeeds, they will be given the resulting values.
+ * @param object_name [in] The desired Object Name to look for.
+ * @param object_type [out] The BACNET_OBJECT_TYPE of the matching Object.
+ * @param object_instance [out] The object instance number of the matching Object.
+ * @return True on success or else False if not found.
+ */
+bool Device_Valid_Object_Name(
+ BACNET_CHARACTER_STRING * object_name1,
+ int *object_type,
+ uint32_t * object_instance)
+{
+ bool found = false;
+ int type = 0;
+ uint32_t instance;
+ unsigned max_objects = 0, i = 0;
+ bool check_id = false;
+ BACNET_CHARACTER_STRING object_name2;
+ struct object_functions *pObject = NULL;
+
+ max_objects = Device_Object_List_Count();
+ for (i = 0; i < max_objects; i++) {
+ check_id = Device_Object_List_Identifier(i, &type, &instance);
+ if (check_id) {
+ pObject = Device_Objects_Find_Functions(type);
+ if ((pObject != NULL) && (pObject->Object_Name != NULL) &&
+ (pObject->Object_Name(instance, &object_name2) &&
+ characterstring_same(object_name1, &object_name2))) {
+ found = true;
+ if (object_type) {
+ *object_type = type;
+ }
+ if (object_instance) {
+ *object_instance = instance;
+ }
+ break;
+ }
+ }
+ }
+
+ return found;
+}
+
+/** Determine if we have an object of this type and instance number.
+ * @param object_type [in] The desired BACNET_OBJECT_TYPE
+ * @param object_instance [in] The object instance number to be looked up.
+ * @return True if found, else False if no such Object in this device.
+ */
+bool Device_Valid_Object_Id(
+ int object_type,
+ uint32_t object_instance)
+{
+ bool status = false; /* return value */
+ struct object_functions *pObject = NULL;
+
+ pObject = Device_Objects_Find_Functions(object_type);
+ if ((pObject != NULL) && (pObject->Object_Valid_Instance != NULL)) {
+ status = pObject->Object_Valid_Instance(object_instance);
+ }
+
+ return status;
+}
+
+/** Copy a child object's object_name value, given its ID.
+ * @param object_type [in] The BACNET_OBJECT_TYPE of the child Object.
+ * @param object_instance [in] The object instance number of the child Object.
+ * @param object_name [out] The Object Name found for this child Object.
+ * @return True on success or else False if not found.
+ */
+bool Device_Object_Name_Copy(
+ BACNET_OBJECT_TYPE object_type,
+ uint32_t object_instance,
+ BACNET_CHARACTER_STRING * object_name)
+{
+ struct object_functions *pObject = NULL;
+ bool found = false;
+
+ pObject = Device_Objects_Find_Functions(object_type);
+ if ((pObject != NULL) && (pObject->Object_Name != NULL)) {
+ found = pObject->Object_Name(object_instance, object_name);
+ }
+
+ return found;
+}
+
+/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
+ BACNET_STATUS_ABORT for abort message */
+int Device_Read_Property_Local(
+ BACNET_READ_PROPERTY_DATA * rpdata)
+{
+ int apdu_len = 0; /* return value */
+ int len = 0; /* apdu len intermediate value */
+ BACNET_BIT_STRING bit_string;
+ BACNET_CHARACTER_STRING char_string;
+ unsigned i = 0;
+ int object_type = 0;
+ uint32_t instance = 0;
+ unsigned count = 0;
+ uint8_t *apdu = NULL;
+ struct object_functions *pObject = NULL;
+ bool found = false;
+
+ if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
+ (rpdata->application_data_len == 0)) {
+ return 0;
+ }
+ apdu = rpdata->application_data;
+ switch (rpdata->object_property) {
+ case PROP_OBJECT_IDENTIFIER:
+ apdu_len =
+ encode_application_object_id(&apdu[0], OBJECT_DEVICE,
+ Object_Instance_Number);
+ break;
+ case PROP_OBJECT_NAME:
+ apdu_len =
+ encode_application_character_string(&apdu[0], &My_Object_Name);
+ break;
+ case PROP_OBJECT_TYPE:
+ apdu_len = encode_application_enumerated(&apdu[0], OBJECT_DEVICE);
+ break;
+ case PROP_DESCRIPTION:
+ characterstring_init_ansi(&char_string, Description);
+ apdu_len =
+ encode_application_character_string(&apdu[0], &char_string);
+ break;
+ case PROP_SYSTEM_STATUS:
+ apdu_len = encode_application_enumerated(&apdu[0], System_Status);
+ break;
+ case PROP_VENDOR_NAME:
+ characterstring_init_ansi(&char_string, Vendor_Name);
+ apdu_len =
+ encode_application_character_string(&apdu[0], &char_string);
+ break;
+ case PROP_VENDOR_IDENTIFIER:
+ apdu_len =
+ encode_application_unsigned(&apdu[0], Vendor_Identifier);
+ break;
+ case PROP_MODEL_NAME:
+ characterstring_init_ansi(&char_string, Model_Name);
+ apdu_len =
+ encode_application_character_string(&apdu[0], &char_string);
+ break;
+ case PROP_FIRMWARE_REVISION:
+ characterstring_init_ansi(&char_string, BACnet_Version);
+ apdu_len =
+ encode_application_character_string(&apdu[0], &char_string);
+ break;
+ case PROP_APPLICATION_SOFTWARE_VERSION:
+ characterstring_init_ansi(&char_string,
+ Application_Software_Version);
+ apdu_len =
+ encode_application_character_string(&apdu[0], &char_string);
+ break;
+ case PROP_LOCATION:
+ characterstring_init_ansi(&char_string, Location);
+ apdu_len =
+ encode_application_character_string(&apdu[0], &char_string);
+ break;
+ case PROP_PROTOCOL_VERSION:
+ apdu_len =
+ encode_application_unsigned(&apdu[0],
+ Device_Protocol_Version());
+ break;
+ case PROP_PROTOCOL_REVISION:
+ apdu_len =
+ encode_application_unsigned(&apdu[0],
+ Device_Protocol_Revision());
+ break;
+ case PROP_PROTOCOL_SERVICES_SUPPORTED:
+ /* Note: list of services that are executed, not initiated. */
+ bitstring_init(&bit_string);
+ for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
+ /* automatic lookup based on handlers set */
+ bitstring_set_bit(&bit_string, (uint8_t) i,
+ apdu_service_supported((BACNET_SERVICES_SUPPORTED) i));
+ }
+ apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
+ break;
+ case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
+ /* Note: this is the list of objects that can be in this device,
+ not a list of objects that this device can access */
+ bitstring_init(&bit_string);
+ for (i = 0; i < MAX_ASHRAE_OBJECT_TYPE; i++) {
+ /* initialize all the object types to not-supported */
+ bitstring_set_bit(&bit_string, (uint8_t) i, false);
+ }
+ /* set the object types with objects to supported */
+
+ pObject = &Object_Table[0];
+ while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
+ if ((pObject->Object_Count) && (pObject->Object_Count() > 0)) {
+ bitstring_set_bit(&bit_string, pObject->Object_Type, true);
+ }
+ pObject++;
+ }
+ apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
+ break;
+ case PROP_OBJECT_LIST:
+ count = Device_Object_List_Count();
+ /* Array element zero is the number of objects in the list */
+ if (rpdata->array_index == 0)
+ apdu_len = encode_application_unsigned(&apdu[0], count);
+ /* if no index was specified, then try to encode the entire list */
+ /* into one packet. Note that more than likely you will have */
+ /* to return an error if the number of encoded objects exceeds */
+ /* your maximum APDU size. */
+ else if (rpdata->array_index == BACNET_ARRAY_ALL) {
+ for (i = 1; i <= count; i++) {
+ found =
+ Device_Object_List_Identifier(i, &object_type,
+ &instance);
+ if (found) {
+ len =
+ encode_application_object_id(&apdu[apdu_len],
+ object_type, instance);
+ apdu_len += len;
+ /* assume next one is the same size as this one */
+ /* can we all fit into the APDU? Don't check for last entry */
+ if ((i != count) && (apdu_len + len) >= MAX_APDU) {
+ /* Abort response */
+ rpdata->error_code =
+ ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
+ apdu_len = BACNET_STATUS_ABORT;
+ break;
+ }
+ } else {
+ /* error: internal error? */
+ rpdata->error_class = ERROR_CLASS_SERVICES;
+ rpdata->error_code = ERROR_CODE_OTHER;
+ apdu_len = BACNET_STATUS_ERROR;
+ break;
+ }
+ }
+ } else {
+ found =
+ Device_Object_List_Identifier(rpdata->array_index,
+ &object_type, &instance);
+ if (found) {
+ apdu_len =
+ encode_application_object_id(&apdu[0], object_type,
+ instance);
+ } else {
+ rpdata->error_class = ERROR_CLASS_PROPERTY;
+ rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
+ apdu_len = BACNET_STATUS_ERROR;
+ }
+ }
+ break;
+ case PROP_MAX_APDU_LENGTH_ACCEPTED:
+ apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
+ break;
+ case PROP_SEGMENTATION_SUPPORTED:
+ apdu_len =
+ encode_application_enumerated(&apdu[0],
+ Device_Segmentation_Supported());
+ break;
+ case PROP_APDU_TIMEOUT:
+ apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
+ break;
+ case PROP_NUMBER_OF_APDU_RETRIES:
+ apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
+ break;
+ case PROP_DEVICE_ADDRESS_BINDING:
+ /* FIXME: the real max apdu remaining should be passed into function */
+ apdu_len = address_list_encode(&apdu[0], MAX_APDU);
+ break;
+ case PROP_DATABASE_REVISION:
+ apdu_len =
+ encode_application_unsigned(&apdu[0], Database_Revision);
+ break;
+#if defined(BACDL_MSTP)
+ case PROP_MAX_INFO_FRAMES:
+ apdu_len =
+ encode_application_unsigned(&apdu[0],
+ dlmstp_max_info_frames());
+ break;
+ case PROP_MAX_MASTER:
+ apdu_len =
+ encode_application_unsigned(&apdu[0], dlmstp_max_master());
+ break;
+#endif
+ case PROP_ACTIVE_COV_SUBSCRIPTIONS:
+ break;
+ default:
+ rpdata->error_class = ERROR_CLASS_PROPERTY;
+ rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
+ apdu_len = BACNET_STATUS_ERROR;
+ break;
+ }
+ /* only array properties can have array options */
+ if ((apdu_len >= 0) && (rpdata->object_property != PROP_OBJECT_LIST) &&
+ (rpdata->array_index != BACNET_ARRAY_ALL)) {
+ rpdata->error_class = ERROR_CLASS_PROPERTY;
+ rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
+ apdu_len = BACNET_STATUS_ERROR;
+ }
+
+ return apdu_len;
+}
+
+/** Looks up the requested Object and Property, and encodes its Value in an APDU.
+ * @ingroup ObjIntf
+ * If the Object or Property can't be found, sets the error class and code.
+ *
+ * @param rpdata [in,out] Structure with the desired Object and Property info
+ * on entry, and APDU message on return.
+ * @return The length of the APDU on success, else BACNET_STATUS_ERROR
+ */
+int Device_Read_Property(
+ BACNET_READ_PROPERTY_DATA * rpdata)
+{
+ int apdu_len = BACNET_STATUS_ERROR;
+ struct object_functions *pObject = NULL;
+
+ /* initialize the default return values */
+ rpdata->error_class = ERROR_CLASS_OBJECT;
+ rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
+ pObject = Device_Objects_Find_Functions(rpdata->object_type);
+ if (pObject != NULL) {
+ if (pObject->Object_Valid_Instance &&
+ pObject->Object_Valid_Instance(rpdata->object_instance)) {
+ if (pObject->Object_Read_Property) {
+ apdu_len = pObject->Object_Read_Property(rpdata);
+ }
+ } else {
+ rpdata->error_class = ERROR_CLASS_OBJECT;
+ rpdata->error_code = ERROR_CODE_UNKNOWN_OBJECT;
+ }
+ } else {
+ rpdata->error_class = ERROR_CLASS_OBJECT;
+ rpdata->error_code = ERROR_CODE_UNSUPPORTED_OBJECT_TYPE;
+ }
+
+ return apdu_len;
+}
+
+/** Initialize the Device Object.
+ Initialize the group of object helper functions for any supported Object.
+ Initialize each of the Device Object child Object instances.
+ * @ingroup ObjIntf
+ * @param object_table [in,out] array of structure with object functions.
+ * Each Child Object must provide some implementation of each of these
+ * functions in order to properly support the default handlers.
+ */
+void Device_Init(
+ object_functions_t * object_table)
+{
+ struct object_functions *pObject = NULL;
+
+ characterstring_init_ansi(&My_Object_Name, "SimpleClient");
+ /* we don't use the object table passed in */
+ (void) object_table;
+ pObject = &Object_Table[0];
+ while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
+ if (pObject->Object_Init) {
+ pObject->Object_Init();
+ }
+ pObject++;
+ }
+}
diff --git a/bacnet-stack/demo/object/device.c b/bacnet-stack/demo/object/device.c
index 7050ec96..1134892e 100644
--- a/bacnet-stack/demo/object/device.c
+++ b/bacnet-stack/demo/object/device.c
@@ -83,87 +83,209 @@ extern int Routed_Device_Read_Property_Local(
extern bool Routed_Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA * wp_data);
+/* may be overridden by outside table */
+static object_functions_t *Object_Table;
-static object_functions_t Object_Table[] = {
- {
- OBJECT_DEVICE, NULL, Device_Count, /* don't init - recursive! */
- Device_Index_To_Instance, Device_Valid_Object_Instance_Number,
- Device_Object_Name, Device_Read_Property_Local,
- Device_Write_Property_Local, Device_Property_Lists,
- NULL, NULL, NULL, NULL}, {
- OBJECT_ANALOG_INPUT, Analog_Input_Init, Analog_Input_Count,
- Analog_Input_Index_To_Instance, Analog_Input_Valid_Instance,
- Analog_Input_Object_Name, Analog_Input_Read_Property,
- Analog_Input_Write_Property, Analog_Input_Property_Lists,
- NULL, NULL, NULL, Analog_Input_Intrinsic_Reporting}, {
- OBJECT_ANALOG_VALUE, Analog_Value_Init, Analog_Value_Count,
- Analog_Value_Index_To_Instance, Analog_Value_Valid_Instance,
- Analog_Value_Object_Name, Analog_Value_Read_Property,
- Analog_Value_Write_Property, Analog_Value_Property_Lists,
- NULL, NULL, NULL, Analog_Value_Intrinsic_Reporting}, {
- OBJECT_BINARY_INPUT, Binary_Input_Init, Binary_Input_Count,
- Binary_Input_Index_To_Instance, Binary_Input_Valid_Instance,
- Binary_Input_Object_Name, Binary_Input_Read_Property,
- NULL, Binary_Input_Property_Lists,
- NULL, NULL, NULL, NULL}, {
- OBJECT_BINARY_VALUE, Binary_Value_Init, Binary_Value_Count,
- Binary_Value_Index_To_Instance, Binary_Value_Valid_Instance,
- Binary_Value_Object_Name, Binary_Value_Read_Property,
- Binary_Value_Write_Property, Binary_Value_Property_Lists,
- NULL, NULL, NULL, NULL}, {
+static object_functions_t My_Object_Table[] = {
+ {OBJECT_DEVICE,
+ NULL /* Init - don't init Device or it will recourse! */,
+ Device_Count,
+ Device_Index_To_Instance,
+ Device_Valid_Object_Instance_Number,
+ Device_Object_Name,
+ Device_Read_Property_Local,
+ Device_Write_Property_Local,
+ Device_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
+ {OBJECT_ANALOG_INPUT,
+ Analog_Input_Init,
+ Analog_Input_Count,
+ Analog_Input_Index_To_Instance,
+ Analog_Input_Valid_Instance,
+ Analog_Input_Object_Name,
+ Analog_Input_Read_Property,
+ Analog_Input_Write_Property,
+ Analog_Input_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ Analog_Input_Intrinsic_Reporting},
+ {OBJECT_ANALOG_VALUE,
+ Analog_Value_Init,
+ Analog_Value_Count,
+ Analog_Value_Index_To_Instance,
+ Analog_Value_Valid_Instance,
+ Analog_Value_Object_Name,
+ Analog_Value_Read_Property,
+ Analog_Value_Write_Property,
+ Analog_Value_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ Analog_Value_Intrinsic_Reporting},
+ {OBJECT_BINARY_INPUT,
+ Binary_Input_Init,
+ Binary_Input_Count,
+ Binary_Input_Index_To_Instance,
+ Binary_Input_Valid_Instance,
+ Binary_Input_Object_Name,
+ Binary_Input_Read_Property,
+ NULL /* Write Property */,
+ Binary_Input_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ Binary_Input_Encode_Value_List,
+ Binary_Input_Change_Of_Value,
+ Binary_Input_Change_Of_Value_Clear,
+ NULL /* Intrinsic Reporting */},
+ {OBJECT_BINARY_VALUE,
+ Binary_Value_Init,
+ Binary_Value_Count,
+ Binary_Value_Index_To_Instance,
+ Binary_Value_Valid_Instance,
+ Binary_Value_Object_Name,
+ Binary_Value_Read_Property,
+ Binary_Value_Write_Property,
+ Binary_Value_Property_Lists,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
#if defined(INTRINSIC_REPORTING)
- OBJECT_NOTIFICATION_CLASS, Notification_Class_Init,
- Notification_Class_Count,
- Notification_Class_Index_To_Instance,
- Notification_Class_Valid_Instance,
- Notification_Class_Object_Name, Notification_Class_Read_Property,
- Notification_Class_Write_Property,
- Notification_Class_Property_Lists,
- NULL, NULL, NULL, NULL}, {
+ {OBJECT_NOTIFICATION_CLASS,
+ Notification_Class_Init,
+ Notification_Class_Count,
+ Notification_Class_Index_To_Instance,
+ Notification_Class_Valid_Instance,
+ Notification_Class_Object_Name,
+ Notification_Class_Read_Property,
+ Notification_Class_Write_Property,
+ Notification_Class_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
#endif
- OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init,
- Life_Safety_Point_Count,
- Life_Safety_Point_Index_To_Instance,
- Life_Safety_Point_Valid_Instance,
- Life_Safety_Point_Object_Name, Life_Safety_Point_Read_Property,
- Life_Safety_Point_Write_Property, Life_Safety_Point_Property_Lists,
- NULL, NULL, NULL, NULL}, {
- OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count,
- Load_Control_Index_To_Instance, Load_Control_Valid_Instance,
- Load_Control_Object_Name, Load_Control_Read_Property,
- Load_Control_Write_Property, Load_Control_Property_Lists,
- NULL, NULL, NULL, NULL}, {
- OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init,
- Multistate_Output_Count,
- Multistate_Output_Index_To_Instance,
- Multistate_Output_Valid_Instance,
- Multistate_Output_Object_Name, Multistate_Output_Read_Property,
- Multistate_Output_Write_Property, Multistate_Output_Property_Lists,
- NULL, NULL, NULL, NULL}, {
- OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init,
- Multistate_Input_Count,
- Multistate_Input_Index_To_Instance,
- Multistate_Input_Valid_Instance,
- Multistate_Input_Object_Name, Multistate_Input_Read_Property,
- Multistate_Input_Write_Property, Multistate_Input_Property_Lists,
- NULL, NULL, NULL, NULL}, {
- OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count,
- Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance,
- Trend_Log_Object_Name, Trend_Log_Read_Property,
- Trend_Log_Write_Property, Trend_Log_Property_Lists,
- TrendLogGetRRInfo, NULL, NULL, NULL}, {
+ {OBJECT_LIFE_SAFETY_POINT,
+ Life_Safety_Point_Init,
+ Life_Safety_Point_Count,
+ Life_Safety_Point_Index_To_Instance,
+ Life_Safety_Point_Valid_Instance,
+ Life_Safety_Point_Object_Name,
+ Life_Safety_Point_Read_Property,
+ Life_Safety_Point_Write_Property,
+ Life_Safety_Point_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
+ {OBJECT_LOAD_CONTROL,
+ Load_Control_Init,
+ Load_Control_Count,
+ Load_Control_Index_To_Instance,
+ Load_Control_Valid_Instance,
+ Load_Control_Object_Name,
+ Load_Control_Read_Property,
+ Load_Control_Write_Property,
+ Load_Control_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
+ {OBJECT_MULTI_STATE_OUTPUT,
+ Multistate_Output_Init,
+ Multistate_Output_Count,
+ Multistate_Output_Index_To_Instance,
+ Multistate_Output_Valid_Instance,
+ Multistate_Output_Object_Name,
+ Multistate_Output_Read_Property,
+ Multistate_Output_Write_Property,
+ Multistate_Output_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
+ {OBJECT_MULTI_STATE_INPUT,
+ Multistate_Input_Init,
+ Multistate_Input_Count,
+ Multistate_Input_Index_To_Instance,
+ Multistate_Input_Valid_Instance,
+ Multistate_Input_Object_Name,
+ Multistate_Input_Read_Property,
+ Multistate_Input_Write_Property,
+ Multistate_Input_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
+ {OBJECT_TRENDLOG,
+ Trend_Log_Init,
+ Trend_Log_Count,
+ Trend_Log_Index_To_Instance,
+ Trend_Log_Valid_Instance,
+ Trend_Log_Object_Name,
+ Trend_Log_Read_Property,
+ Trend_Log_Write_Property,
+ Trend_Log_Property_Lists,
+ TrendLogGetRRInfo,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
#if defined(BACFILE)
- OBJECT_FILE, bacfile_init, bacfile_count,
- bacfile_index_to_instance, bacfile_valid_instance,
- bacfile_object_name, bacfile_read_property,
- bacfile_write_property, BACfile_Property_Lists,
- NULL, NULL, NULL, NULL}, {
+ {OBJECT_FILE,
+ bacfile_init,
+ bacfile_count,
+ bacfile_index_to_instance,
+ bacfile_valid_instance,
+ bacfile_object_name,
+ bacfile_read_property,
+ bacfile_write_property,
+ BACfile_Property_Lists,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */},
#endif
- MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL}
+ {MAX_BACNET_OBJECT_TYPE,
+ NULL /* Init */,
+ NULL /* Count */,
+ NULL /* Index_To_Instance */,
+ NULL /* Valid_Instance */,
+ NULL /* Object_Name */,
+ NULL /* Read_Property */,
+ NULL /* Write_Property */,
+ NULL /* Property_Lists */,
+ NULL /* ReadRangeInfo */,
+ NULL /* Iterator */,
+ NULL /* Value_Lists */,
+ NULL /* COV */,
+ NULL /* COV Clear */,
+ NULL /* Intrinsic Reporting */}
};
-
/** Glue function to let the Device object, when called by a handler,
* lookup which Object type needs to be invoked.
* @ingroup ObjHelpers
@@ -176,13 +298,12 @@ static struct object_functions *Device_Objects_Find_Functions(
{
struct object_functions *pObject = NULL;
- pObject = &Object_Table[0];
+ pObject = Object_Table;
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
/* handle each object type */
if (pObject->Object_Type == Object_Type) {
return (pObject);
}
-
pObject++;
}
@@ -341,16 +462,16 @@ static const int Device_Properties_Required[] = {
PROP_SEGMENTATION_SUPPORTED,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
-#if defined(BACDL_MSTP)
- PROP_MAX_MASTER,
- PROP_MAX_INFO_FRAMES,
-#endif
PROP_DEVICE_ADDRESS_BINDING,
PROP_DATABASE_REVISION,
-1
};
static const int Device_Properties_Optional[] = {
+#if defined(BACDL_MSTP)
+ PROP_MAX_MASTER,
+ PROP_MAX_INFO_FRAMES,
+#endif
PROP_DESCRIPTION,
PROP_LOCAL_TIME,
PROP_UTC_OFFSET,
@@ -744,7 +865,7 @@ unsigned Device_Object_List_Count(
struct object_functions *pObject = NULL;
/* initialize the default return values */
- pObject = &Object_Table[0];
+ pObject = Object_Table;
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if (pObject->Object_Count) {
count += pObject->Object_Count();
@@ -782,7 +903,7 @@ bool Device_Object_List_Identifier(
}
object_index = array_index - 1;
/* initialize the default return values */
- pObject = &Object_Table[0];
+ pObject = Object_Table;
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if (pObject->Object_Count) {
object_index -= count;
@@ -887,7 +1008,7 @@ bool Device_Valid_Object_Id(
* @return True on success or else False if not found.
*/
bool Device_Object_Name_Copy(
- BACNET_OBJECT_TYPE object_type,
+ BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
{
@@ -1087,7 +1208,7 @@ int Device_Read_Property_Local(
}
/* set the object types with objects to supported */
- pObject = &Object_Table[0];
+ pObject = Object_Table;
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if ((pObject->Object_Count) && (pObject->Object_Count() > 0)) {
bitstring_set_bit(&bit_string, pObject->Object_Type, true);
@@ -1206,7 +1327,7 @@ int Device_Read_Property_Local(
* If the Object or Property can't be found, sets the error class and code.
*
* @param rpdata [in,out] Structure with the desired Object and Property info
- * on entry, and APDU message on return.
+ * on entry, and APDU message on return.
* @return The length of the APDU on success, else BACNET_STATUS_ERROR
*/
int Device_Read_Property(
@@ -1483,6 +1604,43 @@ bool Device_Encode_Value_List(
return (status);
}
+bool Device_COV(
+ BACNET_OBJECT_TYPE object_type,
+ uint32_t object_instance)
+{
+ bool status = false; /* Ever the pessamist! */
+ struct object_functions *pObject = NULL;
+
+ pObject = Device_Objects_Find_Functions(object_type);
+ if (pObject != NULL) {
+ if (pObject->Object_Valid_Instance &&
+ pObject->Object_Valid_Instance(object_instance)) {
+ if (pObject->Object_COV) {
+ status = pObject->Object_COV(
+ object_instance);
+ }
+ }
+ }
+
+ return (status);
+}
+
+void Device_COV_Clear(
+ BACNET_OBJECT_TYPE object_type,
+ uint32_t object_instance)
+{
+ struct object_functions *pObject = NULL;
+
+ pObject = Device_Objects_Find_Functions(object_type);
+ if (pObject != NULL) {
+ if (pObject->Object_Valid_Instance &&
+ pObject->Object_Valid_Instance(object_instance)) {
+ if (pObject->Object_COV_Clear) {
+ pObject->Object_COV_Clear(object_instance);
+ }
+ }
+ }
+}
#if defined(INTRINSIC_REPORTING)
void Device_local_reporting(
@@ -1548,10 +1706,12 @@ void Device_Init(
struct object_functions *pObject = NULL;
characterstring_init_ansi(&My_Object_Name, "SimpleServer");
- /* we don't use the object table passed in
- since there is extra stuff we don't need in there. */
- (void) object_table;
- pObject = &Object_Table[0];
+ if (object_table) {
+ Object_Table = object_table;
+ } else {
+ Object_Table = &My_Object_Table[0];
+ }
+ pObject = Object_Table;
while (pObject->Object_Type < MAX_BACNET_OBJECT_TYPE) {
if (pObject->Object_Init) {
pObject->Object_Init();
@@ -1625,7 +1785,7 @@ void Routing_Device_Init(
Add_Routed_Device(first_object_instance, &My_Object_Name, Description);
/* Now substitute our routed versions of the main object functions. */
- pDevObject = &Object_Table[0];
+ pDevObject = Object_Table;
pDevObject->Object_Index_To_Instance = Routed_Device_Index_To_Instance;
pDevObject->Object_Valid_Instance =
Routed_Device_Valid_Object_Instance_Number;
diff --git a/bacnet-stack/demo/object/device.h b/bacnet-stack/demo/object/device.h
index 8c84eeb5..084efea0 100644
--- a/bacnet-stack/demo/object/device.h
+++ b/bacnet-stack/demo/object/device.h
@@ -70,7 +70,7 @@ typedef uint32_t(
* @param object_name [in,out] Pointer to a character_string structure that
* will hold a copy of the object name if this is a valid object_instance.
* @return True if the object_instance is valid and object_name has been
- * filled with a copy of the Object's name.
+ * filled with a copy of the Object's name.
*/
typedef bool(
*object_name_function)
@@ -113,6 +113,23 @@ typedef bool(
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list);
+/** Look in the table of objects for this instance to see if value changed.
+ * @ingroup ObjHelpers
+ * @param [in] The object instance number to be looked up.
+ * @return True if the object instance has changed.
+ */
+typedef bool(
+ *object_cov_function) (
+ uint32_t object_instance);
+
+/** Look in the table of objects for this instance to clear the changed flag.
+ * @ingroup ObjHelpers
+ * @param [in] The object instance number to be looked up.
+ */
+typedef void(
+ *object_cov_clear_function) (
+ uint32_t object_instance);
+
/** Intrinsic Reporting funcionality.
* @ingroup ObjHelpers
* @param [in] Object instance.
@@ -127,7 +144,7 @@ typedef void (
* Each Object must provide some implementation of each of these helpers
* in order to properly support the handlers. Eg, the ReadProperty handler
* handler_read_property() relies on the instance of Object_Read_Property
- * for each Object type.
+ * for each Object type, or configure the function as NULL.
* In both appearance and operation, this group of functions acts like
* they are member functions of a C++ Object base class.
*/
@@ -144,6 +161,8 @@ typedef struct object_functions {
rr_info_function Object_RR_Info;
object_iterate_function Object_Iterator;
object_value_list_function Object_Value_List;
+ object_cov_function Object_COV;
+ object_cov_clear_function Object_COV_Clear;
object_intrinsic_reporting_function Object_Intrinsic_Reporting;
} object_functions_t;
@@ -224,13 +243,19 @@ extern "C" {
void Device_Objects_Property_List(
BACNET_OBJECT_TYPE object_type,
struct special_property_list_t *pPropertyList);
-
+ /* functions to support COV */
bool Device_Encode_Value_List(
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_VALUE * value_list);
bool Device_Value_List_Supported(
BACNET_OBJECT_TYPE object_type);
+ bool Device_COV(
+ BACNET_OBJECT_TYPE object_type,
+ uint32_t object_instance);
+ void Device_COV_Clear(
+ BACNET_OBJECT_TYPE object_type,
+ uint32_t object_instance);
uint32_t Device_Object_Instance_Number(
void);
@@ -401,11 +426,7 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define DEVICE_OBJ_FUNCTIONS \
- OBJECT_DEVICE, NULL, Device_Count, Device_Index_To_Instance, \
- Device_Valid_Object_Instance_Number, Device_Object_Name, \
- Device_Read_Property_Local, Device_Write_Property_Local, \
- Device_Property_Lists, DeviceGetRRInfo, NULL, NULL
+
/** @defgroup ObjFrmwk Object Framework
* The modules in this section describe the BACnet-stack's framework for
* BACnet-defined Objects (Device, Analog Input, etc). There are two submodules
@@ -415,11 +436,15 @@ extern "C" {
* - The interface between the implemented Objects and the BAC-stack services,
* specifically the handlers, which are mediated through function calls to
* the Device object.
- *//** @defgroup ObjHelpers Object Helper Functions
+ */
+
+/** @defgroup ObjHelpers Object Helper Functions
* @ingroup ObjFrmwk
* This section describes the function templates for the helper functions that
* provide common object support.
- *//** @defgroup ObjIntf Handler-to-Object Interface Functions
+ */
+
+/** @defgroup ObjIntf Handler-to-Object Interface Functions
* @ingroup ObjFrmwk
* This section describes the fairly limited set of functions that link the
* BAC-stack handlers to the BACnet Object instances. All of these calls are
diff --git a/bacnet-stack/demo/object/lc.h b/bacnet-stack/demo/object/lc.h
index 09704288..02aec0a8 100644
--- a/bacnet-stack/demo/object/lc.h
+++ b/bacnet-stack/demo/object/lc.h
@@ -76,10 +76,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define LOAD_CONTROL_OBJ_FUNCTIONS \
- OBJECT_LOAD_CONTROL, Load_Control_Init, Load_Control_Count, \
- Load_Control_Index_To_Instance, Load_Control_Valid_Instance, \
- Load_Control_Object_Name, Load_Control_Read_Property, \
- Load_Control_Write_Property, Load_Control_Property_Lists, NULL, \
- NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/lsp.h b/bacnet-stack/demo/object/lsp.h
index 402622c9..0db654f7 100644
--- a/bacnet-stack/demo/object/lsp.h
+++ b/bacnet-stack/demo/object/lsp.h
@@ -69,11 +69,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define LIFE_SAFETY_POINT_OBJ_FUNCTIONS \
- OBJECT_LIFE_SAFETY_POINT, Life_Safety_Point_Init, \
- Life_Safety_Point_Count, Life_Safety_Point_Index_To_Instance, \
- Life_Safety_Point_Valid_Instance, Life_Safety_Point_Object_Name, \
- Life_Safety_Point_Read_Property, \
- Life_Safety_Point_Write_Property, \
- Life_Safety_Point_Property_Lists, NULL, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/ms-input.h b/bacnet-stack/demo/object/ms-input.h
index 4a8fbe2c..9f71311b 100644
--- a/bacnet-stack/demo/object/ms-input.h
+++ b/bacnet-stack/demo/object/ms-input.h
@@ -96,11 +96,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define MULTI_STATE_INPUT_OBJ_FUNCTIONS \
- OBJECT_MULTI_STATE_INPUT, Multistate_Input_Init, \
- Multistate_Input_Count, Multistate_Input_Index_To_Instance, \
- Multistate_Input_Valid_Instance, Multistate_Input_Object_Name, \
- Multistate_Input_Read_Property, \
- Multistate_Input_Write_Property, \
- Multistate_Input_Property_Lists, NULL, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/mso.h b/bacnet-stack/demo/object/mso.h
index 829b2e37..fe9a642b 100644
--- a/bacnet-stack/demo/object/mso.h
+++ b/bacnet-stack/demo/object/mso.h
@@ -71,11 +71,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define MULTI_STATE_OUTPUT_OBJ_FUNCTIONS \
- OBJECT_MULTI_STATE_OUTPUT, Multistate_Output_Init, \
- Multistate_Output_Count, Multistate_Output_Index_To_Instance, \
- Multistate_Output_Valid_Instance, Multistate_Output_Object_Name, \
- Multistate_Output_Read_Property, \
- Multistate_Output_Write_Property, \
- Multistate_Output_Property_Lists, NULL, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/object/nc.h b/bacnet-stack/demo/object/nc.h
index 14552f3f..04c0ea68 100644
--- a/bacnet-stack/demo/object/nc.h
+++ b/bacnet-stack/demo/object/nc.h
@@ -138,10 +138,5 @@ BACnetRecipient ::= CHOICE {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define NOTIFICATION_CLASS_OBJ_FUNCTIONS \
- OBJECT_NOTIFICATION_CLASS, Notification_Class_Init, Notification_Class_Count, \
- Notification_Class_Index_To_Instance, Notification_Class_Valid_Instance, \
- Notification_Class_Object_Name, Notification_Class_Read_Property, \
- Notification_Class_Write_Property, Notification_Class_Property_Lists, \
- NULL, NULL, NULL
+
#endif /* NC_H */
diff --git a/bacnet-stack/demo/object/trendlog.h b/bacnet-stack/demo/object/trendlog.h
index 336686bc..1caef24e 100644
--- a/bacnet-stack/demo/object/trendlog.h
+++ b/bacnet-stack/demo/object/trendlog.h
@@ -197,10 +197,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define TRENDLOG_OBJ_FUNCTIONS \
- OBJECT_TRENDLOG, Trend_Log_Init, Trend_Log_Count, \
- Trend_Log_Index_To_Instance, Trend_Log_Valid_Instance, \
- Trend_Log_Object_Name, Trend_Log_Read_Property, \
- Trend_Log_Write_Property, Trend_Log_Property_Lists, \
- TrendLogGetRRInfo, NULL, NULL
+
#endif
diff --git a/bacnet-stack/demo/ptransfer/Makefile b/bacnet-stack/demo/ptransfer/Makefile
index 3bf45d01..1c2d5b7d 100644
--- a/bacnet-stack/demo/ptransfer/Makefile
+++ b/bacnet-stack/demo/ptransfer/Makefile
@@ -1,37 +1,44 @@
-#Makefile to build BACnet Application for the Linux Port
-
-# tools - only if you need them.
-# Most platforms have this already defined
-# CC = gcc
-
-TARGET = ptransfer
-
-TARGET_BIN = ${TARGET}$(TARGET_EXT)
-
-SRCS = main.c
-
-OBJS = ${SRCS:.c=.o}
-
-all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
-
-${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
- ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
- size $@
- cp $@ ../../bin
-
-lib: ${BACNET_LIB_TARGET}
-
-${BACNET_LIB_TARGET}:
- ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
-
-.c.o:
- ${CC} -c ${CFLAGS} $*.c -o $@
-
-depend:
- rm -f .depend
- ${CC} -MM ${CFLAGS} *.c >> .depend
-
-clean:
- rm -f core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET} $(TARGET).map
-
-include: .depend
+#Makefile to build BACnet Application using GCC compiler
+
+# tools - only if you need them.
+# Most platforms have this already defined
+# CC = gcc
+# AR = ar
+# MAKE = make
+# SIZE = size
+#
+# Assumes rm and cp are available
+
+# Executable file name
+TARGET = ptransfer
+
+TARGET_BIN = ${TARGET}$(TARGET_EXT)
+
+SRCS = main.c \
+ ../object/device-client.c
+
+OBJS = ${SRCS:.c=.o}
+
+all: ${BACNET_LIB_TARGET} Makefile ${TARGET_BIN}
+
+${TARGET_BIN}: ${OBJS} Makefile ${BACNET_LIB_TARGET}
+ ${CC} ${PFLAGS} ${OBJS} ${LFLAGS} -o $@
+ size $@
+ cp $@ ../../bin
+
+lib: ${BACNET_LIB_TARGET}
+
+${BACNET_LIB_TARGET}:
+ ( cd ${BACNET_LIB_DIR} ; $(MAKE) clean ; $(MAKE) )
+
+.c.o:
+ ${CC} -c ${CFLAGS} $*.c -o $@
+
+depend:
+ rm -f .depend
+ ${CC} -MM ${CFLAGS} *.c >> .depend
+
+clean:
+ rm -rf core ${TARGET_BIN} ${OBJS} ${BACNET_LIB_TARGET}
+
+include: .depend
diff --git a/bacnet-stack/demo/ptransfer/main.c b/bacnet-stack/demo/ptransfer/main.c
index 0fbc7425..6d1e1a5e 100644
--- a/bacnet-stack/demo/ptransfer/main.c
+++ b/bacnet-stack/demo/ptransfer/main.c
@@ -68,13 +68,6 @@ uint8_t Send_Private_Transfer_Request(
char block_number,
DATABLOCK * block);
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -132,7 +125,7 @@ void MyRejectHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/ptransfer/makefile.b32 b/bacnet-stack/demo/ptransfer/makefile.b32
index 5bfcb9f5..f9d9fc77 100644
--- a/bacnet-stack/demo/ptransfer/makefile.b32
+++ b/bacnet-stack/demo/ptransfer/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/readfile/Makefile b/bacnet-stack/demo/readfile/Makefile
index 72d28828..235f65c7 100644
--- a/bacnet-stack/demo/readfile/Makefile
+++ b/bacnet-stack/demo/readfile/Makefile
@@ -8,7 +8,8 @@ TARGET = bacarf
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/readfile/main.c b/bacnet-stack/demo/readfile/main.c
index 8b655c2f..5d10af92 100644
--- a/bacnet-stack/demo/readfile/main.c
+++ b/bacnet-stack/demo/readfile/main.c
@@ -50,13 +50,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -186,7 +179,7 @@ static void LocalIAmHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/readfile/makefile.b32 b/bacnet-stack/demo/readfile/makefile.b32
index 759c1d2d..12591afc 100644
--- a/bacnet-stack/demo/readfile/makefile.b32
+++ b/bacnet-stack/demo/readfile/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/readprop/Makefile b/bacnet-stack/demo/readprop/Makefile
index a9dc49a7..836ee012 100644
--- a/bacnet-stack/demo/readprop/Makefile
+++ b/bacnet-stack/demo/readprop/Makefile
@@ -14,7 +14,8 @@ TARGET = bacrp
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/readprop/main.c b/bacnet-stack/demo/readprop/main.c
index e7b1a5c9..1e68f0ee 100644
--- a/bacnet-stack/demo/readprop/main.c
+++ b/bacnet-stack/demo/readprop/main.c
@@ -53,13 +53,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -150,7 +143,7 @@ void My_Read_Property_Ack_Handler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/readprop/makefile.b32 b/bacnet-stack/demo/readprop/makefile.b32
index d1c7d2a9..83181339 100644
--- a/bacnet-stack/demo/readprop/makefile.b32
+++ b/bacnet-stack/demo/readprop/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/readpropm/Makefile b/bacnet-stack/demo/readpropm/Makefile
index 9b7b955c..2d38b8f6 100644
--- a/bacnet-stack/demo/readpropm/Makefile
+++ b/bacnet-stack/demo/readpropm/Makefile
@@ -9,7 +9,8 @@ TARGET = bacrpm
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/readpropm/main.c b/bacnet-stack/demo/readpropm/main.c
index b2be57c0..784ca2b2 100644
--- a/bacnet-stack/demo/readpropm/main.c
+++ b/bacnet-stack/demo/readpropm/main.c
@@ -54,13 +54,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -195,7 +188,7 @@ void My_Read_Property_Multiple_Ack_Handler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/readpropm/makefile.b32 b/bacnet-stack/demo/readpropm/makefile.b32
index d60bdbd2..99dc89f0 100644
--- a/bacnet-stack/demo/readpropm/makefile.b32
+++ b/bacnet-stack/demo/readpropm/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/readrange/main.c b/bacnet-stack/demo/readrange/main.c
index d7e68bd4..140427a6 100644
--- a/bacnet-stack/demo/readrange/main.c
+++ b/bacnet-stack/demo/readrange/main.c
@@ -80,13 +80,6 @@
#define _stricmp stricmp
#endif
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -144,7 +137,7 @@ void MyRejectHandler(
static void Init_Objects(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
}
static void Init_Service_Handlers(
diff --git a/bacnet-stack/demo/reinit/Makefile b/bacnet-stack/demo/reinit/Makefile
index a9609f29..42984e9f 100644
--- a/bacnet-stack/demo/reinit/Makefile
+++ b/bacnet-stack/demo/reinit/Makefile
@@ -9,7 +9,8 @@ TARGET = bacrd
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/reinit/main.c b/bacnet-stack/demo/reinit/main.c
index cb9361b7..c07e9cf6 100644
--- a/bacnet-stack/demo/reinit/main.c
+++ b/bacnet-stack/demo/reinit/main.c
@@ -51,13 +51,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -121,7 +114,7 @@ void MyReinitializeDeviceSimpleAckHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/reinit/makefile.b32 b/bacnet-stack/demo/reinit/makefile.b32
index 71ef2b53..f32dc1c8 100644
--- a/bacnet-stack/demo/reinit/makefile.b32
+++ b/bacnet-stack/demo/reinit/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/scov/Makefile b/bacnet-stack/demo/scov/Makefile
index 4dcaafc4..0b5d70ba 100644
--- a/bacnet-stack/demo/scov/Makefile
+++ b/bacnet-stack/demo/scov/Makefile
@@ -14,7 +14,8 @@ TARGET = bacscov
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/scov/main.c b/bacnet-stack/demo/scov/main.c
index 96c663d8..53a88278 100644
--- a/bacnet-stack/demo/scov/main.c
+++ b/bacnet-stack/demo/scov/main.c
@@ -54,13 +54,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -121,7 +114,7 @@ void MyRejectHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/scov/makefile.b32 b/bacnet-stack/demo/scov/makefile.b32
index 8e42bdb7..4107b3ef 100644
--- a/bacnet-stack/demo/scov/makefile.b32
+++ b/bacnet-stack/demo/scov/makefile.b32
@@ -45,7 +45,8 @@ BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/server/main.c b/bacnet-stack/demo/server/main.c
index 9d7db810..83bf9e0a 100644
--- a/bacnet-stack/demo/server/main.c
+++ b/bacnet-stack/demo/server/main.c
@@ -118,6 +118,9 @@ static void Init_Service_Handlers(
/* handle communication so we can shutup when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
+ /* handle the data coming back from private requests */
+ apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
+ handler_unconfirmed_private_transfer);
#if defined(INTRINSIC_REPORTING)
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM,
handler_alarm_ack);
@@ -202,15 +205,16 @@ int main(
dlenv_maintenance_timer(elapsed_seconds);
Load_Control_State_Machine_Handler();
elapsed_milliseconds = elapsed_seconds * 1000;
- if (dcc_communication_enabled()) {
- handler_cov_task(elapsed_seconds);
- }
+ handler_cov_timer_seconds(elapsed_seconds);
tsm_timer_milliseconds(elapsed_milliseconds);
trend_log_timer(elapsed_seconds);
#if defined(INTRINSIC_REPORTING)
Device_local_reporting();
#endif
}
+ if (dcc_communication_enabled()) {
+ handler_cov_task();
+ }
/* scan cache address */
address_binding_tmr += elapsed_seconds;
if (address_binding_tmr >= 60) {
diff --git a/bacnet-stack/demo/timesync/Makefile b/bacnet-stack/demo/timesync/Makefile
index ef39a83c..28ce9043 100644
--- a/bacnet-stack/demo/timesync/Makefile
+++ b/bacnet-stack/demo/timesync/Makefile
@@ -9,7 +9,8 @@ TARGET = bacts
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/timesync/main.c b/bacnet-stack/demo/timesync/main.c
index 5b178b2d..0625c78c 100644
--- a/bacnet-stack/demo/timesync/main.c
+++ b/bacnet-stack/demo/timesync/main.c
@@ -46,13 +46,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -93,7 +86,7 @@ void MyRejectHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/timesync/makefile.b32 b/bacnet-stack/demo/timesync/makefile.b32
index b53157d3..2b676438 100644
--- a/bacnet-stack/demo/timesync/makefile.b32
+++ b/bacnet-stack/demo/timesync/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/ucov/Makefile b/bacnet-stack/demo/ucov/Makefile
index 395aec7a..703cd74f 100644
--- a/bacnet-stack/demo/ucov/Makefile
+++ b/bacnet-stack/demo/ucov/Makefile
@@ -9,7 +9,8 @@ TARGET = bacucov
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/ucov/main.c b/bacnet-stack/demo/ucov/main.c
index 052d9727..c2148b2a 100644
--- a/bacnet-stack/demo/ucov/main.c
+++ b/bacnet-stack/demo/ucov/main.c
@@ -50,17 +50,10 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/ucov/makefile.b32 b/bacnet-stack/demo/ucov/makefile.b32
index 6f416712..c590cbb0 100644
--- a/bacnet-stack/demo/ucov/makefile.b32
+++ b/bacnet-stack/demo/ucov/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/uptransfer/Makefile b/bacnet-stack/demo/uptransfer/Makefile
index eb43cc87..9d3b38b1 100644
--- a/bacnet-stack/demo/uptransfer/Makefile
+++ b/bacnet-stack/demo/uptransfer/Makefile
@@ -14,7 +14,8 @@ TARGET = bacupt
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/uptransfer/main.c b/bacnet-stack/demo/uptransfer/main.c
index cedb4b4d..344dc6ab 100644
--- a/bacnet-stack/demo/uptransfer/main.c
+++ b/bacnet-stack/demo/uptransfer/main.c
@@ -54,13 +54,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -124,74 +117,10 @@ void MyRejectHandler(
}
}
-void MyUnconfirmedPrivateTransferHandler(
- uint8_t * service_request,
- uint16_t service_len,
- BACNET_ADDRESS * src)
-{
- BACNET_PRIVATE_TRANSFER_DATA private_data;
- BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
- BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
- int len = 0;
- uint8_t *application_data;
- int application_data_len;
- bool first_value = true;
- bool print_brace = false;
-
- len = ptransfer_decode_service_request(
- service_request, service_len, &private_data);
- if (len >= 0) {
- printf("PrivateTransfer:vendorID=%u\r\n",
- (unsigned)private_data.vendorID);
- printf("PrivateTransfer:serviceNumber=%lu\r\n",
- (unsigned long)private_data.serviceNumber);
- application_data = private_data.serviceParameters;
- application_data_len = private_data.serviceParametersLen;
- for (;;) {
- len =
- bacapp_decode_application_data(application_data,
- (uint8_t) application_data_len, &value);
- if (first_value && (len < application_data_len)) {
- first_value = false;
-#if PRINT_ENABLED
- fprintf(stdout, "{");
-#endif
- print_brace = true;
- }
- /* private transfer doesn't provide any clues */
- object_value.object_type = MAX_BACNET_OBJECT_TYPE;
- object_value.object_instance = BACNET_MAX_INSTANCE;
- object_value.object_property = MAX_BACNET_PROPERTY_ID;
- object_value.array_index = BACNET_ARRAY_ALL;
- object_value.value = &value;
- bacapp_print_value(stdout, &object_value);
- if (len > 0) {
- if (len < application_data_len) {
- application_data += len;
- application_data_len -= len;
- /* there's more! */
-#if PRINT_ENABLED
- fprintf(stdout, ",");
-#endif
- } else {
- break;
- }
- } else {
- break;
- }
- }
-#if PRINT_ENABLED
- if (print_brace)
- fprintf(stdout, "}");
- fprintf(stdout, "\r\n");
-#endif
- }
-}
-
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
@@ -204,9 +133,9 @@ static void Init_Service_Handlers(
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
- /* handle the data coming back from confirmed requests */
+ /* handle the data coming back from requests */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_PRIVATE_TRANSFER,
- MyUnconfirmedPrivateTransferHandler);
+ handler_unconfirmed_private_transfer);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
diff --git a/bacnet-stack/demo/uptransfer/makefile.b32 b/bacnet-stack/demo/uptransfer/makefile.b32
index 16bec5df..a77d4123 100644
--- a/bacnet-stack/demo/uptransfer/makefile.b32
+++ b/bacnet-stack/demo/uptransfer/makefile.b32
@@ -45,7 +45,8 @@ BUILD_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BUILD_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/whohas/Makefile b/bacnet-stack/demo/whohas/Makefile
index 51125e75..57387a3e 100644
--- a/bacnet-stack/demo/whohas/Makefile
+++ b/bacnet-stack/demo/whohas/Makefile
@@ -9,7 +9,8 @@ TARGET = bacwh
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/whohas/main.c b/bacnet-stack/demo/whohas/main.c
index 859133e2..7bb936eb 100644
--- a/bacnet-stack/demo/whohas/main.c
+++ b/bacnet-stack/demo/whohas/main.c
@@ -50,13 +50,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -96,7 +89,7 @@ void MyRejectHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/whohas/makefile.b32 b/bacnet-stack/demo/whohas/makefile.b32
index a800fa12..c0f93de9 100644
--- a/bacnet-stack/demo/whohas/makefile.b32
+++ b/bacnet-stack/demo/whohas/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/whois/Makefile b/bacnet-stack/demo/whois/Makefile
index 00ef02f2..2c117481 100644
--- a/bacnet-stack/demo/whois/Makefile
+++ b/bacnet-stack/demo/whois/Makefile
@@ -8,7 +8,8 @@ TARGET = bacwi
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/whois/main.c b/bacnet-stack/demo/whois/main.c
index 72f26714..77d75975 100644
--- a/bacnet-stack/demo/whois/main.c
+++ b/bacnet-stack/demo/whois/main.c
@@ -50,13 +50,6 @@
#endif
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -97,7 +90,7 @@ void MyRejectHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* Note: this applications doesn't need to handle who-is
it is confusing for the user! */
/* set the handler for all the services we don't implement
diff --git a/bacnet-stack/demo/whois/makefile.b32 b/bacnet-stack/demo/whois/makefile.b32
index d4737449..468ffda6 100644
--- a/bacnet-stack/demo/whois/makefile.b32
+++ b/bacnet-stack/demo/whois/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/whoisrouter/Makefile b/bacnet-stack/demo/whoisrouter/Makefile
index 585f238a..ae264288 100644
--- a/bacnet-stack/demo/whoisrouter/Makefile
+++ b/bacnet-stack/demo/whoisrouter/Makefile
@@ -8,7 +8,8 @@ TARGET = bacwir
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/whoisrouter/main.c b/bacnet-stack/demo/whoisrouter/main.c
index a5b8249a..a3b741eb 100644
--- a/bacnet-stack/demo/whoisrouter/main.c
+++ b/bacnet-stack/demo/whoisrouter/main.c
@@ -51,12 +51,6 @@
#endif
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -175,7 +169,7 @@ void My_NPDU_Handler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/whoisrouter/makefile.b32 b/bacnet-stack/demo/whoisrouter/makefile.b32
index 9a45d15a..18be31d4 100644
--- a/bacnet-stack/demo/whoisrouter/makefile.b32
+++ b/bacnet-stack/demo/whoisrouter/makefile.b32
@@ -42,7 +42,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/writefile/Makefile b/bacnet-stack/demo/writefile/Makefile
index 6d212166..f26b1fe4 100644
--- a/bacnet-stack/demo/writefile/Makefile
+++ b/bacnet-stack/demo/writefile/Makefile
@@ -9,7 +9,8 @@ TARGET = bacawf
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/writefile/main.c b/bacnet-stack/demo/writefile/main.c
index 30836d79..4cfcafeb 100644
--- a/bacnet-stack/demo/writefile/main.c
+++ b/bacnet-stack/demo/writefile/main.c
@@ -50,13 +50,6 @@
#include "txbuf.h"
#include "dlenv.h"
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -140,7 +133,7 @@ static void LocalIAmHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/writefile/makefile.b32 b/bacnet-stack/demo/writefile/makefile.b32
index 3a623ed9..61f92549 100644
--- a/bacnet-stack/demo/writefile/makefile.b32
+++ b/bacnet-stack/demo/writefile/makefile.b32
@@ -41,7 +41,8 @@ BACNET_DEFINES = -DPRINT_ENABLED=1 -DBACAPP_ALL
BACDL_DEFINE=-DBACDL_BIP=1 -DUSE_INADDR=1
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/demo/writeprop/Makefile b/bacnet-stack/demo/writeprop/Makefile
index 2667a8c4..5a9587f7 100644
--- a/bacnet-stack/demo/writeprop/Makefile
+++ b/bacnet-stack/demo/writeprop/Makefile
@@ -9,7 +9,8 @@ TARGET = bacwp
TARGET_BIN = ${TARGET}$(TARGET_EXT)
-SRCS = main.c
+SRCS = main.c \
+ ../object/device-client.c
OBJS = ${SRCS:.c=.o}
diff --git a/bacnet-stack/demo/writeprop/main.c b/bacnet-stack/demo/writeprop/main.c
index 4a835547..61bca2b5 100644
--- a/bacnet-stack/demo/writeprop/main.c
+++ b/bacnet-stack/demo/writeprop/main.c
@@ -56,13 +56,6 @@
#define MAX_PROPERTY_VALUES 64
#endif
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL}
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -141,7 +134,7 @@ void MyWritePropertySimpleAckHandler(
static void Init_Service_Handlers(
void)
{
- Device_Init(&Object_Table[0]);
+ Device_Init(NULL);
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
diff --git a/bacnet-stack/demo/writeprop/makefile.b32 b/bacnet-stack/demo/writeprop/makefile.b32
index 567b7401..2ce1d2f5 100644
--- a/bacnet-stack/demo/writeprop/makefile.b32
+++ b/bacnet-stack/demo/writeprop/makefile.b32
@@ -45,7 +45,8 @@ WRITEPROPS_DEFINE = -DMAX_PROPERTY_VALUES=64
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(WRITEPROPS_DEFINE)
-SRCS = main.c
+SRCS = main.c \
+ $(BACNET_OBJECT)\device-client.c
OBJS = $(SRCS:.c=.obj)
diff --git a/bacnet-stack/include/handlers.h b/bacnet-stack/include/handlers.h
index 1d6a743f..6d47d4e4 100644
--- a/bacnet-stack/include/handlers.h
+++ b/bacnet-stack/include/handlers.h
@@ -215,7 +215,8 @@ extern "C" {
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
- void handler_cov_task(
+ void handler_cov_task(void);
+ void handler_cov_timer_seconds(
uint32_t elapsed_seconds);
void handler_cov_init(
void);
diff --git a/bacnet-stack/ports/win32/main.c b/bacnet-stack/ports/win32/main.c
index 61505952..24bf9333 100644
--- a/bacnet-stack/ports/win32/main.c
+++ b/bacnet-stack/ports/win32/main.c
@@ -59,26 +59,6 @@
#include "bacfile.h"
#endif
-/* All included BACnet objects */
-static object_functions_t Object_Table[] = {
- {DEVICE_OBJ_FUNCTIONS},
- {ANALOG_INPUT_OBJ_FUNCTIONS},
- {ANALOG_OUTPUT_OBJ_FUNCTIONS},
- {ANALOG_VALUE_OBJ_FUNCTIONS},
- {BINARY_INPUT_OBJ_FUNCTIONS},
- {BINARY_OUTPUT_OBJ_FUNCTIONS},
- {BINARY_VALUE_OBJ_FUNCTIONS},
- {LIFE_SAFETY_POINT_OBJ_FUNCTIONS},
- {LOAD_CONTROL_OBJ_FUNCTIONS},
- {MULTI_STATE_OUTPUT_OBJ_FUNCTIONS},
- {MULTI_STATE_INPUT_OBJ_FUNCTIONS},
- {TRENDLOG_OBJ_FUNCTIONS},
-#if defined(BACFILE)
- {FILE_OBJ_FUNCTIONS},
-#endif
- {MAX_BACNET_OBJECT_TYPE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
-};
-
/* buffer used for receive */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
@@ -189,8 +169,7 @@ static void LocalIAmHandler(
static void Init_Service_Handlers(
void)
{
- Device_Initialize_Object_Functions(&Object_Table[0]);
- Device_Init();
+ Device_Init(NULL);
/* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);