Commented the demo/server in a new module.

Embedded its PICS in the server documentation (hopefully a good idea).
Added a PrettyPrintPropertyValue() function to the epics program (hopefully OK format).
Added a function apdu_service_supported_to_index() to the apdu code to translate a SERVICE_SUPPORTED_ enum to its SERVICE_CONFIRMED_ or SERVICE_UNCONFIRMED_ index, and used it when PrettyPrinting services.
This commit is contained in:
tbrennan3
2010-03-23 04:55:11 +00:00
parent 35f0a52d51
commit 5a99f0662c
4 changed files with 218 additions and 2 deletions
+86 -1
View File
@@ -135,6 +135,85 @@ void MyRejectHandler(
Error_Detected = true;
}
/** Provide a nicer output for Supported Services and Object Types.
*
* @param stream
* @param value
* @param property
* @return
*/
bool PrettyPrintPropertyValue(
FILE * stream,
BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property)
{
bool status = true; /*return value */
size_t len = 0, i = 0, j = 0;
if ( (value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING) &&
( (property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) ||
(property == PROP_PROTOCOL_SERVICES_SUPPORTED) ) )
{
len = bitstring_bits_used(&value->type.Bit_String);
fprintf(stream, "{ \r\n ");
for (i = 0; i < len; i++) {
fprintf(stream, "%s",
bitstring_bit(&value->type.Bit_String,
(uint8_t) i) ? " true" : "false");
if (i < len - 1)
fprintf(stream, ",");
else
fprintf(stream, " ");
if ( (i == (len-1) ) || ( (i % 8) == 7 ) ) // line break every 8
{
fprintf(stream, " # ");
// Now rerun the same 8 bits, but print labels for true ones
for ( j = i - (i%8); j <= i; j++)
{
if ( bitstring_bit(&value->type.Bit_String, (uint8_t) j) )
{
if (property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED)
fprintf( stream, " %s,", bactext_object_type_name(j) );
// PROP_PROTOCOL_SERVICES_SUPPORTED
else
{
bool bIsConfirmed;
size_t newIndex;
if ( apdu_service_supported_to_index( j,
&newIndex, &bIsConfirmed ) )
{
if ( bIsConfirmed )
fprintf( stream, " %s,",
bactext_confirmed_service_name(newIndex) );
else
fprintf( stream, " %s,",
bactext_unconfirmed_service_name(
(newIndex) ) );
}
}
}
else // not supported
fprintf( stream, "," );
}
fprintf(stream, "\r\n ");
}
}
fprintf(stream, "}");
}
else
{
/* How did I get here? Fix your code. */
/* Meanwhile, a safe fallback plan */
status = bacapp_print_value(stdout, value, property);
}
return status;
}
void PrintReadPropertyData(
BACNET_READ_PROPERTY_DATA * data)
{
@@ -198,7 +277,13 @@ void PrintReadPropertyData(
fprintf(stdout, "\r\n");
}
}
} else {
}
else if ( (data->object_property == PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED) ||
(data->object_property == PROP_PROTOCOL_SERVICES_SUPPORTED) )
{
PrettyPrintPropertyValue(stdout, &value, data->object_property);
}
else {
bacapp_print_value(stdout, &value, data->object_property);
}
if (len) {
+79 -1
View File
@@ -52,9 +52,76 @@
/** @file server/main.c Example server application using the BACnet Stack */
/* buffers used for receiving */
/** @defgroup Demos Demos of Servers and Clients
* Most of the folders under the /demo folder contain demonstration (ie, sample)
* code that implements the name functionality.
*
* The exceptions to this general rule, /handler and /object folders, are
* described in the various BIBBs and Object Framework modules.
*/
/** @defgroup ServerDemo Demo of a BACnet Server (Device)
* @ingroup Demos
* This is a basic demonstration of a simple BACnet Device consisting of
* the services and properties shown in its PICS (output provided by
* the demo/epics/epics program):
* @verbatim
List of Objects in test device:
{
object-identifier: (Device, 1234)
object-name: "SimpleServer"
object-type: Device
system-status: operational
vendor-name: "BACnet Stack at SourceForge"
vendor-identifier: 260
model-name: "GNU"
firmware-version: "0.5.5"
application-software-version: "1.0"
protocol-version: 1
protocol-revision: 5
protocol-services-supported: {
false,false,false,false,false, true, true, true, # ,,,,, Subscribe-COV, Atomic-Read-File, Atomic-Write-File,
false,false,false,false, true,false, true, true, # ,,,, Read-Property,, Read-Property-Multiple, Write-Property,
false, true,false,false, true,false,false,false, # , Device-Communication-Control,,, Reinitialize-Device,,,,
false,false,false,false, true,false,false,false, # ,,,, COV-Notification,,,,
true, true, true,false, true,false,false,false # Time-Synchronization, Who-Has, Who-Is,, UTC-Time-Synchronization,,,,
}
protocol-object-types-supported: {
true, true, true, true, true, true,false,false, # Analog Input, Analog Output, Analog Value, Binary Input, Binary Output, Binary Value,,,
true,false, true,false,false, true, true,false, # Device,, File,,, Multi-State Input, Multi-State Output,,
false,false,false,false, true, true,false,false, # ,,,, Trendlog, Life Safety Point,,,
false,false,false,false, true,false,false,false, # ,,,, Load-Control,,,,
false,false,false,false,false,false # ,,,,,,
}
object-list: {(Device, 1234),(Analog Input, 0),(Analog Input, 1),
(Analog Input, 2),(Analog Input, 3),(Analog Output, 0),(Analog Output, 1),
(Analog Output, 2),(Analog Output, 3),(Analog Value, 0),(Analog Value, 1),
(Analog Value, 2),(Analog Value, 3),(Binary Input, 0),(Binary Input, 1),
(Binary Input, 2),(Binary Input, 3),(Binary Input, 4),(Binary Output, 0),
(Binary Output, 1),(Binary Output, 2),(Binary Output, 3),(Binary Value, 0),
(Binary Value, 1),(Binary Value, 2),(Binary Value, 3),(Binary Value, 4),
(Binary Value, 5),(Binary Value, 6),(Binary Value, 7),(Binary Value, 8),
(Binary Value, 9),(Life Safety Point, 0),(Life Safety Point, 1),(Life Safety Point, 2),
(Life Safety Point, 3),(Life Safety Point, 4),(Life Safety Point, 5),(Life Safety Point, 6),
(Load-Control, 0),(Load-Control, 1),(Load-Control, 2),(Load-Control, 3),
(Multi-State Output, 0),(Multi-State Output, 1),(Multi-State Output, 2),(Multi-State Output, 3),
(Multi-State Input, 0),(Trendlog, 0),(Trendlog, 1),(Trendlog, 2),
(Trendlog, 3),(Trendlog, 4),(Trendlog, 5),(Trendlog, 6),
(Trendlog, 7),(File, 0),(File, 1),(File, 2)}
max-apdu-length-accepted: 1476
segmentation-supported: no-segmentation
apdu-timeout: 3000
number-of-APDU-retries: 3
device-address-binding: Null
database-revision: 1
} @endverbatim
*/
/*@{*/
/** Buffer used for receiving */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/** Initialize the handlers we will utilize. */
static void Init_Service_Handlers(
void)
{
@@ -95,12 +162,21 @@ static void Init_Service_Handlers(
handler_device_communication_control);
}
/** Handler registered with atexit() inside main function to, well, cleanup.
* Especially if we don't end normally.
*/
static void cleanup(
void)
{
datalink_cleanup();
}
/** Main function of server demo.
*
* @param argc [in] Arg count.
* @param argv [in] Takes one argument: the Device Instance #.
* @return 0 on success.
*/
int main(
int argc,
char *argv[])
@@ -158,3 +234,5 @@ int main(
/* blink LEDs, Turn on or off outputs, etc */
}
}
/*@}*/ /* End group ServerDemo */
+9
View File
@@ -158,6 +158,15 @@ extern "C" {
bool apdu_service_supported(
BACNET_SERVICES_SUPPORTED service_supported);
/* Function to translate a SERVICE_SUPPORTED_ enum to its SERVICE_CONFIRMED_
* or SERVICE_UNCONFIRMED_ index.
*/
bool apdu_service_supported_to_index(
BACNET_SERVICES_SUPPORTED service_supported,
size_t *index,
bool *bIsConfirmed );
void apdu_set_error_handler(
BACNET_CONFIRMED_SERVICE service_choice,
error_function pFunction);
+44
View File
@@ -166,6 +166,50 @@ bool apdu_service_supported(
return status;
}
/** Function to translate a SERVICE_SUPPORTED_ enum to its SERVICE_CONFIRMED_
* or SERVICE_UNCONFIRMED_ index.
* Useful with the bactext_confirmed_service_name() functions.
*
* @param service_supported [in] The SERVICE_SUPPORTED_ enum value to convert.
* @param index [out] The SERVICE_CONFIRMED_ or SERVICE_UNCONFIRMED_ index,
* if found.
* @param bIsConfirmed [out] True if index is a SERVICE_CONFIRMED_ type.
* @return True if a match was found and index and bIsConfirmed are valid.
*/
bool apdu_service_supported_to_index(
BACNET_SERVICES_SUPPORTED service_supported,
size_t *index,
bool *bIsConfirmed )
{
int i = 0;
*bIsConfirmed = false;
bool found = false;
if (service_supported < MAX_BACNET_SERVICES_SUPPORTED) {
/* is it a confirmed service? */
for (i = 0; i < MAX_BACNET_CONFIRMED_SERVICE; i++) {
if (confirmed_service_supported[i] == service_supported) {
found = true;
*index = i;
*bIsConfirmed = true;
break;
}
}
if (!found) {
/* is it an unconfirmed service? */
for (i = 0; i < MAX_BACNET_UNCONFIRMED_SERVICE; i++) {
if (unconfirmed_service_supported[i] == service_supported) {
found = true;
*index = i;
break;
}
}
}
}
return found;
}
/* Confirmed ACK Function Handlers */
static void *Confirmed_ACK_Function[MAX_BACNET_CONFIRMED_SERVICE];