adding read property service
This commit is contained in:
+16
-2
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -208,5 +208,5 @@ int main(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* TEST_WHOIS */
|
||||
#endif /* TEST_REJECT */
|
||||
#endif /* TEST */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user