adding read property service

This commit is contained in:
skarg
2005-03-23 23:09:04 +00:00
parent a67cadf94f
commit 66f3cb4a00
8 changed files with 212 additions and 19 deletions
+16 -2
View File
@@ -675,12 +675,13 @@ typedef enum
SERVICE_CONFIRMED_VT_DATA = 23,
// Security Services
SERVICE_CONFIRMED_AUTHENTICATE = 24,
SERVICE_CONFIRMED_REQUEST_KEY = 25
SERVICE_CONFIRMED_REQUEST_KEY = 25,
// Services added after 1995
// readRange (26) see Object Access Services
// lifeSafetyOperation (27) see Alarm and Event Services
// subscribeCOVProperty (28) see Alarm and Event Services
// getEventInformation (29) see Alarm and Event Services
MAX_BACNET_CONFIRMED_SERVICE = 30
} BACNET_CONFIRMED_SERVICE;
typedef enum {
@@ -693,12 +694,13 @@ typedef enum {
SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION = 6,
SERVICE_UNCONFIRMED_WHO_HAS = 7,
SERVICE_UNCONFIRMED_WHO_IS = 8,
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION = 9
SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION = 9,
// Other services to be added as they are defined.
// All choice values in this production are reserved
// for definition by ASHRAE.
// Proprietary extensions are made by using the
// UnconfirmedPrivateTransfer service. See Clause 23.
MAX_BACNET_UNCONFIRMED_SERVICE = 10
} BACNET_UNCONFIRMED_SERVICE;
typedef enum {
@@ -781,6 +783,9 @@ typedef enum {
// Enumerated values 0-63 are reserved for definition by ASHRAE.
// Enumerated values 64-65535 may be used by others subject to
// the procedures and constraints described in Clause 23.
MAX_BACNET_ABORT_REASON = 5,
FIRST_PROPRIETARY_ABORT_REASON = 64,
LAST_PROPRIETARY_ABORT_REASON = 65535
} BACNET_ABORT_REASON;
typedef enum {
@@ -797,6 +802,9 @@ typedef enum {
// Enumerated values 0-63 are reserved for definition by ASHRAE.
// Enumerated values 64-65535 may be used by others subject to
// the procedures and constraints described in Clause 23.
MAX_BACNET_REJECT_REASON = 10,
FIRST_PROPRIETARY_REJECT_REASON = 64,
LAST_PROPRIETARY_REJECT_REASON = 65535
} BACNET_BACNET_REJECT_REASON;
typedef enum {
@@ -810,6 +818,9 @@ typedef enum {
// Enumerated values 0-63 are reserved for definition by ASHRAE.
// Enumerated values 64-65535 may be used by others subject to
// the procedures and constraints described in Clause 23.
MAX_BACNET_ERROR_CLASS = 7,
FIRST_PROPRIETARY_ERROR_CLASS = 64,
LAST_PROPRIETARY_ERROR_CLASS = 65535
} BACNET_ERROR_CLASS;
typedef enum {
@@ -868,6 +879,9 @@ typedef enum {
// Enumerated values 256-65535 may be used by others subject to
// the procedures and constraints described in Clause 23.
// The last enumeration used in this version is 46.
MAX_BACNET_ERROR_CODE = 47,
FIRST_PROPRIETARY_ERROR_CODE = 256,
LAST_PROPRIETARY_ERROR_CODE = 65535
} BACNET_ERROR_CODE;
#endif // end of BACENUM_H
+152 -1
View File
@@ -39,6 +39,11 @@
#include "bacenum.h"
#include "config.h" // the custom stuff
// vendor id assigned by ASHRAE
static uint32_t Object_Identifier = 0;
// FIXME: it is likely that this name is configurable,
// so consider a fixed sized string
static const char *Object_Name = "SimpleServer";
static BACNET_DEVICE_STATUS System_Status = STATUS_OPERATIONAL;
static const char *Vendor_Name = "ASHRAE";
static uint16_t Vendor_Identifier = 0;
@@ -81,7 +86,17 @@ static uint8_t Database_Revision = 0;
//Profile_Name
// methods to manipulate the data
// FIXME: add APDU encode methods for each?
uint32_t Device_Object_Identifier(void)
{
return Object_Identifier;
}
void Device_Set_Object_Identifier(uint32_t object_id)
{
// FIXME: bounds check?
Object_Identifier = object_id;
}
BACNET_DEVICE_STATUS Device_System_Status(void)
{
return System_Status;
@@ -186,6 +201,7 @@ uint16_t Device_APDU_Timeout(void)
return APDU_Timeout;
}
// in milliseconds
void Device_Set_APDU_Timeout(uint16_t timeout)
{
APDU_Timeout = timeout;
@@ -211,3 +227,138 @@ void Device_Set_Database_Revision(uint8_t revision)
Database_Revision = revision;
}
int Device_Encode_Property_APDU(
uint8_t *apdu,
BACNET_PROPERTY_ID property,
int array_index)
{
int apdu_len = 0; // return value
switch (property)
{
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_DEVICE,
Object_Identifier);
break;
case PROP_OBJECT_NAME:
apdu_len = encode_tagged_character_string(&apdu[0], Object_Name);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_tagged_enumerated(&apdu[0], OBJECT_DEVICE);
break;
case PROP_DESCRIPTION:
apdu_len = encode_tagged_character_string(&apdu[0], Description);
break;
case PROP_SYSTEM_STATUS:
apdu_len = encode_tagged_enumerated(&apdu[0], System_Status);
break;
case PROP_VENDOR_NAME:
apdu_len = encode_tagged_character_string(&apdu[0], Vendor_Name);
break;
case PROP_VENDOR_IDENTIFIER:
apdu_len = encode_tagged_unsigned(&apdu[0], Vendor_Identifier);
break;
case PROP_MODEL_NAME:
apdu_len = encode_tagged_character_string(&apdu[0], Model_Name);
break;
case PROP_FIRMWARE_REVISION:
apdu_len = encode_tagged_character_string(&apdu[0], Program_Version);
break;
case PROP_APPLICATION_SOFTWARE_VERSION:
apdu_len = encode_tagged_character_string(&apdu[0],
Application_Software_Version);
break;
// if you support time
case PROP_LOCAL_TIME:
//t = time(NULL);
//my_tm = localtime(&t);
//apdu_len =
// encode_tagged_time(&apdu[0], my_tm->tm_hour, my_tm->tm_min,
// my_tm->tm_sec, 0);
break;
// if you support date
case PROP_LOCAL_DATE:
//t = time(NULL);
//my_tm = localtime(&t);
// year = years since 1900
// month 1=Jan
// day = day of month
// wday 1=Monday...7=Sunday
//apdu_len = encode_tagged_date(&apdu[0],
// my_tm->tm_year,
// my_tm->tm_mon + 1,
// my_tm->tm_mday, ((my_tm->tm_wday == 0) ? 7 : my_tm->tm_wday));
break;
case PROP_PROTOCOL_VERSION:
apdu_len = encode_tagged_unsigned(&apdu[0], Protocol_Version);
break;
// Legacy Support - necessary?
//case PROP_PROTOCOL_CONFORMANCE_CLASS:
// apdu_len = encode_tagged_unsigned(&apdu[0], 1);
// break;
case PROP_PROTOCOL_SERVICES_SUPPORTED:
// FIXME: needs an encoding function for bitstring
apdu[0] = 0x85; /* what is following? (this is a bitstring) */
apdu[1] = 0x06; /* length extension to 6 bytes */
apdu[2] = 0x05; /* 5 unused bits in the final byte */
apdu[3] = 0x00; /* none of the first 8 bits are set */
apdu[4] = 0x09; /* bits 3,0 are set */
apdu[5] = 0x00; /* none of the 3rd set of bits are set */
apdu[6] = 0x20; /* bit 5 is set */
apdu[7] = 0x20; /* bit 5 is set */
apdu_len = 8; /* bytes in this apdu */
break;
case PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED:
// FIXME: needs an encoding function for bitstring
apdu[0] = 0x84; /* what is following? (this is a bitstring) */
apdu[1] = 0x06; /* 6 unused bits in the final byte */
apdu[2] = 0xFF; /* All of the first 8 bits are set */
apdu[3] = 0xFF; /* All of the second 8 bits are set */
apdu[4] = 0xC0; /* All of the valid bits are set */
apdu_len = 5; /* bytes in this apdu */
break;
case PROP_OBJECT_LIST:
// FIXME: hook into real object list, not just device
// Array element zero is the number of objects in the list
if (array_index == 0)
apdu_len = encode_tagged_unsigned(&apdu[0], 1);
// if no index was specified, then try to encode the entire list
// into one packet. Note that more than likely you will have
// to return an error if the number of encoded objects exceeds
// your maximum APDU size.
else if (array_index == BACNET_ARRAY_ALL)
{
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance);
}
else
{
// the first object in the list is at index=1
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance);
// FIXME: handle the error case of an index beyond the bounds
}
break;
case PROP_MAX_APDU_LENGTH_ACCEPTED:
apdu_len = encode_tagged_unsigned(&apdu[0],
Device_Max_APDU_Length_Accepted());
break;
case PROP_SEGMENTATION_SUPPORTED:
apdu_len = encode_tagged_enumerated(&apdu[0],
Device_Segmentation_Supported());
break;
case PROP_APDU_TIMEOUT:
apdu_len = encode_tagged_unsigned(&apdu[0], APDU_Timeout);
break;
case PROP_NUMBER_OF_APDU_RETRIES:
apdu_len = encode_tagged_unsigned(&apdu[0], Number_Of_APDU_Retries);
break;
default:
break;
}
return apdu_len;
}
+11 -3
View File
@@ -40,6 +40,9 @@
#include "bacdef.h"
#include "bacenum.h"
uint32_t Device_Object_Identifier(void);
void Device_Set_Object_Identifier(uint32_t object_id);
BACNET_DEVICE_STATUS Device_System_Status(void);
void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
@@ -61,11 +64,11 @@ void Device_Set_Application_Software_Version(const char *name);
const char *Device_Description(void);
void Device_Set_Description(const char *name);
// some stack-centric constant values - no set methods
uint8_t Device_Protocol_Version(void);
uint8_t Device_Set_Protocol_Revision(void);
uint8_t Device_Protocol_Revision(void);
uint16_t Device_Max_APDU_Length_Accepted(void);
BACNET_SEGMENTATION Device_Set_Segmentation_Supported(void);
BACNET_SEGMENTATION Device_Segmentation_Supported(void);
uint16_t Device_APDU_Timeout(void);
void Device_Set_APDU_Timeout(uint16_t timeout);
@@ -76,5 +79,10 @@ void Device_Set_Number_Of_APDU_Retries(uint8_t retries);
uint8_t Device_Database_Revision(void);
void Device_Set_Database_Revision(uint8_t revision);
int Device_Encode_Property_APDU(
uint8_t *apdu,
BACNET_PROPERTY_ID property,
int array_index);
#endif
+23 -8
View File
@@ -2,7 +2,7 @@
// Written by Steve Karg - 2005 - skarg@users.sourceforge.net
// Bug fixes, feature requests, and suggestions are welcome
// This is one way to use the BACnet stack under Linux
// This is one way to use the embedded BACnet stack under Linux
#include <stddef.h>
#include <stdint.h>
@@ -20,10 +20,6 @@
static uint8_t Tx_Buf[MAX_MPDU] = {0};
static uint8_t Rx_Buf[MAX_MPDU] = {0};
// vendor id assigned by ASHRAE
uint16_t Vendor_Id = 42;
uint32_t Device_Id = 111;
// flag to send an I-Am
bool I_Am_Request = true;
@@ -120,11 +116,22 @@ void WhoIsHandler(
return;
}
int main(int argc, char *argv[])
static void Init_Device_Parameters(void)
{
BACNET_ADDRESS src = {0}; // address where message came from
uint16_t pdu_len = 0;
// configure my initial values
Device_Set_Object_Identifier(111);
Device_Set_Vendor_Name("Lithonia Lighting");
Device_Set_Vendor_Identifier(42);
Device_Set_Model_Name("Simple BACnet Server");
Device_Set_Firmware_Revision("1.00");
Device_Set_Application_Software_Version("none");
Device_Set_Description("Example of a simple BACnet server");
return;
}
static void Init_Service_Handlers(void)
{
// custom handlers
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,WhoIsHandler);
@@ -222,7 +229,15 @@ int main(int argc, char *argv[])
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_REQUEST_KEY,
UnrecognizedServiceHandler);
}
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {0}; // address where message came from
uint16_t pdu_len = 0;
Init_Device_Parameters();
Init_Service_Handlers();
// init the physical layer
if (!ethernet_init("eth0"))
return 1;
+1 -1
View File
@@ -208,5 +208,5 @@ int main(void)
return 0;
}
#endif /* TEST_WHOIS */
#endif /* TEST_REJECT */
#endif /* TEST */
+2 -2
View File
@@ -1,6 +1,6 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2004 Steve Karg
Copyright (C) 2005 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -52,7 +52,7 @@ int reject_decode_apdu(
uint8_t *apdu,
unsigned apdu_len,
uint8_t *invoke_id,
uint8_t *reject_reason)
uint8_t *reject_reason);
#ifdef TEST
void testReject(Test * pTest);
+5
View File
@@ -44,3 +44,8 @@ make -f reject.mak
./reject >> test.log
make -f reject.mak clean
make -f bacerror.mak clean
make -f bacerror.mak
./bacerror >> test.log
make -f bacerror.mak clean
+2 -2
View File
@@ -1,6 +1,6 @@
/*####COPYRIGHTBEGIN####
-------------------------------------------
Copyright (C) 2004 Steve Karg
Copyright (C) 2005 Steve Karg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -37,7 +37,7 @@
#include <stdint.h>
#include <stdbool.h>
// encode I-Am service - use -1 for limit if you want unlimited
// encode service - use -1 for limit if you want unlimited
int whois_encode_apdu(
uint8_t *apdu,
int32_t low_limit,