Add facility to adjust the services and and other features supported via config.h. This is to reduce code size in embedded builds where the compiler does not do a great job in removing functions that are never called. This is particularly useful for simple server only applications where decoding of response packets and encoding of requests are not required for example.

Also added possibility for RMP of encoding large items in-line in the response packet so that the object RP handlers know how much space they really have without the need for a full APDU buffer being maintained.
This commit is contained in:
petermcs
2012-04-30 10:14:18 +00:00
parent 44055ff37f
commit 2e51778790
17 changed files with 148 additions and 17 deletions
+83
View File
@@ -160,4 +160,87 @@
#define MAX_OCTET_STRING_BYTES (MAX_APDU-6)
#endif
/*
** Control the selection of services etc to enable code size reduction for those
** compiler suites which do not handle removing of unused functions in modules
** so well.
**
** We will start with the A type services code first as these are least likely
** to be required in embedded systems using the stack.
*/
/*
** First we see if this is a test build and enable all the services as they
** may be required.
**
** Note: I've left everything enabled here in the main config.h. You would
** use a local copy of config.h with settings configured for your needs to
** make use of the code space reductions.
**/
#ifdef TEST
#define BACNET_SVC_I_HAVE_A 1
#define BACNET_SVC_WP_A 1
#define BACNET_SVC_RP_A 1
#define BACNET_SVC_RPM_A 1
#define BACNET_SVC_DCC_A 1
#define BACNET_SVC_RD_A 1
#define BACNET_SVC_SERVER 0
#define BACNET_USE_OCTETSTRING 1
#define BACNET_USE_DOUBLE 1
#define BACNET_USE_SIGNED 1
#else /* Otherwise define our working set - all enabled here to avoid breaking things */
#define BACNET_SVC_I_HAVE_A 1
#define BACNET_SVC_WP_A 1
#define BACNET_SVC_RP_A 1
#define BACNET_SVC_RPM_A 1
#define BACNET_SVC_DCC_A 1
#define BACNET_SVC_RD_A 1
#define BACNET_SVC_SERVER 0
#define BACNET_USE_OCTETSTRING 1
#define BACNET_USE_DOUBLE 1
#define BACNET_USE_SIGNED 1
#endif
/* Do them one by one */
#ifndef BACNET_SVC_I_HAVE_A /* Do we send I_Have requests? */
#define BACNET_SVC_I_HAVE_A 0
#endif
#ifndef BACNET_SVC_WP_A /* Do we send WriteProperty requests? */
#define BACNET_SVC_WP_A 0
#endif
#ifndef BACNET_SVC_RP_A /* Do we send ReadProperty requests? */
#define BACNET_SVC_RP_A 0
#endif
#ifndef BACNET_SVC_RPM_A /* Do we send ReadPropertyMultiple requests? */
#define BACNET_SVC_RPM_A 0
#endif
#ifndef BACNET_SVC_DCC_A /* Do we send DeviceCommunicationControl requests? */
#define BACNET_SVC_DCC_A 0
#endif
#ifndef BACNET_SVC_RD_A /* Do we send ReinitialiseDevice requests? */
#define BACNET_SVC_RD_A 0
#endif
#ifndef BACNET_SVC_SERVER /* Are we a pure server type device? */
#define BACNET_SVC_SERVER 1
#endif
#ifndef BACNET_USE_OCTETSTRING /* Do we need any octet strings? */
#define BACNET_USE_OCTETSTRING 0
#endif
#ifndef BACNET_USE_DOUBLE /* Do we need any doubles? */
#define BACNET_USE_DOUBLE 0
#endif
#ifndef BACNET_USE_SIGNED /* Do we need any signed integers */
#define BACNET_USE_SIGNED 0
#endif
#endif
+2
View File
@@ -97,6 +97,7 @@ int abort_encode_apdu(
return apdu_len;
}
#if !BACNET_SVC_SERVER
/* decode the service request only */
int abort_decode_service_request(
uint8_t * apdu,
@@ -115,6 +116,7 @@ int abort_decode_service_request(
return len;
}
#endif
#ifdef TEST
#include <assert.h>
+4
View File
@@ -49,6 +49,10 @@
/** @file bacapp.c Utilities for the BACnet_Application_Data_Value */
#if defined(_MSC_VER)
#define snprintf _snprintf
#endif
int bacapp_encode_application_data(
uint8_t * apdu,
BACNET_APPLICATION_DATA_VALUE * value)
+7
View File
@@ -866,6 +866,8 @@ int encode_application_object_id(
return len;
}
#if BACNET_USE_OCTETSTRING
/* from clause 20.2.8 Encoding of an Octet String Value */
/* returns the number of apdu bytes consumed */
int encode_octet_string(
@@ -981,6 +983,7 @@ int decode_context_octet_string(
return len;
}
#endif
/* from clause 20.2.9 Encoding of a Character String Value */
/* returns the number of apdu bytes consumed */
@@ -1305,6 +1308,7 @@ int encode_context_enumerated(
return len;
}
#if BACNET_USE_SIGNED
/* from clause 20.2.5 Encoding of a Signed Integer Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -1425,6 +1429,7 @@ int encode_context_signed(
return len;
}
#endif
/* from clause 20.2.6 Encoding of a Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
@@ -1457,6 +1462,7 @@ int encode_context_real(
return len;
}
#if BACNET_USE_DOUBLE
/* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
@@ -1489,6 +1495,7 @@ int encode_context_double(
return len;
}
#endif
/* from clause 20.2.13 Encoding of a Time Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
+2
View File
@@ -63,6 +63,7 @@ int bacerror_encode_apdu(
return apdu_len;
}
#if !BACNET_SVC_SERVER
/* decode the application class and code */
int bacerror_decode_error_class_and_code(
uint8_t * apdu,
@@ -123,6 +124,7 @@ int bacerror_decode_service_request(
return len;
}
#endif
#ifdef TEST
#include <assert.h>
+2 -1
View File
@@ -113,6 +113,7 @@ int decode_unsigned32(
return 4;
}
#if BACNET_USE_SIGNED
int encode_signed8(
uint8_t * apdu,
int8_t value)
@@ -219,7 +220,7 @@ int decode_signed32(
return 4;
}
#endif
/* end of decoding_encoding.c */
#ifdef TEST
#include <assert.h>
+3
View File
@@ -138,6 +138,8 @@ int encode_bacnet_real(
return 4;
}
#if BACNET_USE_DOUBLE
/* from clause 20.2.7 Encoding of a Double Precision Real Number Value */
/* returns the number of apdu bytes consumed */
int decode_double(
@@ -241,6 +243,7 @@ int decode_context_double(
}
return len;
}
#endif
/* end of decoding_encoding.c */
#ifdef TEST
+2
View File
@@ -615,6 +615,7 @@ bool characterstring_valid(
return valid;
}
#if BACNET_USE_OCTETSTRING
/* returns false if the string exceeds capacity
initialize by using value=NULL */
bool octetstring_init(
@@ -799,6 +800,7 @@ bool octetstring_value_same(
return false;
}
#endif
#ifdef TEST
#include <assert.h>
+2 -1
View File
@@ -124,7 +124,7 @@ bool dcc_set_status_duration(
return valid;
}
#if BACNET_SVC_DCC_A
/* encode service */
int dcc_encode_apdu(
uint8_t * apdu,
@@ -161,6 +161,7 @@ int dcc_encode_apdu(
return apdu_len;
}
#endif
/* decode the service request only */
int dcc_decode_service_request(
+3
View File
@@ -70,6 +70,8 @@ int ihave_encode_apdu(
return apdu_len;
}
#if BACNET_SVC_I_HAVE_A
/* decode the service request only */
int ihave_decode_service_request(
uint8_t * apdu,
@@ -135,6 +137,7 @@ int ihave_decode_apdu(
return len;
}
#endif
#ifdef TEST
#include <assert.h>
+13 -10
View File
@@ -33,6 +33,7 @@
####COPYRIGHTEND####*/
#include <stddef.h>
#include "memcopy.h"
#include <string.h>
/** @file memcopy.c Custom memcopy function */
@@ -45,20 +46,22 @@ size_t memcopy(
size_t len, /* amount of data to copy */
size_t max)
{ /* total size of destination */
size_t i;
size_t copy_len = 0;
char *s1, *s2;
// size_t i;
// size_t copy_len = 0;
// char *s1, *s2;
s1 = dest;
s2 = src;
// s1 = dest;
// s2 = src;
if (len <= (max - offset)) {
for (i = 0; i < len; i++) {
s1[offset + i] = s2[i];
copy_len++;
}
memcpy(&((char *)dest)[offset], src, len);
return(len);
// for (i = 0; i < len; i++) {
// s1[offset + i] = s2[i];
// copy_len++;
// }
}
return copy_len;
return 0;
}
#ifdef TEST
+2 -1
View File
@@ -38,7 +38,7 @@
#include "rd.h"
/** @file rd.c Encode/Decode Reinitialize Device APDUs */
#if BACNET_SVC_RD_A
/* encode service */
int rd_encode_apdu(
uint8_t * apdu,
@@ -68,6 +68,7 @@ int rd_encode_apdu(
return apdu_len;
}
#endif
/* decode the service request only */
int rd_decode_service_request(
+2
View File
@@ -110,6 +110,7 @@ int reject_encode_apdu(
return apdu_len;
}
#if !BACNET_SVC_SERVER
/* decode the service request only */
int reject_decode_service_request(
uint8_t * apdu,
@@ -128,6 +129,7 @@ int reject_decode_service_request(
return len;
}
#endif
#ifdef TEST
#include <assert.h>
+4
View File
@@ -39,6 +39,7 @@
/** @file rp.c Encode/Decode Read Property and RP ACKs */
#if BACNET_SVC_RP_A
/* encode service */
int rp_encode_apdu(
uint8_t * apdu,
@@ -73,6 +74,7 @@ int rp_encode_apdu(
return apdu_len;
}
#endif
/* decode the service request only */
int rp_decode_service_request(
@@ -213,6 +215,7 @@ int rp_ack_encode_apdu(
}
#if BACNET_SVC_RP_A
/** Decode the ReadProperty reply and store the result for one Property in a
* BACNET_READ_PROPERTY_DATA structure.
* This leaves the value(s) in the application_data buffer to be decoded later;
@@ -275,6 +278,7 @@ int rp_ack_decode_service_request(
return len;
}
#endif
#ifdef TEST
#include <assert.h>
+13 -2
View File
@@ -42,6 +42,7 @@
/** @file rpm.c Encode/Decode Read Property Multiple and RPM ACKs */
#if BACNET_SVC_RPM_A
/* encode the initial portion of the service */
int rpm_encode_apdu_init(
uint8_t * apdu,
@@ -199,6 +200,8 @@ int rpm_encode_apdu(
return apdu_len;
}
#endif
/* decode the object portion of the service request only. Bails out if
* tags are wrong or missing/incomplete
*/
@@ -379,8 +382,12 @@ int rpm_ack_encode_apdu_object_property_value(
if (apdu) {
/* Tag 4: propertyValue */
apdu_len += encode_opening_tag(&apdu[apdu_len], 4);
for (len = 0; len < application_data_len; len++) {
apdu[apdu_len++] = application_data[len];
if (application_data == &apdu[apdu_len]) { /* Is Data already in place? */
apdu_len += application_data_len; /* Yes, step over data */
} else { /* No, copy data in */
for (len = 0; len < application_data_len; len++) {
apdu[apdu_len++] = application_data[len];
}
}
apdu_len += encode_closing_tag(&apdu[apdu_len], 4);
}
@@ -419,6 +426,8 @@ int rpm_ack_encode_apdu_object_end(
return apdu_len;
}
#if BACNET_SVC_RPM_A
/* decode the object portion of the service request only */
int rpm_ack_decode_object_id(
uint8_t * apdu,
@@ -509,6 +518,8 @@ int rpm_ack_decode_object_property(
return (int) len;
}
#endif
#ifdef TEST
#include <assert.h>
#include <string.h>
+2 -1
View File
@@ -39,7 +39,7 @@
#include "timesync.h"
/** @file timesync.c Encode/Decode TimeSync APDUs */
#if BACNET_SVC_TS_A
/* encode service */
int timesync_encode_apdu_service(
uint8_t * apdu,
@@ -80,6 +80,7 @@ int timesync_encode_apdu(
return timesync_encode_apdu_service(apdu,
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION, my_date, my_time);
}
#endif
/* decode the service request only */
int timesync_decode_service_request(
+2 -1
View File
@@ -38,7 +38,7 @@
#include "wp.h"
/** @file wp.c Encode/Decode BACnet Write Property APDUs */
#if BACNET_SVC_WP_A
/* encode service */
int wp_encode_apdu(
uint8_t * apdu,
@@ -88,6 +88,7 @@ int wp_encode_apdu(
return apdu_len;
}
#endif
/* decode the service request only */
/* FIXME: there could be various error messages returned