Indented.

This commit is contained in:
skarg
2007-11-29 15:56:53 +00:00
parent c585241c03
commit 411d6c1b24
236 changed files with 17864 additions and 15724 deletions
+27 -22
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -63,9 +63,11 @@ static char *Communication_Password = NULL;
static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS * src,
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
@@ -76,30 +78,34 @@ static void MyErrorHandler(BACNET_ADDRESS * src,
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
void MyDeviceCommunicationControlSimpleAckHandler(BACNET_ADDRESS * src,
void MyDeviceCommunicationControlSimpleAckHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id)
{
(void) src;
@@ -107,15 +113,14 @@ void MyDeviceCommunicationControlSimpleAckHandler(BACNET_ADDRESS * src,
printf("DeviceCommunicationControl Acknowledged!\r\n");
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_bind);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -138,7 +143,9 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -192,8 +199,7 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
@@ -208,8 +214,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
+50 -49
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -69,56 +69,62 @@ static BACNET_RP_SERVICE_DATA Read_Property_Data;
/* FIXME: keep the object list in here */
/* static OS_Keylist Object_List; */
static void MyErrorHandler(BACNET_ADDRESS * src,
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
#if 1
#if 1
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name(error_class),
bactext_error_code_name(error_code));
#else
#else
(void) error_class;
(void) error_code;
#endif
#endif
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
#if 1
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name(abort_reason));
#else
#if 1
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
#else
(void) abort_reason;
#endif
#endif
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
#if 1
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name(reject_reason));
#else
#if 1
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
#else
(void) reject_reason;
#endif
#endif
Error_Detected = true;
}
void PrintReadPropertyData(BACNET_READ_PROPERTY_DATA * data)
void PrintReadPropertyData(
BACNET_READ_PROPERTY_DATA * data)
{
BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
int len = 0;
@@ -170,16 +176,17 @@ void PrintReadPropertyData(BACNET_READ_PROPERTY_DATA * data)
}
}
void MyReadPropertyAckHandler(uint8_t * service_request,
void MyReadPropertyAckHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
{
int len = 0;
BACNET_READ_PROPERTY_DATA data;
(void) src;
len = rp_ack_decode_service_request(service_request,
service_len, &data);
len = rp_ack_decode_service_request(service_request, service_len, &data);
if (len > 0) {
memmove(&Read_Property_Data.service_data, service_data, sizeof(data));
memmove(&Read_Property_Data.data, &data, sizeof(data));
@@ -187,15 +194,14 @@ void MyReadPropertyAckHandler(uint8_t * service_request,
}
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_bind);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -207,13 +213,13 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
MyReadPropertyAckHandler);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY,
MyErrorHandler);
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static uint8_t Read_Properties(uint32_t device_instance)
static uint8_t Read_Properties(
uint32_t device_instance)
{
uint8_t invoke_id = 0;
static unsigned index = 0;
@@ -226,12 +232,10 @@ static uint8_t Read_Properties(uint32_t device_instance)
}
if (pRequired[index] != -1) {
printf(" %s: ",bactext_property_name(pRequired[index]));
printf(" %s: ", bactext_property_name(pRequired[index]));
invoke_id = Send_Read_Property_Request(device_instance,
OBJECT_DEVICE,
device_instance,
pRequired[index],
BACNET_ARRAY_ALL);
device_instance, pRequired[index], BACNET_ARRAY_ALL);
if (invoke_id) {
index++;
}
@@ -240,7 +244,9 @@ static uint8_t Read_Properties(uint32_t device_instance)
return invoke_id;
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -257,9 +263,7 @@ int main(int argc, char *argv[])
/* print help if not enough arguments */
if (argc < 2) {
printf
("%s device-instance\r\n",
filename_remove_path(argv[0]));
printf("%s device-instance\r\n", filename_remove_path(argv[0]));
return 0;
}
@@ -267,7 +271,7 @@ int main(int argc, char *argv[])
Target_Device_Object_Instance = strtol(argv[1], NULL, 0);
if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) {
fprintf(stderr, "device-instance=%u - it must be less than %u\r\n",
Target_Device_Object_Instance, BACNET_MAX_INSTANCE+1);
Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1);
return 1;
}
/* setup my info */
@@ -281,8 +285,7 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
printf("List of Objects in test device:\r\n");
printf("{\r\n");
/* loop forever */
@@ -299,8 +302,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds) {
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
}
/* wait until the device is bound, or timeout and quit */
found = address_bind_request(Target_Device_Object_Instance,
@@ -308,7 +310,7 @@ int main(int argc, char *argv[])
if (found) {
/* invoke ID is set to zero when it is not in use */
if (invoke_id == 0) {
invoke_id = Read_Properties(Target_Device_Object_Instance);
invoke_id = Read_Properties(Target_Device_Object_Instance);
if (invoke_id == 0) {
break;
}
@@ -321,8 +323,7 @@ int main(int argc, char *argv[])
}
} else if (tsm_invoke_id_free(invoke_id)) {
invoke_id = 0;
}
else if (tsm_invoke_id_failed(invoke_id)) {
} else if (tsm_invoke_id_failed(invoke_id)) {
fprintf(stderr, "\rError: TSM Timeout!\r\n");
tsm_free_invoke_id(invoke_id);
invoke_id = 0;
+7 -5
View File
@@ -40,7 +40,7 @@
#include "ai.h"
#include "ao.h"
#if defined(BACFILE)
#include "bacfile.h"
#include "bacfile.h"
#endif
/*
@@ -95,9 +95,11 @@ shall be TRUE, otherwise FALSE.
*/
#if defined(BACFILE)
void handler_atomic_read_file(uint8_t * service_request,
void handler_atomic_read_file(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_ATOMIC_READ_FILE_DATA data;
int len = 0;
@@ -125,7 +127,7 @@ void handler_atomic_read_file(uint8_t * service_request,
fprintf(stderr, "ARF: Segmented Message. Sending Abort!\n");
#endif
goto ARF_ABORT;
}
}
len = arf_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */
if (len < 0) {
@@ -186,7 +188,7 @@ void handler_atomic_read_file(uint8_t * service_request,
service_data->invoke_id,
SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code);
}
ARF_ABORT:
ARF_ABORT:
pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+5 -4
View File
@@ -47,9 +47,11 @@
/* that someone can read from us. It is common to */
/* use the description as the file name. */
#if defined(BACFILE)
void handler_atomic_read_file_ack(uint8_t * service_request,
void handler_atomic_read_file_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
{
int len = 0;
BACNET_ATOMIC_READ_FILE_DATA data;
@@ -60,8 +62,7 @@ void handler_atomic_read_file_ack(uint8_t * service_request,
(void) src;
/* get the file instance from the tsm data before freeing it */
instance = bacfile_instance_from_tsm(service_data->invoke_id);
len = arf_ack_decode_service_request(service_request,
service_len, &data);
len = arf_ack_decode_service_request(service_request, service_len, &data);
#if PRINT_ENABLED
fprintf(stderr, "Received Read-File Ack!\n");
#endif
+8 -6
View File
@@ -40,7 +40,7 @@
/* demo objects */
#include "device.h"
#if defined(BACFILE)
#include "bacfile.h"
#include "bacfile.h"
#endif
/*
@@ -73,9 +73,11 @@ standard.
*/
#if defined(BACFILE)
void handler_atomic_write_file(uint8_t * service_request,
void handler_atomic_write_file(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_ATOMIC_WRITE_FILE_DATA data;
int len = 0;
@@ -113,7 +115,7 @@ void handler_atomic_write_file(uint8_t * service_request,
fprintf(stderr, "Bad Encoding. Sending Abort!\n");
#endif
goto AWF_ABORT;
}
}
if (data.object_type == OBJECT_FILE) {
if (!bacfile_valid_instance(data.object_instance)) {
error = true;
@@ -126,7 +128,7 @@ void handler_atomic_write_file(uint8_t * service_request,
#endif
len =
awf_ack_encode_apdu(&Handler_Transmit_Buffer
[pdu_len], service_data->invoke_id, &data);
[pdu_len], service_data->invoke_id, &data);
} else {
error = true;
error_class = ERROR_CLASS_OBJECT;
@@ -151,7 +153,7 @@ void handler_atomic_write_file(uint8_t * service_request,
service_data->invoke_id,
SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code);
}
AWF_ABORT:
AWF_ABORT:
pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+6 -4
View File
@@ -40,9 +40,11 @@
static char *My_Password = "filister";
void handler_device_communication_control(uint8_t * service_request,
void handler_device_communication_control(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
uint16_t timeDuration = 0;
BACNET_COMMUNICATION_ENABLE_DISABLE state = COMMUNICATION_ENABLE;
@@ -70,7 +72,7 @@ void handler_device_communication_control(uint8_t * service_request,
"Sending Abort - segmented message.\n");
#endif
goto DCC_ABORT;
}
}
/* decode the service request only */
len = dcc_decode_service_request(service_request,
service_len, &timeDuration, &state, &password);
@@ -121,7 +123,7 @@ void handler_device_communication_control(uint8_t * service_request,
#endif
}
}
DCC_ABORT:
DCC_ABORT:
pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+8 -4
View File
@@ -32,8 +32,10 @@
#include "iam.h"
#include "address.h"
void handler_i_am_add(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_i_am_add(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
uint32_t device_id = 0;
@@ -61,8 +63,10 @@ void handler_i_am_add(uint8_t * service_request,
return;
}
void handler_i_am_bind(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_i_am_bind(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
uint32_t device_id = 0;
+5 -4
View File
@@ -32,16 +32,17 @@
#include "bactext.h"
#include "ihave.h"
void handler_i_have(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_i_have(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
BACNET_I_HAVE_DATA data;
(void) service_len;
(void) src;
len = ihave_decode_service_request(service_request,
service_len, &data);
len = ihave_decode_service_request(service_request, service_len, &data);
if (len != -1) {
#if PRINT_ENABLED
fprintf(stderr, "I-Have: %s %d from %s %u!\r\n",
+6 -4
View File
@@ -41,9 +41,11 @@
static char *Password = "Jesus";
static BACNET_CHARACTER_STRING My_Password;
void handler_reinitialize_device(uint8_t * service_request,
void handler_reinitialize_device(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_REINITIALIZED_STATE state;
BACNET_CHARACTER_STRING their_password;
@@ -70,7 +72,7 @@ void handler_reinitialize_device(uint8_t * service_request,
"ReinitializeDevice: Sending Abort - segmented message.\n");
#endif
goto RD_ABORT;
}
}
/* decode the service request only */
len = rd_decode_service_request(service_request,
service_len, &state, &their_password);
@@ -124,7 +126,7 @@ void handler_reinitialize_device(uint8_t * service_request,
#endif
}
}
RD_ABORT:
RD_ABORT:
pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+32 -67
View File
@@ -47,7 +47,7 @@
#include "lsp.h"
#include "mso.h"
#if defined(BACFILE)
#include "bacfile.h"
#include "bacfile.h"
#endif
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
@@ -69,115 +69,82 @@ int Encode_Property_APDU(
*error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_UNKNOWN_OBJECT;
/* handle each object type */
switch(object_type) {
switch (object_type) {
case OBJECT_DEVICE:
if (Device_Valid_Object_Instance_Number(object_instance)) {
apdu_len = Device_Encode_Property_APDU(
&apdu[0],
property,
array_index,
error_class, error_code);
apdu_len = Device_Encode_Property_APDU(&apdu[0],
property, array_index, error_class, error_code);
}
break;
case OBJECT_ANALOG_INPUT:
if (Analog_Input_Valid_Instance(object_instance)) {
apdu_len = Analog_Input_Encode_Property_APDU(
&apdu[0],
apdu_len = Analog_Input_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_ANALOG_OUTPUT:
if (Analog_Output_Valid_Instance(object_instance)) {
apdu_len = Analog_Output_Encode_Property_APDU(
&apdu[0],
apdu_len = Analog_Output_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_ANALOG_VALUE:
if (Analog_Value_Valid_Instance(object_instance)) {
apdu_len = Analog_Value_Encode_Property_APDU(
&apdu[0],
apdu_len = Analog_Value_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_BINARY_INPUT:
if (Binary_Input_Valid_Instance(object_instance)) {
apdu_len = Binary_Input_Encode_Property_APDU(
&apdu[0],
apdu_len = Binary_Input_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_BINARY_OUTPUT:
if (Binary_Output_Valid_Instance(object_instance)) {
apdu_len = Binary_Output_Encode_Property_APDU(
&apdu[0],
apdu_len = Binary_Output_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_BINARY_VALUE:
if (Binary_Value_Valid_Instance(object_instance)) {
apdu_len = Binary_Value_Encode_Property_APDU(
&apdu[0],
apdu_len = Binary_Value_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_LIFE_SAFETY_POINT:
if (Life_Safety_Point_Valid_Instance(object_instance)) {
apdu_len = Life_Safety_Point_Encode_Property_APDU(
&apdu[0],
apdu_len = Life_Safety_Point_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_LOAD_CONTROL:
if (Load_Control_Valid_Instance(object_instance)) {
apdu_len = Load_Control_Encode_Property_APDU(
&apdu[0],
apdu_len = Load_Control_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
case OBJECT_MULTI_STATE_OUTPUT:
if (Multistate_Output_Valid_Instance(object_instance)) {
apdu_len = Multistate_Output_Encode_Property_APDU(
&apdu[0],
apdu_len = Multistate_Output_Encode_Property_APDU(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
#if defined(BACFILE)
case OBJECT_FILE:
if (bacfile_valid_instance(object_instance)) {
apdu_len = bacfile_encode_property_apdu(
&apdu[0],
apdu_len = bacfile_encode_property_apdu(&apdu[0],
object_instance,
property,
array_index,
error_class, error_code);
property, array_index, error_class, error_code);
}
break;
#endif
@@ -190,9 +157,11 @@ int Encode_Property_APDU(
return apdu_len;
}
void handler_read_property(uint8_t * service_request,
void handler_read_property(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_READ_PROPERTY_DATA data;
int len = 0;
@@ -237,13 +206,10 @@ void handler_read_property(uint8_t * service_request,
/* assume that there is an error */
error = true;
len = Encode_Property_APDU(
&Temp_Buf[0],
len = Encode_Property_APDU(&Temp_Buf[0],
data.object_type,
data.object_instance,
data.object_property,
data.array_index,
&error_class, &error_code);
data.object_property, data.array_index, &error_class, &error_code);
if (len >= 0) {
/* encode the APDU portion of the packet */
data.application_data = &Temp_Buf[0];
@@ -253,8 +219,7 @@ void handler_read_property(uint8_t * service_request,
rp_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data);
#if PRINT_ENABLED
fprintf(stderr,
"RP: Sending Ack!\n");
fprintf(stderr, "RP: Sending Ack!\n");
#endif
error = false;
}
@@ -276,7 +241,7 @@ void handler_read_property(uint8_t * service_request,
#endif
}
}
RP_ABORT:
RP_ABORT:
pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+7 -5
View File
@@ -42,7 +42,8 @@
#include "txbuf.h"
/* for debugging... */
static void PrintReadPropertyData(BACNET_READ_PROPERTY_DATA * data)
static void PrintReadPropertyData(
BACNET_READ_PROPERTY_DATA * data)
{
BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
int len = 0;
@@ -95,17 +96,18 @@ static void PrintReadPropertyData(BACNET_READ_PROPERTY_DATA * data)
}
}
void handler_read_property_ack(uint8_t * service_request,
void handler_read_property_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
{
int len = 0;
BACNET_READ_PROPERTY_DATA data;
(void) src;
(void) service_data; /* we could use these... */
len = rp_ack_decode_service_request(service_request,
service_len, &data);
len = rp_ack_decode_service_request(service_request, service_len, &data);
#if 0
fprintf(stderr, "Received Read-Property Ack!\n");
#endif
+143 -190
View File
@@ -49,25 +49,24 @@
#include "lsp.h"
#include "mso.h"
#if defined(BACFILE)
#include "bacfile.h"
#include "bacfile.h"
#endif
static uint8_t Temp_Buf[MAX_APDU] = { 0 };
struct property_list_t
{
struct property_list_t {
const int *pList;
unsigned count;
};
struct special_property_list_t
{
struct special_property_list_t {
struct property_list_t Required;
struct property_list_t Optional;
struct property_list_t Proprietary;
};
static unsigned property_list_count(const int *pList)
static unsigned property_list_count(
const int *pList)
{
unsigned property_count = 0;
@@ -90,72 +89,62 @@ static void RPM_Property_List(
pPropertyList->Optional.pList = NULL;
pPropertyList->Proprietary.pList = NULL;
switch (object_type) {
case OBJECT_ANALOG_INPUT:
Analog_Input_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_ANALOG_OUTPUT:
Analog_Output_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_ANALOG_VALUE:
Analog_Value_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_BINARY_INPUT:
Binary_Input_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_BINARY_OUTPUT:
Binary_Output_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_BINARY_VALUE:
Binary_Value_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_LIFE_SAFETY_POINT:
Life_Safety_Point_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_LOAD_CONTROL:
Load_Control_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_MULTI_STATE_OUTPUT:
break;
case OBJECT_ANALOG_INPUT:
Analog_Input_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_ANALOG_OUTPUT:
Analog_Output_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_ANALOG_VALUE:
Analog_Value_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_BINARY_INPUT:
Binary_Input_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_BINARY_OUTPUT:
Binary_Output_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_BINARY_VALUE:
Binary_Value_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_LIFE_SAFETY_POINT:
Life_Safety_Point_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_LOAD_CONTROL:
Load_Control_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_MULTI_STATE_OUTPUT:
break;
#if defined(BACFILE)
case OBJECT_FILE:
BACfile_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
case OBJECT_FILE:
BACfile_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
#endif
case OBJECT_DEVICE:
Device_Property_Lists(
&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
default:
break;
case OBJECT_DEVICE:
Device_Property_Lists(&pPropertyList->Required.pList,
&pPropertyList->Optional.pList,
&pPropertyList->Proprietary.pList);
break;
default:
break;
}
/* fill the count */
pPropertyList->Required.count =
@@ -173,7 +162,7 @@ static int RPM_Object_Property(
BACNET_PROPERTY_ID special_property,
unsigned index)
{
int property = -1; /* return value */
int property = -1; /* return value */
unsigned required, optional, proprietary;
required = pPropertyList->Required.count;
@@ -210,8 +199,7 @@ static unsigned RPM_Object_Property_Count(
if (special_property == PROP_ALL) {
count = pPropertyList->Required.count +
pPropertyList->Optional.count +
pPropertyList->Proprietary.count;
pPropertyList->Optional.count + pPropertyList->Proprietary.count;
} else if (special_property == PROP_REQUIRED) {
count = pPropertyList->Required.count;
} else if (special_property == PROP_OPTIONAL) {
@@ -222,14 +210,19 @@ static unsigned RPM_Object_Property_Count(
}
/* copy len bytes from src to offset of dest if there is enough space. */
int apdu_copy(uint8_t *dest, uint8_t *src, int offset, int len, int max)
int apdu_copy(
uint8_t * dest,
uint8_t * src,
int offset,
int len,
int max)
{
int i;
int copy_len = 0;
if (len <= (max-offset)) {
if (len <= (max - offset)) {
for (i = 0; i < len; i++) {
dest[offset+i] = src[i];
dest[offset + i] = src[i];
copy_len++;
}
}
@@ -239,7 +232,8 @@ int apdu_copy(uint8_t *dest, uint8_t *src, int offset, int len, int max)
/* Encode the RPM property returning the length of the encoding,
or 0 if there is no room to fit the encoding. */
int RPM_Encode_Property(uint8_t *apdu,
int RPM_Encode_Property(
uint8_t * apdu,
uint16_t offset,
uint16_t max_apdu,
BACNET_OBJECT_TYPE object_type,
@@ -252,35 +246,30 @@ int RPM_Encode_Property(uint8_t *apdu,
BACNET_ERROR_CLASS error_class = ERROR_CLASS_OBJECT;
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
len = rpm_ack_encode_apdu_object_property(
&Temp_Buf[0],
object_property,
array_index);
len = rpm_ack_encode_apdu_object_property(&Temp_Buf[0],
object_property, array_index);
len = apdu_copy(&apdu[0], &Temp_Buf[0], offset, len, max_apdu);
if (!len)
return 0;
apdu_len += len;
len = Encode_Property_APDU(
&Temp_Buf[0],
len = Encode_Property_APDU(&Temp_Buf[0],
object_type,
object_instance,
object_property,
array_index,
&error_class, &error_code);
object_property, array_index, &error_class, &error_code);
if (len < 0) {
/* error was returned - encode that for the response */
len = rpm_ack_encode_apdu_object_property_error(
&Temp_Buf[0],
len = rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0],
error_class, error_code);
len = apdu_copy(&apdu[0], &Temp_Buf[0], offset+apdu_len, len, max_apdu);
len =
apdu_copy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len,
max_apdu);
if (!len)
return 0;
} else if ((offset+apdu_len+1+len+1) < max_apdu) {
} else if ((offset + apdu_len + 1 + len + 1) < max_apdu) {
/* enough room to fit the property value and tags */
len = rpm_ack_encode_apdu_object_property_value(
&apdu[offset+apdu_len],
&Temp_Buf[0],
len);
len =
rpm_ack_encode_apdu_object_property_value(&apdu[offset + apdu_len],
&Temp_Buf[0], len);
} else {
/* not enough room - abort! */
return 0;
@@ -311,16 +300,14 @@ void handler_read_property_multiple(
int32_t array_index = 0;
/* jps_debug - see if we are utilizing all the buffer */
/* memset(&Handler_Transmit_Buffer[0], 0xff, sizeof(Handler_Transmit_Buffer));*/
/* memset(&Handler_Transmit_Buffer[0], 0xff, sizeof(Handler_Transmit_Buffer)); */
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_encode_pdu(
&Handler_Transmit_Buffer[0],
npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0],
src, &my_address, &npdu_data);
if (service_data->segmented_message) {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED
@@ -330,102 +317,82 @@ void handler_read_property_multiple(
}
/* decode apdu request & encode apdu reply
encode complex ack, invoke id, service choice */
apdu_len = rpm_ack_encode_apdu_init(
&Handler_Transmit_Buffer[npdu_len],
apdu_len = rpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id);
do
{
len = rpm_decode_object_id(
&service_request[decode_len],
service_len - decode_len,
&object_type, &object_instance);
do {
len = rpm_decode_object_id(&service_request[decode_len],
service_len - decode_len, &object_type, &object_instance);
/* end of object? */
if (len > 0) {
decode_len += len;
} else {
len = rpm_decode_object_end(
&service_request[decode_len],
len = rpm_decode_object_end(&service_request[decode_len],
service_len - decode_len);
if (len == 1) {
decode_len++;
len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]);
copy_len = apdu_copy(
&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len,
sizeof(Handler_Transmit_Buffer));
copy_len =
apdu_copy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len, sizeof(Handler_Transmit_Buffer));
if (!copy_len) {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
} else {
apdu_len += copy_len;
}
} else {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_OTHER, true);
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RPM_ABORT;
}
break;
}
len = rpm_ack_encode_apdu_object_begin(
&Temp_Buf[0],
len = rpm_ack_encode_apdu_object_begin(&Temp_Buf[0],
object_type, object_instance);
copy_len = apdu_copy(
&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len,
sizeof(Handler_Transmit_Buffer));
copy_len = apdu_copy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len, sizeof(Handler_Transmit_Buffer));
if (!copy_len) {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
apdu_len = abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
} else {
apdu_len += copy_len;
}
/* do each property of this object of the RPM request */
do
{
len = rpm_decode_object_property(
&service_request[decode_len],
service_len - decode_len,
&object_property,
&array_index);
do {
len = rpm_decode_object_property(&service_request[decode_len],
service_len - decode_len, &object_property, &array_index);
/* end of property list? */
if (len > 0) {
decode_len += len;
} else {
len = rpm_decode_object_end(
&service_request[decode_len],
len = rpm_decode_object_end(&service_request[decode_len],
service_len - decode_len);
if (len == 1) {
decode_len++;
len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]);
copy_len = apdu_copy(
&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
apdu_len, len,
copy_len =
apdu_copy(&Handler_Transmit_Buffer[npdu_len],
&Temp_Buf[0], apdu_len, len,
sizeof(Handler_Transmit_Buffer));
if (!copy_len) {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED,
true);
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer
[npdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
} else {
apdu_len += copy_len;
}
} else {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_OTHER, true);
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, ABORT_REASON_OTHER, true);
goto RPM_ABORT;
}
/* stop decoding properties */
@@ -434,8 +401,7 @@ void handler_read_property_multiple(
/* handle the special properties */
if ((object_property == PROP_ALL) ||
(object_property == PROP_REQUIRED) ||
(object_property == PROP_OPTIONAL))
{
(object_property == PROP_OPTIONAL)) {
struct special_property_list_t property_list;
unsigned property_count = 0;
unsigned index = 0;
@@ -443,63 +409,50 @@ void handler_read_property_multiple(
special_object_property = object_property;
RPM_Property_List(object_type, &property_list);
property_count = RPM_Object_Property_Count(
&property_list,
property_count = RPM_Object_Property_Count(&property_list,
special_object_property);
for (index = 0; index < property_count; index++)
{
object_property = RPM_Object_Property(
&property_list,
special_object_property,
index);
len = RPM_Encode_Property(
&Handler_Transmit_Buffer[0],
for (index = 0; index < property_count; index++) {
object_property = RPM_Object_Property(&property_list,
special_object_property, index);
len = RPM_Encode_Property(&Handler_Transmit_Buffer[0],
npdu_len + apdu_len,
sizeof(Handler_Transmit_Buffer),
object_type,
object_instance,
object_property,
array_index);
object_instance, object_property, array_index);
if (len > 0) {
apdu_len += len;
} else {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer
[npdu_len], service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
}
}
} else {
/* handle an individual property */
len = RPM_Encode_Property(
&Handler_Transmit_Buffer[0],
len = RPM_Encode_Property(&Handler_Transmit_Buffer[0],
npdu_len + apdu_len,
sizeof(Handler_Transmit_Buffer),
object_type,
object_instance,
object_property,
array_index);
object_instance, object_property, array_index);
if (len > 0) {
apdu_len += len;
} else {
apdu_len = abort_encode_apdu(
&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
apdu_len =
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
goto RPM_ABORT;
}
}
} while(1);
} while (1);
if (decode_len >= service_len) {
break;
}
} while(1);
RPM_ABORT:
} while (1);
RPM_ABORT:
pdu_len = apdu_len + npdu_len;
bytes_sent = datalink_send_pdu(
src,
&npdu_data,
&Handler_Transmit_Buffer[0],
pdu_len);
bytes_sent = datalink_send_pdu(src,
&npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
}
+11 -6
View File
@@ -32,7 +32,9 @@
#include "timesync.h"
#if PRINT_ENABLED
static void show_bacnet_date_time(BACNET_DATE * bdate, BACNET_TIME * btime)
static void show_bacnet_date_time(
BACNET_DATE * bdate,
BACNET_TIME * btime)
{
/* show the date received */
fprintf(stderr, "%u", (unsigned) bdate->year);
@@ -47,8 +49,10 @@ static void show_bacnet_date_time(BACNET_DATE * bdate, BACNET_TIME * btime)
}
#endif
void handler_timesync(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_timesync(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
BACNET_DATE bdate;
@@ -67,8 +71,10 @@ void handler_timesync(uint8_t * service_request,
return;
}
void handler_timesync_utc(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_timesync_utc(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
BACNET_DATE bdate;
@@ -86,4 +92,3 @@ void handler_timesync_utc(uint8_t * service_request,
return;
}
+7 -8
View File
@@ -35,8 +35,10 @@
#include "device.h"
#include "client.h"
void handler_who_has(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_who_has(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
BACNET_WHO_HAS_DATA data;
@@ -47,15 +49,12 @@ void handler_who_has(uint8_t * service_request,
bool found = false;
(void) src;
len = whohas_decode_service_request(service_request,
service_len, &data);
len = whohas_decode_service_request(service_request, service_len, &data);
if (len > 0) {
if ((data.low_limit == -1) || (data.high_limit == -1))
directed_to_me = true;
else if ((Device_Object_Instance_Number() >=
(uint32_t) data.low_limit)
&& (Device_Object_Instance_Number() <=
(uint32_t) data.high_limit))
else if ((Device_Object_Instance_Number() >= (uint32_t) data.low_limit)
&& (Device_Object_Instance_Number() <= (uint32_t) data.high_limit))
directed_to_me = true;
if (directed_to_me) {
/* do we have such an object? If so, send an I-Have.
+4 -2
View File
@@ -37,8 +37,10 @@
#include "client.h"
#include "txbuf.h"
void handler_who_is(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
void handler_who_is(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
int32_t low_limit = 0;
+204 -231
View File
@@ -47,12 +47,14 @@
#include "lsp.h"
#include "mso.h"
#if defined(BACFILE)
#include "bacfile.h"
#include "bacfile.h"
#endif
void handler_write_property(uint8_t * service_request,
void handler_write_property(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
BACNET_WRITE_PROPERTY_DATA wp_data;
int len = 0;
@@ -79,9 +81,8 @@ void handler_write_property(uint8_t * service_request,
fprintf(stderr, "WP: Segmented message. Sending Abort!\n");
#endif
goto WP_ABORT;
} /* decode the service request only */
len = wp_decode_service_request(service_request,
service_len, &wp_data);
} /* decode the service request only */
len = wp_decode_service_request(service_request, service_len, &wp_data);
#if PRINT_ENABLED
if (len > 0)
fprintf(stderr, "WP: type=%u instance=%u property=%u index=%d\n",
@@ -99,232 +100,204 @@ void handler_write_property(uint8_t * service_request,
fprintf(stderr, "WP: Bad Encoding. Sending Abort!\n");
#endif
goto WP_ABORT;
}
switch (wp_data.object_type) {
case OBJECT_DEVICE:
if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for Device!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Error for Device!\n");
#endif
}
break;
case OBJECT_ANALOG_INPUT:
case OBJECT_BINARY_INPUT:
error_class = ERROR_CLASS_PROPERTY;
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error!\n");
#endif
break;
case OBJECT_BINARY_OUTPUT:
if (Binary_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for BO!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for BO!\n");
#endif
}
break;
case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for BV!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for BV!\n");
#endif
}
break;
case OBJECT_ANALOG_OUTPUT:
if (Analog_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for AO!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for AO!\n");
#endif
}
break;
case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for AV!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for AV!\n");
#endif
}
break;
case OBJECT_LIFE_SAFETY_POINT:
if (Life_Safety_Point_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for LSP!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for LSP!\n");
#endif
}
break;
case OBJECT_LOAD_CONTROL:
if (Load_Control_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for Load Control!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Write Access Error for Load Control!\n");
#endif
}
break;
case OBJECT_MULTI_STATE_OUTPUT:
if (Multistate_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Write Property Simple Ack for MSO!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for MSO!\n");
#endif
}
break;
#if defined(BACFILE)
case OBJECT_FILE:
if (bacfile_write_property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Simple Ack for File!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class,
error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for File!\n");
#endif
}
break;
#endif /* BACFILE */
default:
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Unknown Object Error!\n");
#endif
break;
}
WP_ABORT:
switch (wp_data.object_type) {
case OBJECT_DEVICE:
if (Device_Write_Property(&wp_data, &error_class, &error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for Device!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Error for Device!\n");
#endif
}
break;
case OBJECT_ANALOG_INPUT:
case OBJECT_BINARY_INPUT:
error_class = ERROR_CLASS_PROPERTY;
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error!\n");
#endif
break;
case OBJECT_BINARY_OUTPUT:
if (Binary_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for BO!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for BO!\n");
#endif
}
break;
case OBJECT_BINARY_VALUE:
if (Binary_Value_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for BV!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for BV!\n");
#endif
}
break;
case OBJECT_ANALOG_OUTPUT:
if (Analog_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for AO!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for AO!\n");
#endif
}
break;
case OBJECT_ANALOG_VALUE:
if (Analog_Value_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for AV!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for AV!\n");
#endif
}
break;
case OBJECT_LIFE_SAFETY_POINT:
if (Life_Safety_Point_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for LSP!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for LSP!\n");
#endif
}
break;
case OBJECT_LOAD_CONTROL:
if (Load_Control_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for Load Control!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Write Access Error for Load Control!\n");
#endif
}
break;
case OBJECT_MULTI_STATE_OUTPUT:
if (Multistate_Output_Write_Property(&wp_data, &error_class,
&error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr,
"WP: Sending Write Property Simple Ack for MSO!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for MSO!\n");
#endif
}
break;
#if defined(BACFILE)
case OBJECT_FILE:
if (bacfile_write_property(&wp_data, &error_class, &error_code)) {
len =
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack for File!\n");
#endif
} else {
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id,
SERVICE_CONFIRMED_WRITE_PROPERTY, error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Write Access Error for File!\n");
#endif
}
break;
#endif /* BACFILE */
default:
len =
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY,
error_class, error_code);
#if PRINT_ENABLED
fprintf(stderr, "WP: Sending Unknown Object Error!\n");
#endif
break;
}
WP_ABORT:
pdu_len += len;
bytes_sent = datalink_send_pdu(src, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+4 -2
View File
@@ -34,9 +34,11 @@
#include "npdu.h"
#include "reject.h"
void handler_unrecognized_service(uint8_t * service_request,
void handler_unrecognized_service(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data)
{
int len = 0;
int pdu_len = 0;
+4 -2
View File
@@ -42,9 +42,11 @@
#include "handlers.h"
#include "txbuf.h"
uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id,
uint8_t Send_Atomic_Read_File_Stream(
uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, unsigned requestedOctetCount)
int fileStartPosition,
unsigned requestedOctetCount)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
+6 -6
View File
@@ -42,9 +42,11 @@
#include "handlers.h"
#include "txbuf.h"
uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
uint8_t Send_Atomic_Write_File_Stream(
uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, BACNET_OCTET_STRING * fileData)
int fileStartPosition,
BACNET_OCTET_STRING * fileData)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -76,8 +78,7 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
if (status) {
/* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, true,
MESSAGE_PRIORITY_NORMAL);
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len =
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data);
@@ -116,8 +117,7 @@ uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
invoke_id = 0;
#if PRINT_ENABLED
fprintf(stderr, "Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds octet string capacity)!\n",
pdu_len);
"(payload [%d] exceeds octet string capacity)!\n", pdu_len);
#endif
}
}
+6 -3
View File
@@ -42,9 +42,12 @@
#include "handlers.h"
#include "txbuf.h"
uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password)
{ /* NULL=optional */
uint8_t Send_Device_Communication_Control_Request(
uint32_t device_id,
uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE state,
char *password)
{ /* NULL=optional */
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
unsigned max_apdu = 0;
+4 -2
View File
@@ -44,9 +44,11 @@
#include "txbuf.h"
/* find a specific device, or use -1 for limit if you want unlimited */
void Send_I_Have(uint32_t device_id,
void Send_I_Have(
uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, char *object_name)
uint32_t object_instance,
char *object_name)
{
int len = 0;
int pdu_len = 0;
+4 -2
View File
@@ -42,8 +42,10 @@
#include "handlers.h"
#include "txbuf.h"
uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
BACNET_REINITIALIZED_STATE state, char *password)
uint8_t Send_Reinitialize_Device_Request(
uint32_t device_id,
BACNET_REINITIALIZED_STATE state,
char *password)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
+5 -4
View File
@@ -44,10 +44,12 @@
#include "txbuf.h"
/* returns invoke id of 0 if device is not bound or no tsm available */
uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
uint8_t Send_Read_Property_Request(
uint32_t device_id, /* destination device */
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property, int32_t array_index)
BACNET_PROPERTY_ID object_property,
int32_t array_index)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -89,8 +91,7 @@ uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t) pdu_len);
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
+6 -2
View File
@@ -42,7 +42,9 @@
#include "handlers.h"
#include "txbuf.h"
void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime)
void Send_TimeSync(
BACNET_DATE * bdate,
BACNET_TIME * btime)
{
int len = 0;
int pdu_len = 0;
@@ -74,7 +76,9 @@ void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime)
#endif
}
void Send_TimeSyncUTC(BACNET_DATE * bdate, BACNET_TIME * btime)
void Send_TimeSyncUTC(
BACNET_DATE * bdate,
BACNET_TIME * btime)
{
int pdu_len = 0;
BACNET_ADDRESS dest;
+8 -4
View File
@@ -43,8 +43,10 @@
#include "txbuf.h"
/* find a specific device, or use -1 for limit if you want unlimited */
void Send_WhoHas_Name(int32_t low_limit,
int32_t high_limit, char *object_name)
void Send_WhoHas_Name(
int32_t low_limit,
int32_t high_limit,
char *object_name)
{
int len = 0;
int pdu_len = 0;
@@ -80,9 +82,11 @@ void Send_WhoHas_Name(int32_t low_limit,
}
/* find a specific device, or use -1 for limit if you want unlimited */
void Send_WhoHas_Object(int32_t low_limit,
void Send_WhoHas_Object(
int32_t low_limit,
int32_t high_limit,
BACNET_OBJECT_TYPE object_type, uint32_t object_instance)
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance)
{
int len = 0;
int pdu_len = 0;
+3 -1
View File
@@ -44,7 +44,9 @@
#include "txbuf.h"
/* find a specific device, or use -1 for limit if you want unlimited */
void Send_WhoIs(int32_t low_limit, int32_t high_limit)
void Send_WhoIs(
int32_t low_limit,
int32_t high_limit)
{
int len = 0;
int pdu_len = 0;
+14 -10
View File
@@ -44,12 +44,15 @@
#include "txbuf.h"
/* returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
uint8_t Send_Write_Property_Request_Data(
uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
uint8_t * application_data,
int application_data_len, uint8_t priority, int32_t array_index)
int application_data_len,
uint8_t priority,
int32_t array_index)
{
BACNET_ADDRESS dest;
BACNET_ADDRESS my_address;
@@ -95,8 +98,7 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
max_apdu in the address binding table. */
if ((unsigned) pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest,
&npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t) pdu_len);
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len);
bytes_sent =
datalink_send_pdu(&dest, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len);
@@ -119,12 +121,14 @@ uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
return invoke_id;
}
uint8_t Send_Write_Property_Request(uint32_t device_id,
uint8_t Send_Write_Property_Request(
uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
BACNET_APPLICATION_DATA_VALUE * object_value,
uint8_t priority, int32_t array_index)
uint8_t priority,
int32_t array_index)
{
uint8_t application_data[MAX_APDU] = { 0 };
int apdu_len = 0, len = 0;
@@ -133,11 +137,11 @@ uint8_t Send_Write_Property_Request(uint32_t device_id,
#if PRINT_ENABLED_DEBUG
fprintf(stderr, "WriteProperty service: "
"%s tag=%d\n",
(object_value->context_specific?"context":"application"),
(int)(object_value->context_specific?object_value->context_tag:object_value->tag) );
(object_value->context_specific ? "context" : "application"),
(int) (object_value->context_specific ? object_value->
context_tag : object_value->tag));
#endif
len = bacapp_encode_data(&application_data[apdu_len],
object_value);
len = bacapp_encode_data(&application_data[apdu_len], object_value);
if ((len + apdu_len) < MAX_APDU) {
apdu_len += len;
} else {
+76 -68
View File
@@ -31,13 +31,12 @@
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#define MAX_ANALOG_INPUTS 7
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Input_Properties_Required[] =
{
static const int Analog_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -49,14 +48,12 @@ static const int Analog_Input_Properties_Required[] =
-1
};
static const int Analog_Input_Properties_Optional[] =
{
static const int Analog_Input_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Analog_Input_Properties_Proprietary[] =
{
static const int Analog_Input_Properties_Proprietary[] = {
9997,
9998,
9999,
@@ -81,7 +78,8 @@ void Analog_Input_Property_Lists(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(uint32_t object_instance)
bool Analog_Input_Valid_Instance(
uint32_t object_instance)
{
if (object_instance < MAX_ANALOG_INPUTS)
return true;
@@ -91,7 +89,8 @@ bool Analog_Input_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Input_Count(void)
unsigned Analog_Input_Count(
void)
{
return MAX_ANALOG_INPUTS;
}
@@ -99,12 +98,14 @@ unsigned Analog_Input_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Input_Index_To_Instance(unsigned index)
uint32_t Analog_Input_Index_To_Instance(
unsigned index)
{
return index;
}
char *Analog_Input_Name(uint32_t object_instance)
char *Analog_Input_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -118,67 +119,73 @@ char *Analog_Input_Name(uint32_t object_instance)
/* return apdu length, or -1 on error */
/* assumption - object has already exists */
int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
int Analog_Input_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float value = 3.14159F;
(void) array_index;
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break;
case PROP_PRESENT_VALUE:
apdu_len = encode_application_real(&apdu[0], value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case 9997:
apdu_len = encode_application_real(&apdu[0], (float) 90.510);
break;
case 9998:
apdu_len = encode_application_unsigned(&apdu[0], 90);
break;
/* test case for signed encoding-decoding negative value correctly */
case 9999:
apdu_len = encode_application_signed(&apdu[0], -200);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Input_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_INPUT);
break;
case PROP_PRESENT_VALUE:
apdu_len = encode_application_real(&apdu[0], value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case 9997:
apdu_len = encode_application_real(&apdu[0], (float) 90.510);
break;
case 9998:
apdu_len = encode_application_unsigned(&apdu[0], 90);
break;
/* test case for signed encoding-decoding negative value correctly */
case 9999:
apdu_len = encode_application_signed(&apdu[0], -200);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
@@ -189,7 +196,8 @@ int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
#include <string.h>
#include "ctest.h"
void testAnalogInput(Test * pTest)
void testAnalogInput(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -205,8 +213,7 @@ void testAnalogInput(Test * pTest)
/* FIXME: we should do a lot more testing here... */
len = Analog_Input_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len >= 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -219,7 +226,8 @@ void testAnalogInput(Test * pTest)
}
#ifdef TEST_ANALOG_INPUT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -236,5 +244,5 @@ int main(void)
return 0;
}
#endif /* TEST_ANALOG_INPUT */
#endif /* TEST */
#endif /* TEST_ANALOG_INPUT */
#endif /* TEST */
+184 -166
View File
@@ -32,7 +32,7 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_ANALOG_OUTPUTS 4
@@ -47,8 +47,7 @@
/* Here is our Priority Array. They are supposed to be Real, but */
/* we don't have that kind of memory, so we will use a single byte */
/* and load a Real for returning the value when asked. */
static uint8_t
Analog_Output_Level[MAX_ANALOG_OUTPUTS][BACNET_MAX_PRIORITY];
static uint8_t Analog_Output_Level[MAX_ANALOG_OUTPUTS][BACNET_MAX_PRIORITY];
/* Writable out-of-service allows others to play with our Present Value */
/* without changing the physical output */
static bool Analog_Output_Out_Of_Service[MAX_ANALOG_OUTPUTS];
@@ -57,8 +56,7 @@ static bool Analog_Output_Out_Of_Service[MAX_ANALOG_OUTPUTS];
static bool Analog_Output_Initialized = false;
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Output_Properties_Required[] =
{
static const int Analog_Output_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -72,14 +70,12 @@ static const int Analog_Output_Properties_Required[] =
-1
};
static const int Analog_Output_Properties_Optional[] =
{
static const int Analog_Output_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Analog_Output_Properties_Proprietary[] =
{
static const int Analog_Output_Properties_Proprietary[] = {
-1
};
@@ -98,7 +94,8 @@ void Analog_Output_Property_Lists(
return;
}
void Analog_Output_Init(void)
void Analog_Output_Init(
void)
{
unsigned i, j;
@@ -119,7 +116,8 @@ void Analog_Output_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Output_Valid_Instance(uint32_t object_instance)
bool Analog_Output_Valid_Instance(
uint32_t object_instance)
{
Analog_Output_Init();
if (object_instance < MAX_ANALOG_OUTPUTS)
@@ -130,7 +128,8 @@ bool Analog_Output_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Output_Count(void)
unsigned Analog_Output_Count(
void)
{
Analog_Output_Init();
return MAX_ANALOG_OUTPUTS;
@@ -139,7 +138,8 @@ unsigned Analog_Output_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Output_Index_To_Instance(unsigned index)
uint32_t Analog_Output_Index_To_Instance(
unsigned index)
{
Analog_Output_Init();
return index;
@@ -148,7 +148,8 @@ uint32_t Analog_Output_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Analog_Output_Instance_To_Index(uint32_t object_instance)
unsigned Analog_Output_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_ANALOG_OUTPUTS;
@@ -159,7 +160,8 @@ unsigned Analog_Output_Instance_To_Index(uint32_t object_instance)
return index;
}
float Analog_Output_Present_Value(uint32_t object_instance)
float Analog_Output_Present_Value(
uint32_t object_instance)
{
float value = AO_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -179,10 +181,11 @@ float Analog_Output_Present_Value(uint32_t object_instance)
return value;
}
unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance)
unsigned Analog_Output_Present_Value_Priority(
uint32_t object_instance)
{
unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */
unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */
unsigned priority = 0; /* return value */
Analog_Output_Init();
@@ -199,8 +202,10 @@ unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance)
return priority;
}
bool Analog_Output_Present_Value_Set(uint32_t object_instance,
float value, unsigned priority)
bool Analog_Output_Present_Value_Set(
uint32_t object_instance,
float value,
unsigned priority)
{
unsigned index = 0;
bool status = false;
@@ -210,7 +215,7 @@ bool Analog_Output_Present_Value_Set(uint32_t object_instance,
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value >= 0.0) && (value <= 100.0)) {
Analog_Output_Level[index][priority-1] = (uint8_t) value;
Analog_Output_Level[index][priority - 1] = (uint8_t) value;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
@@ -224,7 +229,8 @@ bool Analog_Output_Present_Value_Set(uint32_t object_instance,
return status;
}
bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
bool Analog_Output_Present_Value_Relinquish(
uint32_t object_instance,
unsigned priority)
{
unsigned index = 0;
@@ -234,7 +240,7 @@ bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
if (index < MAX_ANALOG_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ )) {
Analog_Output_Level[index][priority-1] = AO_LEVEL_NULL;
Analog_Output_Level[index][priority - 1] = AO_LEVEL_NULL;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
@@ -249,7 +255,8 @@ bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
}
/* note: the object name must be unique within this device */
char *Analog_Output_Name(uint32_t object_instance)
char *Analog_Output_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -262,14 +269,16 @@ char *Analog_Output_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Analog_Output_Encode_Property_APDU(uint8_t * apdu,
int Analog_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float real_value = (float) 1.414;
@@ -279,107 +288,115 @@ int Analog_Output_Encode_Property_APDU(uint8_t * apdu,
Analog_Output_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_ANALOG_OUTPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Output_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_OUTPUT);
break;
case PROP_PRESENT_VALUE:
real_value = Analog_Output_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Analog_Output_Instance_To_Index(object_instance);
state = Analog_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Analog_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Analog_Output_Level[object_index][i] == AO_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
real_value = Analog_Output_Level[object_index][i];
len = encode_application_real(&apdu[apdu_len], real_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
object_index =
Analog_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Analog_Output_Level[object_index][array_index - 1] ==
AO_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value =
Analog_Output_Level[object_index][array_index - 1];
apdu_len = encode_application_real(&apdu[0], real_value);
encode_application_object_id(&apdu[0], OBJECT_ANALOG_OUTPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Output_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_OUTPUT);
break;
case PROP_PRESENT_VALUE:
real_value = Analog_Output_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Analog_Output_Instance_To_Index(object_instance);
state = Analog_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Analog_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Analog_Output_Level[object_index][i] == AO_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
real_value = Analog_Output_Level[object_index][i];
len =
encode_application_real(&apdu[apdu_len],
real_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
object_index =
Analog_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Analog_Output_Level[object_index][array_index - 1] ==
AO_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value =
Analog_Output_Level[object_index][array_index - 1];
apdu_len =
encode_application_real(&apdu[0], real_value);
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
}
}
}
break;
case PROP_RELINQUISH_DEFAULT:
real_value = AO_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
break;
case PROP_RELINQUISH_DEFAULT:
real_value = AO_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Analog_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -399,56 +416,56 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Analog_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
if (wp_data->priority == 6) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Analog_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = AO_LEVEL_NULL;
object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance);
status =
Analog_Output_Present_Value_Relinquish(wp_data->
object_instance, wp_data->priority);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = AO_LEVEL_NULL;
object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance);
status =
Analog_Output_Present_Value_Relinquish(wp_data->
object_instance, wp_data->priority);
if (!status) {
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance);
Analog_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Analog_Output_Instance_To_Index(wp_data->object_instance);
Analog_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -460,7 +477,8 @@ bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testAnalogOutput(Test * pTest)
void testAnalogOutput(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -475,8 +493,7 @@ void testAnalogOutput(Test * pTest)
len = Analog_Output_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -489,7 +506,8 @@ void testAnalogOutput(Test * pTest)
}
#ifdef TEST_ANALOG_OUTPUT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -506,5 +524,5 @@ int main(void)
return 0;
}
#endif /* TEST_ANALOG_INPUT */
#endif /* TEST */
#endif /* TEST_ANALOG_INPUT */
#endif /* TEST */
+186 -170
View File
@@ -32,7 +32,7 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_ANALOG_VALUES 4
@@ -56,8 +56,7 @@ static bool Analog_Value_Out_Of_Service[MAX_ANALOG_VALUES];
static bool Analog_Value_Initialized = false;
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Value_Properties_Required[] =
{
static const int Analog_Value_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -69,16 +68,14 @@ static const int Analog_Value_Properties_Required[] =
-1
};
static const int Analog_Value_Properties_Optional[] =
{
static const int Analog_Value_Properties_Optional[] = {
PROP_DESCRIPTION,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
static const int Analog_Value_Properties_Proprietary[] =
{
static const int Analog_Value_Properties_Proprietary[] = {
-1
};
@@ -97,7 +94,8 @@ void Analog_Value_Property_Lists(
return;
}
void Analog_Value_Init(void)
void Analog_Value_Init(
void)
{
unsigned i, j;
@@ -118,7 +116,8 @@ void Analog_Value_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Value_Valid_Instance(uint32_t object_instance)
bool Analog_Value_Valid_Instance(
uint32_t object_instance)
{
Analog_Value_Init();
if (object_instance < MAX_ANALOG_VALUES)
@@ -129,7 +128,8 @@ bool Analog_Value_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Analog_Value_Count(void)
unsigned Analog_Value_Count(
void)
{
Analog_Value_Init();
return MAX_ANALOG_VALUES;
@@ -138,7 +138,8 @@ unsigned Analog_Value_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance(unsigned index)
uint32_t Analog_Value_Index_To_Instance(
unsigned index)
{
Analog_Value_Init();
return index;
@@ -147,7 +148,8 @@ uint32_t Analog_Value_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
unsigned Analog_Value_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_ANALOG_VALUES;
@@ -158,7 +160,8 @@ unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
return index;
}
static float Analog_Value_Present_Value(uint32_t object_instance)
static float Analog_Value_Present_Value(
uint32_t object_instance)
{
float value = ANALOG_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -179,7 +182,8 @@ static float Analog_Value_Present_Value(uint32_t object_instance)
}
/* note: the object name must be unique within this device */
char *Analog_Value_Name(uint32_t object_instance)
char *Analog_Value_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -192,14 +196,16 @@ char *Analog_Value_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
int Analog_Value_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float real_value = (float) 1.414;
@@ -209,106 +215,115 @@ int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
Analog_Value_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Value_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
break;
case PROP_PRESENT_VALUE:
real_value = Analog_Value_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Analog_Value_Instance_To_Index(object_instance);
state = Analog_Value_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Analog_Value_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_ANALOG_VALUE);
break;
case PROP_PRESENT_VALUE:
real_value = Analog_Value_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Analog_Value_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Analog_Value_Level[object_index][i] ==
ANALOG_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
real_value = Analog_Value_Level[object_index][i];
len = encode_application_real(&apdu[apdu_len], real_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
object_index = Analog_Value_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Analog_Value_Level[object_index][array_index - 1] ==
ANALOG_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value =
Analog_Value_Level[object_index][array_index - 1];
apdu_len = encode_application_real(&apdu[0], real_value);
state = Analog_Value_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index = Analog_Value_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Analog_Value_Level[object_index][i] ==
ANALOG_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
real_value = Analog_Value_Level[object_index][i];
len =
encode_application_real(&apdu[apdu_len],
real_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
object_index = Analog_Value_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Analog_Value_Level[object_index][array_index - 1] ==
ANALOG_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value =
Analog_Value_Level[object_index][array_index - 1];
apdu_len =
encode_application_real(&apdu[0], real_value);
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
}
}
}
break;
case PROP_RELINQUISH_DEFAULT:
real_value = ANALOG_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
break;
case PROP_RELINQUISH_DEFAULT:
real_value = ANALOG_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -329,76 +344,76 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
level = (uint8_t) value.type.Real;
object_index =
Analog_Value_Instance_To_Index(wp_data->
object_instance);
priority--;
Analog_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Real >= 0.0) && (value.type.Real <= 100.0)) {
level = (uint8_t) value.type.Real;
object_index =
Analog_Value_Instance_To_Index(wp_data->
object_instance);
priority--;
Analog_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = ANALOG_LEVEL_NULL;
object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Analog_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = ANALOG_LEVEL_NULL;
object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Analog_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance);
Analog_Value_Out_Of_Service[object_index] = value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Analog_Value_Instance_To_Index(wp_data->object_instance);
Analog_Value_Out_Of_Service[object_index] = value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -410,7 +425,8 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testAnalog_Value(Test * pTest)
void testAnalog_Value(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -425,8 +441,7 @@ void testAnalog_Value(Test * pTest)
len = Analog_Value_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -439,7 +454,8 @@ void testAnalog_Value(Test * pTest)
}
#ifdef TEST_ANALOG_VALUE
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -456,5 +472,5 @@ int main(void)
return 0;
}
#endif /* TEST_ANALOG_VALUE */
#endif /* TEST */
#endif /* TEST_ANALOG_VALUE */
#endif /* TEST */
+137 -123
View File
@@ -49,12 +49,11 @@ static BACNET_FILE_LISTING BACnet_File_Listing[] = {
{0, "temp_0.txt"},
{1, "temp_1.txt"},
{2, "temp_2.txt"},
{0, NULL} /* last file indication */
{0, NULL} /* last file indication */
};
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int bacfile_Properties_Required[] =
{
static const int bacfile_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -67,14 +66,12 @@ static const int bacfile_Properties_Required[] =
-1
};
static const int bacfile_Properties_Optional[] =
{
static const int bacfile_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int bacfile_Properties_Proprietary[] =
{
static const int bacfile_Properties_Proprietary[] = {
-1
};
@@ -94,7 +91,8 @@ void BACfile_Property_Lists(
}
char *bacfile_name(uint32_t instance)
char *bacfile_name(
uint32_t instance)
{
uint32_t index = 0;
char *filename = NULL;
@@ -111,12 +109,14 @@ char *bacfile_name(uint32_t instance)
return filename;
}
bool bacfile_valid_instance(uint32_t object_instance)
bool bacfile_valid_instance(
uint32_t object_instance)
{
return bacfile_name(object_instance) ? true : false;
}
uint32_t bacfile_count(void)
uint32_t bacfile_count(
void)
{
uint32_t index = 0;
@@ -128,7 +128,8 @@ uint32_t bacfile_count(void)
return index;
}
uint32_t bacfile_index_to_instance(unsigned find_index)
uint32_t bacfile_index_to_instance(
unsigned find_index)
{
uint32_t instance = BACNET_MAX_INSTANCE + 1;
uint32_t index = 0;
@@ -145,7 +146,8 @@ uint32_t bacfile_index_to_instance(unsigned find_index)
return instance;
}
static long fsize(FILE * pFile)
static long fsize(
FILE * pFile)
{
long size = 0;
long origin = 0;
@@ -159,7 +161,8 @@ static long fsize(FILE * pFile)
return (size);
}
static unsigned bacfile_file_size(uint32_t object_instance)
static unsigned bacfile_file_size(
uint32_t object_instance)
{
char *pFilename = NULL;
FILE *pFile = NULL;
@@ -178,13 +181,15 @@ static unsigned bacfile_file_size(uint32_t object_instance)
}
/* return the number of bytes used, or -1 on error */
int bacfile_encode_property_apdu(uint8_t * apdu,
int bacfile_encode_property_apdu(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
char text_string[32] = { "" };
BACNET_CHARACTER_STRING char_string;
BACNET_DATE bdate;
@@ -192,76 +197,82 @@ int bacfile_encode_property_apdu(uint8_t * apdu,
(void) array_index;
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0],
OBJECT_FILE, object_instance);
break;
case PROP_OBJECT_NAME:
sprintf(text_string, "FILE %d", object_instance);
characterstring_init_ansi(&char_string, text_string);
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_FILE);
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
bacfile_name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_FILE_TYPE:
characterstring_init_ansi(&char_string, "TEXT");
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_FILE_SIZE:
apdu_len = encode_application_unsigned(&apdu[0],
bacfile_file_size(object_instance));
break;
case PROP_MODIFICATION_DATE:
/* FIXME: get the actual value instead of April Fool's Day */
bdate.year = 2006; /* AD */
bdate.month = 4; /* 1=Jan */
bdate.day = 1; /* 1..31 */
bdate.wday = 6; /* 1=Monday */
apdu_len = encode_application_date(&apdu[0], &bdate);
/* FIXME: get the actual value */
btime.hour = 7;
btime.min = 0;
btime.sec = 3;
btime.hundredths = 1;
apdu_len += encode_application_time(&apdu[apdu_len], &btime);
break;
case PROP_ARCHIVE:
/* 12.13.8 Archive
This property, of type BOOLEAN, indicates whether the File
object has been saved for historical or backup purposes. This
property shall be logical TRUE only if no changes have been
made to the file data by internal processes or through File
Access Services since the last time the object was archived.
*/
/* FIXME: get the actual value: note it may be inverse... */
apdu_len = encode_application_boolean(&apdu[0], true);
break;
case PROP_READ_ONLY:
/* FIXME: get the actual value */
apdu_len = encode_application_boolean(&apdu[0], true);
break;
case PROP_FILE_ACCESS_METHOD:
apdu_len = encode_application_enumerated(&apdu[0], FILE_STREAM_ACCESS);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0],
OBJECT_FILE, object_instance);
break;
case PROP_OBJECT_NAME:
sprintf(text_string, "FILE %d", object_instance);
characterstring_init_ansi(&char_string, text_string);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_FILE);
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
bacfile_name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_FILE_TYPE:
characterstring_init_ansi(&char_string, "TEXT");
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_FILE_SIZE:
apdu_len = encode_application_unsigned(&apdu[0],
bacfile_file_size(object_instance));
break;
case PROP_MODIFICATION_DATE:
/* FIXME: get the actual value instead of April Fool's Day */
bdate.year = 2006; /* AD */
bdate.month = 4; /* 1=Jan */
bdate.day = 1; /* 1..31 */
bdate.wday = 6; /* 1=Monday */
apdu_len = encode_application_date(&apdu[0], &bdate);
/* FIXME: get the actual value */
btime.hour = 7;
btime.min = 0;
btime.sec = 3;
btime.hundredths = 1;
apdu_len += encode_application_time(&apdu[apdu_len], &btime);
break;
case PROP_ARCHIVE:
/* 12.13.8 Archive
This property, of type BOOLEAN, indicates whether the File
object has been saved for historical or backup purposes. This
property shall be logical TRUE only if no changes have been
made to the file data by internal processes or through File
Access Services since the last time the object was archived.
*/
/* FIXME: get the actual value: note it may be inverse... */
apdu_len = encode_application_boolean(&apdu[0], true);
break;
case PROP_READ_ONLY:
/* FIXME: get the actual value */
apdu_len = encode_application_boolean(&apdu[0], true);
break;
case PROP_FILE_ACCESS_METHOD:
apdu_len =
encode_application_enumerated(&apdu[0], FILE_STREAM_ACCESS);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool bacfile_write_property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
int len = 0;
@@ -279,40 +290,40 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_ARCHIVE:
/* 12.13.8 Archive
This property, of type BOOLEAN, indicates whether the File
object has been saved for historical or backup purposes. This
property shall be logical TRUE only if no changes have been
made to the file data by internal processes or through File
Access Services since the last time the object was archived. */
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.type.Boolean) {
/* FIXME: do something to wp_data->object_instance */
case PROP_ARCHIVE:
/* 12.13.8 Archive
This property, of type BOOLEAN, indicates whether the File
object has been saved for historical or backup purposes. This
property shall be logical TRUE only if no changes have been
made to the file data by internal processes or through File
Access Services since the last time the object was archived. */
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
if (value.type.Boolean) {
/* FIXME: do something to wp_data->object_instance */
} else {
/* FIXME: do something to wp_data->object_instance */
}
} else {
/* FIXME: do something to wp_data->object_instance */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
case PROP_FILE_SIZE:
/* If the file size can be changed by writing to the file,
and File_Access_Method is STREAM_ACCESS, then this property
shall be writable. */
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
/* FIXME: do something with value.type.Unsigned
to wp_data->object_instance */
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_FILE_SIZE:
/* If the file size can be changed by writing to the file,
and File_Access_Method is STREAM_ACCESS, then this property
shall be writable. */
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
/* FIXME: do something with value.type.Unsigned
to wp_data->object_instance */
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -320,7 +331,8 @@ bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data,
uint32_t bacfile_instance(char *filename)
uint32_t bacfile_instance(
char *filename)
{
uint32_t index = 0;
uint32_t instance = BACNET_MAX_INSTANCE + 1;
@@ -343,7 +355,8 @@ uint32_t bacfile_instance(char *filename)
/* Another way would be to store the */
/* invokeID and file instance in a list or table */
/* when the request was sent */
uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
uint32_t bacfile_instance_from_tsm(
uint8_t invokeID)
{
BACNET_NPDU_DATA npdu_data = { 0 }; /* dummy for getting npdu length */
BACNET_CONFIRMED_SERVICE_DATA service_data = { 0 };
@@ -353,7 +366,7 @@ uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
BACNET_ADDRESS dest; /* where the original packet was destined */
uint8_t apdu[MAX_PDU] = { 0 }; /* original APDU packet */
uint16_t apdu_len = 0; /* original APDU packet length */
uint16_t len = 0; /* apdu header length */
uint16_t len = 0; /* apdu header length */
BACNET_ATOMIC_READ_FILE_DATA data = { 0 };
uint32_t object_instance = BACNET_MAX_INSTANCE + 1; /* return value */
bool found = false;
@@ -383,7 +396,8 @@ uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
}
#endif
bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA * data)
bool bacfile_read_data(
BACNET_ATOMIC_READ_FILE_DATA * data)
{
char *pFilename = NULL;
bool found = false;
@@ -395,8 +409,7 @@ bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA * data)
found = true;
pFile = fopen(pFilename, "rb");
if (pFile) {
(void) fseek(pFile,
data->type.stream.fileStartPosition, SEEK_SET);
(void) fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
len = fread(octetstring_value(&data->fileData), 1,
data->type.stream.requestedOctetCount, pFile);
if (len < data->type.stream.requestedOctetCount)
@@ -417,7 +430,8 @@ bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA * data)
return found;
}
bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA * data)
bool bacfile_write_stream_data(
BACNET_ATOMIC_WRITE_FILE_DATA * data)
{
char *pFilename = NULL;
bool found = false;
@@ -428,15 +442,15 @@ bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA * data)
found = true;
/* open the file as a clean slate when starting at 0 */
if (data->type.stream.fileStartPosition == 0)
pFile = fopen(pFilename, "wb");
pFile = fopen(pFilename, "wb");
else
pFile = fopen(pFilename, "rb+");
pFile = fopen(pFilename, "rb+");
if (pFile) {
(void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
(void) fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
if (fwrite(octetstring_value(&data->fileData),
octetstring_length(&data->fileData),1,pFile) != 1) {
octetstring_length(&data->fileData), 1, pFile) != 1) {
}
}
fclose(pFile);
}
}
+78 -68
View File
@@ -31,15 +31,14 @@
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#define MAX_BINARY_INPUTS 5
static BACNET_BINARY_PV Present_Value[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Input_Properties_Required[] =
{
static const int Binary_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -51,14 +50,12 @@ static const int Binary_Input_Properties_Required[] =
-1
};
static const int Binary_Input_Properties_Optional[] =
{
static const int Binary_Input_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Binary_Input_Properties_Proprietary[] =
{
static const int Binary_Input_Properties_Proprietary[] = {
-1
};
@@ -80,7 +77,8 @@ void Binary_Input_Property_Lists(
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Binary_Input_Valid_Instance(uint32_t object_instance)
bool Binary_Input_Valid_Instance(
uint32_t object_instance)
{
if (object_instance < MAX_BINARY_INPUTS)
return true;
@@ -90,7 +88,8 @@ bool Binary_Input_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Binary_Input_Count(void)
unsigned Binary_Input_Count(
void)
{
return MAX_BINARY_INPUTS;
}
@@ -98,12 +97,14 @@ unsigned Binary_Input_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Binary_Input_Index_To_Instance(unsigned index)
uint32_t Binary_Input_Index_To_Instance(
unsigned index)
{
return index;
}
void Binary_Input_Init(void)
void Binary_Input_Init(
void)
{
static bool initialized = false;
unsigned i;
@@ -123,7 +124,8 @@ void Binary_Input_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
unsigned Binary_Input_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_BINARY_INPUTS;
@@ -134,8 +136,8 @@ unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
return index;
}
static BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t
object_instance)
static BACNET_BINARY_PV Binary_Input_Present_Value(
uint32_t object_instance)
{
BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0;
@@ -148,7 +150,8 @@ static BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t
return value;
}
char *Binary_Input_Name(uint32_t object_instance)
char *Binary_Input_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -163,13 +166,15 @@ char *Binary_Input_Name(uint32_t object_instance)
/* return apdu length, or -1 on error */
/* assumption - object already exists, and has been bounds checked */
int Binary_Input_Encode_Property_APDU(uint8_t * apdu,
int Binary_Input_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_POLARITY polarity = POLARITY_NORMAL;
@@ -178,50 +183,54 @@ int Binary_Input_Encode_Property_APDU(uint8_t * apdu,
(void) array_index;
Binary_Input_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* note: object name must be unique in our device */
characterstring_init_ansi(&char_string,
Binary_Input_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
break;
case PROP_PRESENT_VALUE:
/* note: you need to look up the actual value */
apdu_len =
encode_application_enumerated(&apdu[0],
Binary_Input_Present_Value(object_instance));
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false);
break;
case PROP_POLARITY:
apdu_len = encode_application_enumerated(&apdu[0], polarity);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* note: object name must be unique in our device */
characterstring_init_ansi(&char_string,
Binary_Input_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_BINARY_INPUT);
break;
case PROP_PRESENT_VALUE:
/* note: you need to look up the actual value */
apdu_len =
encode_application_enumerated(&apdu[0],
Binary_Input_Present_Value(object_instance));
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0], false);
break;
case PROP_POLARITY:
apdu_len = encode_application_enumerated(&apdu[0], polarity);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
@@ -232,7 +241,8 @@ int Binary_Input_Encode_Property_APDU(uint8_t * apdu,
#include <string.h>
#include "ctest.h"
void testBinaryInput(Test * pTest)
void testBinaryInput(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -248,8 +258,7 @@ void testBinaryInput(Test * pTest)
/* FIXME: we should do a lot more testing here... */
len = Binary_Input_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len >= 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -262,7 +271,8 @@ void testBinaryInput(Test * pTest)
}
#ifdef TEST_BINARY_INPUT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -279,5 +289,5 @@ int main(void)
return 0;
}
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
+195 -184
View File
@@ -32,7 +32,7 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_BINARY_OUTPUTS 6
@@ -48,8 +48,7 @@ static BACNET_BINARY_PV
static bool Binary_Output_Out_Of_Service[MAX_BINARY_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Output_Properties_Required[] =
{
static const int Binary_Output_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -63,14 +62,12 @@ static const int Binary_Output_Properties_Required[] =
-1
};
static const int Binary_Output_Properties_Optional[] =
{
static const int Binary_Output_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Binary_Output_Properties_Proprietary[] =
{
static const int Binary_Output_Properties_Proprietary[] = {
-1
};
@@ -89,7 +86,8 @@ void Binary_Output_Property_Lists(
return;
}
void Binary_Output_Init(void)
void Binary_Output_Init(
void)
{
unsigned i, j;
static bool initialized = false;
@@ -111,7 +109,8 @@ void Binary_Output_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Binary_Output_Valid_Instance(uint32_t object_instance)
bool Binary_Output_Valid_Instance(
uint32_t object_instance)
{
if (object_instance < MAX_BINARY_OUTPUTS)
return true;
@@ -121,7 +120,8 @@ bool Binary_Output_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Binary_Output_Count(void)
unsigned Binary_Output_Count(
void)
{
return MAX_BINARY_OUTPUTS;
}
@@ -129,7 +129,8 @@ unsigned Binary_Output_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Binary_Output_Index_To_Instance(unsigned index)
uint32_t Binary_Output_Index_To_Instance(
unsigned index)
{
return index;
}
@@ -137,7 +138,8 @@ uint32_t Binary_Output_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
unsigned Binary_Output_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_BINARY_OUTPUTS;
@@ -147,8 +149,8 @@ unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
return index;
}
static BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t
object_instance)
static BACNET_BINARY_PV Binary_Output_Present_Value(
uint32_t object_instance)
{
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -169,7 +171,8 @@ static BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t
}
/* note: the object name must be unique within this device */
char *Binary_Output_Name(uint32_t object_instance)
char *Binary_Output_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -182,14 +185,16 @@ char *Binary_Output_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Binary_Output_Encode_Property_APDU(uint8_t * apdu,
int Binary_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
@@ -200,116 +205,121 @@ int Binary_Output_Encode_Property_APDU(uint8_t * apdu,
Binary_Output_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Output_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT);
break;
case PROP_PRESENT_VALUE:
present_value = Binary_Output_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Binary_Output_Instance_To_Index(object_instance);
state = Binary_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_POLARITY:
apdu_len = encode_application_enumerated(&apdu[0], polarity);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Binary_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Binary_Output_Level[object_index][i] == BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Output_Level[object_index][i];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
object_index =
Binary_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Binary_Output_Level[object_index][array_index] ==
BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value =
Binary_Output_Level[object_index][array_index];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Output_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_BINARY_OUTPUT);
break;
case PROP_PRESENT_VALUE:
present_value = Binary_Output_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Binary_Output_Instance_To_Index(object_instance);
state = Binary_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_POLARITY:
apdu_len = encode_application_enumerated(&apdu[0], polarity);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Binary_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Binary_Output_Level[object_index][i] == BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Output_Level[object_index][i];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
object_index =
Binary_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Binary_Output_Level[object_index][array_index] ==
BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value =
Binary_Output_Level[object_index][array_index];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
}
}
}
break;
case PROP_RELINQUISH_DEFAULT:
present_value = RELINQUISH_DEFAULT;
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
break;
case PROP_RELINQUISH_DEFAULT:
present_value = RELINQUISH_DEFAULT;
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Binary_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -330,78 +340,78 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index =
Binary_Output_Instance_To_Index(wp_data->
object_instance);
priority--;
Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV) value.type.Enumerated;
object_index =
Binary_Output_Instance_To_Index(wp_data->
object_instance);
priority--;
Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
Binary_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance);
Binary_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -413,7 +423,8 @@ bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testBinaryOutput(Test * pTest)
void testBinaryOutput(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -428,8 +439,7 @@ void testBinaryOutput(Test * pTest)
len = Binary_Output_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -442,7 +452,8 @@ void testBinaryOutput(Test * pTest)
}
#ifdef TEST_BINARY_OUTPUT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -459,5 +470,5 @@ int main(void)
return 0;
}
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
+188 -176
View File
@@ -32,7 +32,7 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_BINARY_VALUES 2
@@ -48,8 +48,7 @@ static BACNET_BINARY_PV
static bool Binary_Value_Out_Of_Service[MAX_BINARY_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Binary_Value_Properties_Required[] =
{
static const int Binary_Value_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -60,16 +59,14 @@ static const int Binary_Value_Properties_Required[] =
-1
};
static const int Binary_Value_Properties_Optional[] =
{
static const int Binary_Value_Properties_Optional[] = {
PROP_DESCRIPTION,
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
static const int Binary_Value_Properties_Proprietary[] =
{
static const int Binary_Value_Properties_Proprietary[] = {
-1
};
@@ -88,7 +85,8 @@ void Binary_Value_Property_Lists(
return;
}
void Binary_Value_Init(void)
void Binary_Value_Init(
void)
{
unsigned i, j;
static bool initialized = false;
@@ -110,7 +108,8 @@ void Binary_Value_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Binary_Value_Valid_Instance(uint32_t object_instance)
bool Binary_Value_Valid_Instance(
uint32_t object_instance)
{
if (object_instance < MAX_BINARY_VALUES)
return true;
@@ -120,7 +119,8 @@ bool Binary_Value_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Binary_Value_Count(void)
unsigned Binary_Value_Count(
void)
{
return MAX_BINARY_VALUES;
}
@@ -128,7 +128,8 @@ unsigned Binary_Value_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Binary_Value_Index_To_Instance(unsigned index)
uint32_t Binary_Value_Index_To_Instance(
unsigned index)
{
return index;
}
@@ -136,7 +137,8 @@ uint32_t Binary_Value_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
unsigned Binary_Value_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_BINARY_VALUES;
@@ -146,8 +148,8 @@ unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
return index;
}
static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t
object_instance)
static BACNET_BINARY_PV Binary_Value_Present_Value(
uint32_t object_instance)
{
BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -168,7 +170,8 @@ static BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t
}
/* note: the object name must be unique within this device */
char *Binary_Value_Name(uint32_t object_instance)
char *Binary_Value_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -181,14 +184,16 @@ char *Binary_Value_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
int Binary_Value_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_BINARY_PV present_value = BINARY_INACTIVE;
@@ -198,110 +203,116 @@ int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
Binary_Value_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Value_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len = encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break;
case PROP_PRESENT_VALUE:
present_value = Binary_Value_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Binary_Value_Instance_To_Index(object_instance);
state = Binary_Value_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Binary_Value_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break;
case PROP_PRESENT_VALUE:
present_value = Binary_Value_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Binary_Value_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Binary_Value_Level[object_index][i] == BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Value_Level[object_index][i];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
object_index = Binary_Value_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Binary_Value_Level[object_index][array_index] ==
BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value =
Binary_Value_Level[object_index][array_index];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
state = Binary_Value_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index = Binary_Value_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Binary_Value_Level[object_index][i] == BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value = Binary_Value_Level[object_index][i];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
object_index = Binary_Value_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Binary_Value_Level[object_index][array_index] ==
BINARY_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value =
Binary_Value_Level[object_index][array_index];
len =
encode_application_enumerated(&apdu[apdu_len],
present_value);
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
}
}
}
break;
case PROP_RELINQUISH_DEFAULT:
present_value = RELINQUISH_DEFAULT;
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
break;
case PROP_RELINQUISH_DEFAULT:
present_value = RELINQUISH_DEFAULT;
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Binary_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -322,77 +333,77 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index =
Binary_Value_Instance_To_Index(wp_data->
object_instance);
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Enumerated >= MIN_BINARY_PV) &&
(value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV) value.type.Enumerated;
object_index =
Binary_Value_Instance_To_Index(wp_data->
object_instance);
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = BINARY_NULL;
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
Binary_Value_Out_Of_Service[object_index] = value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Binary_Value_Instance_To_Index(wp_data->object_instance);
Binary_Value_Out_Of_Service[object_index] = value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -404,7 +415,8 @@ bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testBinary_Value(Test * pTest)
void testBinary_Value(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -419,8 +431,7 @@ void testBinary_Value(Test * pTest)
len = Binary_Value_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -433,7 +444,8 @@ void testBinary_Value(Test * pTest)
}
#ifdef TEST_BINARY_VALUE
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -450,5 +462,5 @@ int main(void)
return 0;
}
#endif /* TEST_BINARY_VALUE */
#endif /* TEST */
#endif /* TEST_BINARY_VALUE */
#endif /* TEST */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+235 -208
View File
@@ -32,7 +32,7 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_LIGHTING_OUTPUTS 5
@@ -49,12 +49,12 @@
of the optional parameters, we represent them interally as
integers. */
typedef struct LightingCommand {
BACNET_LIGHTING_OPERATION operation;
uint8_t level; /* 0..100 percent, 255=not used */
uint8_t ramp_rate; /* 0..100 percent-per-second, 255=not used */
uint8_t step_increment; /* 0..100 amount to step, 255=not used */
uint16_t fade_time; /* 1..65535 seconds to transition, 0=not used */
uint16_t duration; /* 1..65535 minutes until relinquish, 0=not used */
BACNET_LIGHTING_OPERATION operation;
uint8_t level; /* 0..100 percent, 255=not used */
uint8_t ramp_rate; /* 0..100 percent-per-second, 255=not used */
uint8_t step_increment; /* 0..100 amount to step, 255=not used */
uint16_t fade_time; /* 1..65535 seconds to transition, 0=not used */
uint16_t duration; /* 1..65535 minutes until relinquish, 0=not used */
} BACNET_LIGHTING_COMMAND;
/* Here is our Priority Array. They are supposed to be Real, but */
@@ -76,51 +76,46 @@ static BACNET_LIGHTING_COMMAND Lighting_Command[MAX_LIGHTING_OUTPUTS];
/* we need to have our arrays initialized before answering any calls */
static bool Lighting_Output_Initialized = false;
int Lighting_Output_Encode_Lighting_Command(uint8_t * apdu,
int Lighting_Output_Encode_Lighting_Command(
uint8_t * apdu,
BACNET_LIGHTING_COMMAND * data)
{
int apdu_len = 0; /* total length of the apdu, return value */
int len = 0; /* total length of the apdu, return value */
int apdu_len = 0; /* total length of the apdu, return value */
int len = 0; /* total length of the apdu, return value */
float real_value = 0.0;
uint32_t unsigned_value = 0;
if (apdu) {
len = encode_context_enumerated(&apdu[apdu_len], 0,
data->operation);
len = encode_context_enumerated(&apdu[apdu_len], 0, data->operation);
apdu_len += len;
/* optional level? */
if (data->level != 255) {
real_value = data->level;
len = encode_context_real(&apdu[apdu_len], 1,
real_value);
len = encode_context_real(&apdu[apdu_len], 1, real_value);
apdu_len += len;
}
/* optional ramp-rate */
if (data->ramp_rate != 255) {
real_value = data->ramp_rate;
len = encode_context_real(&apdu[apdu_len], 2,
real_value);
len = encode_context_real(&apdu[apdu_len], 2, real_value);
apdu_len += len;
}
/* optional step increment */
if (data->step_increment != 255) {
real_value = data->step_increment;
len = encode_context_real(&apdu[apdu_len], 3,
real_value);
len = encode_context_real(&apdu[apdu_len], 3, real_value);
apdu_len += len;
}
/* optional fade time */
if (data->fade_time != 0) {
real_value = data->fade_time;
len = encode_context_real(&apdu[apdu_len], 4,
real_value);
len = encode_context_real(&apdu[apdu_len], 4, real_value);
apdu_len += len;
}
/* optional duration */
if (data->duration != 0) {
unsigned_value = data->duration;
len = encode_context_unsigned(&apdu[apdu_len], 5,
unsigned_value);
len = encode_context_unsigned(&apdu[apdu_len], 5, unsigned_value);
apdu_len += len;
}
}
@@ -128,18 +123,20 @@ int Lighting_Output_Encode_Lighting_Command(uint8_t * apdu,
return apdu_len;
}
int Lighting_Output_Decode_Lighting_Command(uint8_t * apdu,
unsigned apdu_max_len, BACNET_LIGHTING_COMMAND * data)
int Lighting_Output_Decode_Lighting_Command(
uint8_t * apdu,
unsigned apdu_max_len,
BACNET_LIGHTING_COMMAND * data)
{
int len = 0;
int apdu_len = 0;
int tag_len = 0;
uint8_t tag_number = 0;
uint32_t len_value_type = 0;
int type = 0; /* for decoding */
int property = 0; /* for decoding */
int type = 0; /* for decoding */
int property = 0; /* for decoding */
uint32_t unsigned_value = 0;
int i = 0; /* loop counter */
int i = 0; /* loop counter */
float real_value = 0.0;
/* check for value pointers */
@@ -150,7 +147,9 @@ int Lighting_Output_Decode_Lighting_Command(uint8_t * apdu,
len = decode_tag_number_and_value(&apdu[apdu_len],
&tag_number, &len_value_type);
apdu_len += len;
len = decode_enumerated(&apdu[apdu_len], len_value_type, &data->operation);
len =
decode_enumerated(&apdu[apdu_len], len_value_type,
&data->operation);
apdu_len += len;
/* Tag 1: level - OPTIONAL */
if (decode_is_context_tag(&apdu[apdu_len], 1)) {
@@ -171,7 +170,8 @@ int Lighting_Output_Decode_Lighting_Command(uint8_t * apdu,
}
void Lighting_Output_Init(void)
void Lighting_Output_Init(
void)
{
unsigned i, j;
@@ -197,7 +197,8 @@ void Lighting_Output_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Lighting_Output_Valid_Instance(uint32_t object_instance)
bool Lighting_Output_Valid_Instance(
uint32_t object_instance)
{
Lighting_Output_Init();
if (object_instance < MAX_LIGHTING_OUTPUTS)
@@ -208,7 +209,8 @@ bool Lighting_Output_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Lighting_Output_Count(void)
unsigned Lighting_Output_Count(
void)
{
Lighting_Output_Init();
return MAX_LIGHTING_OUTPUTS;
@@ -217,7 +219,8 @@ unsigned Lighting_Output_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Lighting_Output_Index_To_Instance(unsigned index)
uint32_t Lighting_Output_Index_To_Instance(
unsigned index)
{
Lighting_Output_Init();
return index;
@@ -226,7 +229,8 @@ uint32_t Lighting_Output_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Lighting_Output_Instance_To_Index(uint32_t object_instance)
unsigned Lighting_Output_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_LIGHTING_OUTPUTS;
@@ -237,7 +241,8 @@ unsigned Lighting_Output_Instance_To_Index(uint32_t object_instance)
return index;
}
float Lighting_Output_Present_Value(uint32_t object_instance)
float Lighting_Output_Present_Value(
uint32_t object_instance)
{
float value = LIGHTING_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -257,10 +262,11 @@ float Lighting_Output_Present_Value(uint32_t object_instance)
return value;
}
unsigned Lighting_Output_Present_Value_Priority(uint32_t object_instance)
unsigned Lighting_Output_Present_Value_Priority(
uint32_t object_instance)
{
unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */
unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */
unsigned priority = 0; /* return value */
Lighting_Output_Init();
@@ -277,8 +283,10 @@ unsigned Lighting_Output_Present_Value_Priority(uint32_t object_instance)
return priority;
}
bool Lighting_Output_Present_Value_Set(uint32_t object_instance,
float value, unsigned priority)
bool Lighting_Output_Present_Value_Set(
uint32_t object_instance,
float value,
unsigned priority)
{
unsigned index = 0;
bool status = false;
@@ -288,7 +296,7 @@ bool Lighting_Output_Present_Value_Set(uint32_t object_instance,
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value >= 0.0) && (value <= 100.0)) {
Lighting_Output_Level[index][priority-1] = (uint8_t) value;
Lighting_Output_Level[index][priority - 1] = (uint8_t) value;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
@@ -302,7 +310,8 @@ bool Lighting_Output_Present_Value_Set(uint32_t object_instance,
return status;
}
bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance,
bool Lighting_Output_Present_Value_Relinquish(
uint32_t object_instance,
int priority)
{
unsigned index = 0;
@@ -312,7 +321,7 @@ bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance,
if (index < MAX_LIGHTING_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ )) {
Lighting_Output_Level[index][priority-1] = LIGHTING_LEVEL_NULL;
Lighting_Output_Level[index][priority - 1] = LIGHTING_LEVEL_NULL;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
@@ -326,7 +335,8 @@ bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance,
return status;
}
float Lighting_Output_Progress_Value(uint32_t object_instance)
float Lighting_Output_Progress_Value(
uint32_t object_instance)
{
float value = LIGHTING_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -341,7 +351,8 @@ float Lighting_Output_Progress_Value(uint32_t object_instance)
}
/* note: the object name must be unique within this device */
char *Lighting_Output_Name(uint32_t object_instance)
char *Lighting_Output_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -354,14 +365,16 @@ char *Lighting_Output_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Lighting_Output_Encode_Property_APDU(uint8_t * apdu,
int Lighting_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
float real_value = (float) 1.414;
@@ -371,118 +384,129 @@ int Lighting_Output_Encode_Property_APDU(uint8_t * apdu,
Lighting_Output_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len = encode_application_object_id(&apdu[0], OBJECT_LIGHTING_OUTPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* object name must be unique in this device. */
/* FIXME: description could be writable and different than object name */
characterstring_init_ansi(&char_string,
Lighting_Output_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_LIGHTING_OUTPUT);
break;
case PROP_PRESENT_VALUE:
real_value = Lighting_Output_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_PROGRESS_VALUE:
real_value = Lighting_Output_Progress_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_LIGHTING_COMMAND:
apdu_len = Lighting_Output_Encode_Lighting_Command(&apdu[0],
&Lighting_Command[object_instance]);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Lighting_Output_Instance_To_Index(object_instance);
state = Lighting_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Lighting_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Lighting_Output_Level[object_index][i] == LIGHTING_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
real_value = Lighting_Output_Level[object_index][i];
len = encode_application_real(&apdu[apdu_len], real_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
object_index =
Lighting_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Lighting_Output_Level[object_index][array_index - 1] ==
LIGHTING_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value =
Lighting_Output_Level[object_index][array_index - 1];
apdu_len = encode_application_real(&apdu[0], real_value);
encode_application_object_id(&apdu[0], OBJECT_LIGHTING_OUTPUT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
/* object name must be unique in this device. */
/* FIXME: description could be writable and different than object name */
characterstring_init_ansi(&char_string,
Lighting_Output_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
OBJECT_LIGHTING_OUTPUT);
break;
case PROP_PRESENT_VALUE:
real_value = Lighting_Output_Present_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_PROGRESS_VALUE:
real_value = Lighting_Output_Progress_Value(object_instance);
apdu_len = encode_application_real(&apdu[0], real_value);
break;
case PROP_LIGHTING_COMMAND:
apdu_len = Lighting_Output_Encode_Lighting_Command(&apdu[0],
&Lighting_Command[object_instance]);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index = Lighting_Output_Instance_To_Index(object_instance);
state = Lighting_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0], UNITS_PERCENT);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Lighting_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Lighting_Output_Level[object_index][i] ==
LIGHTING_LEVEL_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
real_value = Lighting_Output_Level[object_index][i];
len =
encode_application_real(&apdu[apdu_len],
real_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
object_index =
Lighting_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Lighting_Output_Level[object_index][array_index - 1] ==
LIGHTING_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
real_value =
Lighting_Output_Level[object_index][array_index -
1];
apdu_len =
encode_application_real(&apdu[0], real_value);
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
}
}
}
break;
case PROP_RELINQUISH_DEFAULT:
real_value = LIGHTING_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
break;
case PROP_RELINQUISH_DEFAULT:
real_value = LIGHTING_RELINQUISH_DEFAULT;
apdu_len = encode_application_real(&apdu[0], real_value);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Lighting_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -502,68 +526,70 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Lighting_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
if (wp_data->priority == 6) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_REAL) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
status =
Lighting_Output_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = LIGHTING_LEVEL_NULL;
object_index =
Lighting_Output_Instance_To_Index(wp_data->
object_instance);
status =
Lighting_Output_Present_Value_Relinquish(wp_data->
object_instance, wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = LIGHTING_LEVEL_NULL;
object_index =
Lighting_Output_Instance_To_Index(wp_data->object_instance);
status =
Lighting_Output_Present_Value_Relinquish(wp_data->
object_instance, wp_data->priority);
if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
break;
case PROP_LIGHTING_COMMAND:
/* FIXME: error checking? */
Lighting_Output_Decode_Lighting_Command(wp_data->application_data,
wp_data->application_data_len,
&Lighting_Command[wp_data->object_instance]);
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Lighting_Output_Instance_To_Index(wp_data->
object_instance);
Lighting_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_LIGHTING_COMMAND:
/* FIXME: error checking? */
Lighting_Output_Decode_Lighting_Command(wp_data->application_data,
wp_data->application_data_len,
&Lighting_Command[wp_data->object_instance]);
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Lighting_Output_Instance_To_Index(wp_data->object_instance);
Lighting_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -575,7 +601,8 @@ bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testLightingOutput(Test * pTest)
void testLightingOutput(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -590,8 +617,7 @@ void testLightingOutput(Test * pTest)
len = Lighting_Output_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -604,7 +630,8 @@ void testLightingOutput(Test * pTest)
}
#ifdef TEST_LIGHTING_OUTPUT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -621,5 +648,5 @@ int main(void)
return 0;
}
#endif /* TEST_LIGHTING_INPUT */
#endif /* TEST */
#endif /* TEST_LIGHTING_INPUT */
#endif /* TEST */
+139 -131
View File
@@ -32,14 +32,13 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_LIFE_SAFETY_POINTS 7
/* Here are our stored levels.*/
static BACNET_LIFE_SAFETY_MODE
Life_Safety_Point_Mode[MAX_LIFE_SAFETY_POINTS];
static BACNET_LIFE_SAFETY_MODE Life_Safety_Point_Mode[MAX_LIFE_SAFETY_POINTS];
static BACNET_LIFE_SAFETY_STATE
Life_Safety_Point_State[MAX_LIFE_SAFETY_POINTS];
static BACNET_SILENCED_STATE
@@ -51,8 +50,7 @@ static BACNET_LIFE_SAFETY_OPERATION
static bool Life_Safety_Point_Out_Of_Service[MAX_LIFE_SAFETY_POINTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Life_Safety_Point_Properties_Required[] =
{
static const int Life_Safety_Point_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -68,14 +66,12 @@ static const int Life_Safety_Point_Properties_Required[] =
-1
};
static const int Life_Safety_Point_Properties_Optional[] =
{
static const int Life_Safety_Point_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Life_Safety_Point_Properties_Proprietary[] =
{
static const int Life_Safety_Point_Properties_Proprietary[] = {
-1
};
@@ -94,7 +90,8 @@ void Life_Safety_Point_Property_Lists(
return;
}
void Life_Safety_Point_Init(void)
void Life_Safety_Point_Init(
void)
{
static bool initialized = false;
unsigned i;
@@ -106,8 +103,7 @@ void Life_Safety_Point_Init(void)
for (i = 0; i < MAX_LIFE_SAFETY_POINTS; i++) {
Life_Safety_Point_Mode[i] = LIFE_SAFETY_MODE_DEFAULT;
Life_Safety_Point_State[i] = LIFE_SAFETY_STATE_QUIET;
Life_Safety_Point_Silenced_State[i] =
SILENCED_STATE_UNSILENCED;
Life_Safety_Point_Silenced_State[i] = SILENCED_STATE_UNSILENCED;
Life_Safety_Point_Operation[i] = LIFE_SAFETY_OPERATION_NONE;
}
}
@@ -118,7 +114,8 @@ void Life_Safety_Point_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Life_Safety_Point_Valid_Instance(uint32_t object_instance)
bool Life_Safety_Point_Valid_Instance(
uint32_t object_instance)
{
Life_Safety_Point_Init();
if (object_instance < MAX_LIFE_SAFETY_POINTS)
@@ -129,7 +126,8 @@ bool Life_Safety_Point_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Life_Safety_Point_Count(void)
unsigned Life_Safety_Point_Count(
void)
{
Life_Safety_Point_Init();
return MAX_LIFE_SAFETY_POINTS;
@@ -138,7 +136,8 @@ unsigned Life_Safety_Point_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Life_Safety_Point_Index_To_Instance(unsigned index)
uint32_t Life_Safety_Point_Index_To_Instance(
unsigned index)
{
Life_Safety_Point_Init();
return index;
@@ -147,7 +146,8 @@ uint32_t Life_Safety_Point_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Life_Safety_Point_Instance_To_Index(uint32_t object_instance)
unsigned Life_Safety_Point_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_LIFE_SAFETY_POINTS;
@@ -158,8 +158,8 @@ unsigned Life_Safety_Point_Instance_To_Index(uint32_t object_instance)
return index;
}
static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_Present_Value(uint32_t
object_instance)
static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_Present_Value(
uint32_t object_instance)
{
BACNET_LIFE_SAFETY_STATE present_value = LIFE_SAFETY_STATE_QUIET;
unsigned index = 0;
@@ -173,7 +173,8 @@ static BACNET_LIFE_SAFETY_STATE Life_Safety_Point_Present_Value(uint32_t
}
/* note: the object name must be unique within this device */
char *Life_Safety_Point_Name(uint32_t object_instance)
char *Life_Safety_Point_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -186,14 +187,16 @@ char *Life_Safety_Point_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Life_Safety_Point_Encode_Property_APDU(uint8_t * apdu,
int Life_Safety_Point_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
BACNET_LIFE_SAFETY_STATE present_value = LIFE_SAFETY_STATE_QUIET;
@@ -204,88 +207,93 @@ int Life_Safety_Point_Encode_Property_APDU(uint8_t * apdu,
bool state = false;
BACNET_RELIABILITY reliability = RELIABILITY_NO_FAULT_DETECTED;
(void) array_index; /* currently not used */
(void) array_index; /* currently not used */
Life_Safety_Point_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_LIFE_SAFETY_POINT,
object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Life_Safety_Point_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_LIFE_SAFETY_POINT);
break;
case PROP_PRESENT_VALUE:
present_value = Life_Safety_Point_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
state = Life_Safety_Point_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_RELIABILITY:
/* see standard for details about this property */
reliability = RELIABILITY_NO_FAULT_DETECTED;
apdu_len = encode_application_enumerated(&apdu[0], reliability);
break;
case PROP_MODE:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
mode = Life_Safety_Point_Mode[object_index];
apdu_len = encode_application_enumerated(&apdu[0], mode);
break;
case PROP_ACCEPTED_MODES:
for (mode = MIN_LIFE_SAFETY_MODE; mode < MAX_LIFE_SAFETY_MODE;
mode++) {
len = encode_application_enumerated(&apdu[apdu_len], mode);
apdu_len += len;
}
break;
case PROP_SILENCED:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
silenced_state = Life_Safety_Point_Silenced_State[object_index];
apdu_len = encode_application_enumerated(&apdu[0], silenced_state);
break;
case PROP_OPERATION_EXPECTED:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
operation = Life_Safety_Point_Operation[object_index];
apdu_len = encode_application_enumerated(&apdu[0], operation);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0],
OBJECT_LIFE_SAFETY_POINT, object_instance);
break;
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Life_Safety_Point_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
OBJECT_LIFE_SAFETY_POINT);
break;
case PROP_PRESENT_VALUE:
present_value = Life_Safety_Point_Present_Value(object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
state = Life_Safety_Point_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_RELIABILITY:
/* see standard for details about this property */
reliability = RELIABILITY_NO_FAULT_DETECTED;
apdu_len = encode_application_enumerated(&apdu[0], reliability);
break;
case PROP_MODE:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
mode = Life_Safety_Point_Mode[object_index];
apdu_len = encode_application_enumerated(&apdu[0], mode);
break;
case PROP_ACCEPTED_MODES:
for (mode = MIN_LIFE_SAFETY_MODE; mode < MAX_LIFE_SAFETY_MODE;
mode++) {
len = encode_application_enumerated(&apdu[apdu_len], mode);
apdu_len += len;
}
break;
case PROP_SILENCED:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
silenced_state = Life_Safety_Point_Silenced_State[object_index];
apdu_len = encode_application_enumerated(&apdu[0], silenced_state);
break;
case PROP_OPERATION_EXPECTED:
object_index =
Life_Safety_Point_Instance_To_Index(object_instance);
operation = Life_Safety_Point_Operation[object_index];
apdu_len = encode_application_enumerated(&apdu[0], operation);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Life_Safety_Point_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -304,42 +312,42 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_MODE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value.type.Enumerated >= MIN_LIFE_SAFETY_MODE) &&
(value.type.Enumerated <= MIN_LIFE_SAFETY_MODE)) {
case PROP_MODE:
if (value.tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value.type.Enumerated >= MIN_LIFE_SAFETY_MODE) &&
(value.type.Enumerated <= MIN_LIFE_SAFETY_MODE)) {
object_index =
Life_Safety_Point_Instance_To_Index(wp_data->
object_instance);
Life_Safety_Point_Mode[object_index] =
value.type.Enumerated;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Life_Safety_Point_Instance_To_Index(wp_data->
object_instance);
Life_Safety_Point_Mode[object_index] =
value.type.Enumerated;
Life_Safety_Point_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Life_Safety_Point_Instance_To_Index(wp_data->
object_instance);
Life_Safety_Point_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -351,7 +359,8 @@ bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testLifeSafetyPoint(Test * pTest)
void testLifeSafetyPoint(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -366,8 +375,7 @@ void testLifeSafetyPoint(Test * pTest)
len = Life_Safety_Point_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -380,7 +388,8 @@ void testLifeSafetyPoint(Test * pTest)
}
#ifdef TEST_LIFE_SAFETY_POINT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -397,6 +406,5 @@ int main(void)
return 0;
}
#endif /* TEST_LIFE_SAFETY_POINT */
#endif /* TEST */
#endif /* TEST_LIFE_SAFETY_POINT */
#endif /* TEST */
+202 -189
View File
@@ -32,7 +32,7 @@
#include "bacdcode.h"
#include "bacenum.h"
#include "bacapp.h"
#include "config.h" /* the custom stuff */
#include "config.h" /* the custom stuff */
#include "wp.h"
#define MAX_MULTISTATE_OUTPUTS 4
@@ -53,8 +53,7 @@ static uint8_t
static bool Multistate_Output_Out_Of_Service[MAX_MULTISTATE_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Multistate_Output_Properties_Required[] =
{
static const int Multistate_Output_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
@@ -68,14 +67,12 @@ static const int Multistate_Output_Properties_Required[] =
-1
};
static const int Multistate_Output_Properties_Optional[] =
{
static const int Multistate_Output_Properties_Optional[] = {
PROP_DESCRIPTION,
-1
};
static const int Multistate_Output_Properties_Proprietary[] =
{
static const int Multistate_Output_Properties_Proprietary[] = {
-1
};
@@ -94,7 +91,8 @@ void Multistate_Output_Property_Lists(
return;
}
void Multistate_Output_Init(void)
void Multistate_Output_Init(
void)
{
unsigned i, j;
static bool initialized = false;
@@ -116,7 +114,8 @@ void Multistate_Output_Init(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Multistate_Output_Valid_Instance(uint32_t object_instance)
bool Multistate_Output_Valid_Instance(
uint32_t object_instance)
{
if (object_instance < MAX_MULTISTATE_OUTPUTS)
return true;
@@ -126,7 +125,8 @@ bool Multistate_Output_Valid_Instance(uint32_t object_instance)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */
unsigned Multistate_Output_Count(void)
unsigned Multistate_Output_Count(
void)
{
return MAX_MULTISTATE_OUTPUTS;
}
@@ -134,7 +134,8 @@ unsigned Multistate_Output_Count(void)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */
/* that correlates to the correct index */
uint32_t Multistate_Output_Index_To_Instance(unsigned index)
uint32_t Multistate_Output_Index_To_Instance(
unsigned index)
{
return index;
}
@@ -142,7 +143,8 @@ uint32_t Multistate_Output_Index_To_Instance(unsigned index)
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */
/* that correlates to the correct instance number */
unsigned Multistate_Output_Instance_To_Index(uint32_t object_instance)
unsigned Multistate_Output_Instance_To_Index(
uint32_t object_instance)
{
unsigned index = MAX_MULTISTATE_OUTPUTS;
@@ -152,7 +154,8 @@ unsigned Multistate_Output_Instance_To_Index(uint32_t object_instance)
return index;
}
static uint32_t Multistate_Output_Present_Value(uint32_t object_instance)
static uint32_t Multistate_Output_Present_Value(
uint32_t object_instance)
{
uint32_t value = MULTISTATE_RELINQUISH_DEFAULT;
unsigned index = 0;
@@ -173,7 +176,8 @@ static uint32_t Multistate_Output_Present_Value(uint32_t object_instance)
}
/* note: the object name must be unique within this device */
char *Multistate_Output_Name(uint32_t object_instance)
char *Multistate_Output_Name(
uint32_t object_instance)
{
static char text_string[32] = ""; /* okay for single thread */
@@ -186,14 +190,16 @@ char *Multistate_Output_Name(uint32_t object_instance)
}
/* return apdu len, or -1 on error */
int Multistate_Output_Encode_Property_APDU(uint8_t * apdu,
int Multistate_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
int len = 0;
int apdu_len = 0; /* return value */
int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string;
BACNET_CHARACTER_STRING char_string;
uint32_t present_value = 0;
@@ -203,122 +209,128 @@ int Multistate_Output_Encode_Property_APDU(uint8_t * apdu,
Multistate_Output_Init();
switch (property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], OBJECT_MULTI_STATE_OUTPUT,
object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Multistate_Output_Name(object_instance));
apdu_len = encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], OBJECT_MULTI_STATE_OUTPUT);
break;
case PROP_PRESENT_VALUE:
present_value = Multistate_Output_Present_Value(object_instance);
apdu_len = encode_application_unsigned(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len = encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index =
Multistate_Output_Instance_To_Index(object_instance);
state = Multistate_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
encode_application_object_id(&apdu[0],
OBJECT_MULTI_STATE_OUTPUT, object_instance);
break;
/* note: Name and Description don't have to be the same.
You could make Description writable and different */
case PROP_OBJECT_NAME:
case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string,
Multistate_Output_Name(object_instance));
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0],
OBJECT_MULTI_STATE_OUTPUT);
break;
case PROP_PRESENT_VALUE:
present_value = Multistate_Output_Present_Value(object_instance);
apdu_len = encode_application_unsigned(&apdu[0], present_value);
break;
case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
/* note: see the details in the standard on how to use this */
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
object_index =
Multistate_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Multistate_Output_Level[object_index][i] ==
MULTISTATE_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value =
Multistate_Output_Level[object_index][i];
len =
encode_application_unsigned(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
object_index =
Multistate_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Multistate_Output_Level[object_index][array_index -
1] == MULTISTATE_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
present_value =
Multistate_Output_Level[object_index][array_index -
1];
apdu_len =
encode_application_unsigned(&apdu[0], present_value);
state = Multistate_Output_Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state);
break;
case PROP_PRIORITY_ARRAY:
/* Array element zero is the number of elements in the array */
if (array_index == 0)
apdu_len =
encode_application_unsigned(&apdu[0], BACNET_MAX_PRIORITY);
/* if no index was specified, then try to encode the entire list */
/* into one packet. */
else if (array_index == BACNET_ARRAY_ALL) {
object_index =
Multistate_Output_Instance_To_Index(object_instance);
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
/* FIXME: check if we have room before adding it to APDU */
if (Multistate_Output_Level[object_index][i] ==
MULTISTATE_NULL)
len = encode_application_null(&apdu[apdu_len]);
else {
present_value =
Multistate_Output_Level[object_index][i];
len =
encode_application_unsigned(&apdu[apdu_len],
present_value);
}
/* add it if we have room */
if ((apdu_len + len) < MAX_APDU)
apdu_len += len;
else {
*error_class = ERROR_CLASS_SERVICES;
*error_code = ERROR_CODE_NO_SPACE_FOR_OBJECT;
apdu_len = -1;
break;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
object_index =
Multistate_Output_Instance_To_Index(object_instance);
if (array_index <= BACNET_MAX_PRIORITY) {
if (Multistate_Output_Level[object_index][array_index -
1] == MULTISTATE_NULL)
apdu_len = encode_application_null(&apdu[0]);
else {
present_value =
Multistate_Output_Level[object_index][array_index -
1];
apdu_len =
encode_application_unsigned(&apdu[0],
present_value);
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
apdu_len = -1;
}
}
}
break;
case PROP_RELINQUISH_DEFAULT:
present_value = MULTISTATE_RELINQUISH_DEFAULT;
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_NUMBER_OF_STATES:
apdu_len = encode_application_unsigned(&apdu[apdu_len],
MULTISTATE_NUMBER_OF_STATES);
break;
break;
case PROP_RELINQUISH_DEFAULT:
present_value = MULTISTATE_RELINQUISH_DEFAULT;
apdu_len = encode_application_enumerated(&apdu[0], present_value);
break;
case PROP_NUMBER_OF_STATES:
apdu_len = encode_application_unsigned(&apdu[apdu_len],
MULTISTATE_NUMBER_OF_STATES);
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = -1;
break;
}
return apdu_len;
}
/* returns true if successful */
bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code)
bool Multistate_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false; /* return value */
unsigned int object_index = 0;
@@ -339,81 +351,81 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
/* FIXME: len < application_data_len: more data? */
/* FIXME: len == 0: unable to decode? */
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Unsigned_Int <= MULTISTATE_NUMBER_OF_STATES)) {
level = value.type.Unsigned_Int;
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
priority--;
Multistate_Output_Level[object_index][priority] =
(uint8_t) level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
case PROP_PRESENT_VALUE:
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
priority = wp_data->priority;
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) &&
(value.type.Unsigned_Int <= MULTISTATE_NUMBER_OF_STATES)) {
level = value.type.Unsigned_Int;
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
priority--;
Multistate_Output_Level[object_index][priority] =
(uint8_t) level;
/* Note: you could set the physical output here if we
are the highest priority.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any
object. */
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = MULTISTATE_NULL;
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Multistate_Output_Level[object_index][priority] =
(uint8_t) level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else if (value.tag == BACNET_APPLICATION_TAG_NULL) {
level = MULTISTATE_NULL;
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--;
Multistate_Output_Level[object_index][priority] =
(uint8_t) level;
/* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no
priorities are set.
However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
Multistate_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
} else {
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
case PROP_OUT_OF_SERVICE:
if (value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
object_index =
Multistate_Output_Instance_To_Index(wp_data->
object_instance);
Multistate_Output_Out_Of_Service[object_index] =
value.type.Boolean;
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_INVALID_DATA_TYPE;
}
break;
default:
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
*error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
}
return status;
@@ -425,7 +437,8 @@ bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
#include <string.h>
#include "ctest.h"
void testMultistateOutput(Test * pTest)
void testMultistateOutput(
Test * pTest)
{
uint8_t apdu[MAX_APDU] = { 0 };
int len = 0;
@@ -440,8 +453,7 @@ void testMultistateOutput(Test * pTest)
len = Multistate_Output_Encode_Property_APDU(&apdu[0],
instance,
PROP_OBJECT_IDENTIFIER,
BACNET_ARRAY_ALL, &error_class, &error_code);
PROP_OBJECT_IDENTIFIER, BACNET_ARRAY_ALL, &error_class, &error_code);
ct_test(pTest, len != 0);
len = decode_tag_number_and_value(&apdu[0], &tag_number, &len_value);
ct_test(pTest, tag_number == BACNET_APPLICATION_TAG_OBJECT_ID);
@@ -454,7 +466,8 @@ void testMultistateOutput(Test * pTest)
}
#ifdef TEST_MULTISTATE_OUTPUT
int main(void)
int main(
void)
{
Test *pTest;
bool rc;
@@ -471,5 +484,5 @@ int main(void)
return 0;
}
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
#endif /* TEST_BINARY_INPUT */
#endif /* TEST */
+37 -31
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -61,9 +61,11 @@ static bool End_Of_File_Detected = false;
static bool Error_Detected = false;
static uint8_t Current_Invoke_ID = 0;
static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS * src,
static void Atomic_Read_File_Error_Handler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
@@ -74,43 +76,47 @@ static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS * src,
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("\r\nBACnet Abort!\r\n");
printf("Abort Reason: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("Abort Reason: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("\r\nBACnet Reject!\r\n");
printf("Reject Reason: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("Reject Reason: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void AtomicReadFileAckHandler(uint8_t * service_request,
static void AtomicReadFileAckHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data)
{
int len = 0;
BACNET_ATOMIC_READ_FILE_DATA data;
FILE *pFile = NULL; /* stream pointer */
FILE *pFile = NULL; /* stream pointer */
size_t octets_written = 0;
(void) src; /* FIXME: validate the source address matches */
len = arf_ack_decode_service_request(service_request,
service_len, &data);
(void) src; /* FIXME: validate the source address matches */
len = arf_ack_decode_service_request(service_request, service_len, &data);
if (len > 0) {
/* validate the parameters before storing data */
if ((data.access == FILE_STREAM_ACCESS) &&
@@ -131,8 +137,7 @@ static void AtomicReadFileAckHandler(uint8_t * service_request,
Local_File_Name);
else
printf("\r%u bytes",
(data.type.stream.fileStartPosition +
octets_written));
(data.type.stream.fileStartPosition + octets_written));
fclose(pFile);
}
if (data.endOfFile) {
@@ -143,8 +148,10 @@ static void AtomicReadFileAckHandler(uint8_t * service_request,
}
}
static void LocalIAmHandler(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
static void LocalIAmHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
uint32_t device_id = 0;
@@ -164,15 +171,14 @@ static void LocalIAmHandler(uint8_t * service_request,
return;
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
LocalIAmHandler);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -190,7 +196,9 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -237,8 +245,7 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
@@ -253,8 +260,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (End_Of_File_Detected || Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
+28 -23
View File
@@ -29,7 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#define PRINT_ENABLED 1
@@ -66,51 +66,57 @@ static int32_t Target_Object_Index = BACNET_ARRAY_ALL;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS * src,
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Error: %s: %s\r\n",
bactext_error_class_name((int)error_class),
bactext_error_code_name((int)error_code));
bactext_error_class_name((int) error_class),
bactext_error_code_name((int) error_code));
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name((int)abort_reason));
bactext_abort_reason_name((int) abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name((int)reject_reason));
bactext_reject_reason_name((int) reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_bind);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -122,13 +128,14 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY,
MyErrorHandler);
apdu_set_error_handler(SERVICE_CONFIRMED_READ_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -186,8 +193,7 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
@@ -202,8 +208,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
+29 -29
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -56,15 +56,16 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* global variables used in this file */
static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE;
static BACNET_ADDRESS Target_Address;
static BACNET_REINITIALIZED_STATE Reinitialize_State =
BACNET_REINIT_COLDSTART;
static BACNET_REINITIALIZED_STATE Reinitialize_State = BACNET_REINIT_COLDSTART;
static char *Reinitialize_Password = NULL;
static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS * src,
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
@@ -75,30 +76,34 @@ static void MyErrorHandler(BACNET_ADDRESS * src,
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
void MyReinitializeDeviceSimpleAckHandler(BACNET_ADDRESS * src,
void MyReinitializeDeviceSimpleAckHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id)
{
(void) src;
@@ -106,15 +111,14 @@ void MyReinitializeDeviceSimpleAckHandler(BACNET_ADDRESS * src,
printf("ReinitializeDevice Acknowledged!\r\n");
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_bind);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -133,7 +137,9 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -188,19 +194,14 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
current_seconds = time(NULL);
/* returns 0 bytes on timeout */
pdu_len = datalink_receive(
&src,
&Rx_Buf[0],
MAX_MPDU,
timeout);
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */
if (pdu_len) {
@@ -208,8 +209,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
+11 -12
View File
@@ -55,13 +55,12 @@
/* buffers used for receiving */
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS,
handler_who_has);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -83,8 +82,7 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
handler_reinitialize_device);
apdu_set_unconfirmed_handler
(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
handler_timesync_utc);
(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
handler_timesync);
/* handle communication so we can shutup when asked */
@@ -93,12 +91,15 @@ static void Init_Service_Handlers(void)
handler_device_communication_control);
}
static void cleanup(void)
static void cleanup(
void)
{
datalink_cleanup();
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -147,9 +148,7 @@ int main(int argc, char *argv[])
"BACnet Stack Version %s\n"
"BACnet Device ID: %u\n"
"Max APDU: %d\n",
BACnet_Version,
Device_Object_Instance_Number(),
MAX_APDU);
BACnet_Version, Device_Object_Instance_Number(), MAX_APDU);
Init_Service_Handlers();
BIP_Debug = true;
if (!datalink_init(getenv("BACNET_IFACE")))
+19 -15
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "config.h"
@@ -56,35 +56,38 @@ static int32_t Target_Object_Instance_Max = BACNET_MAX_INSTANCE;
static bool Error_Detected = false;
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -94,8 +97,7 @@ static void Init_Service_Handlers(void)
handler_read_property);
/* handle the reply (request) coming in */
apdu_set_unconfirmed_handler
(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION,
handler_timesync_utc);
(SERVICE_UNCONFIRMED_UTC_TIME_SYNCHRONIZATION, handler_timesync_utc);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_TIME_SYNCHRONIZATION,
handler_timesync);
/* handle any errors coming back */
@@ -103,7 +105,9 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
+9 -9
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -49,15 +49,14 @@
#include "client.h"
#include "txbuf.h"
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_bind);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -67,7 +66,9 @@ static void Init_Service_Handlers(void)
handler_read_property);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
char *value_string = NULL;
bool status = false;
@@ -162,8 +163,7 @@ int main(int argc, char *argv[])
cov_data.listOfValues.priority = BACNET_NO_PRIORITY;
/* optional index */
if (argc > 10)
cov_data.listOfValues.propertyArrayIndex =
strtol(argv[10], NULL, 0);
cov_data.listOfValues.propertyArrayIndex = strtol(argv[10], NULL, 0);
else
cov_data.listOfValues.propertyArrayIndex = BACNET_ARRAY_ALL;
+20 -17
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -59,35 +59,38 @@ static char *Target_Object_Name = NULL;
static bool Error_Detected = false;
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -96,14 +99,15 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_HAVE,
handler_i_have);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_HAVE, handler_i_have);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -157,8 +161,7 @@ int main(int argc, char *argv[])
if (argc < 3)
Send_WhoHas_Name(-1, -1, Target_Object_Name);
else
Send_WhoHas_Object(-1, -1,
Target_Object_Type, Target_Object_Instance);
Send_WhoHas_Object(-1, -1, Target_Object_Type, Target_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
+21 -16
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -55,35 +55,38 @@ static int32_t Target_Object_Instance_Max = BACNET_MAX_INSTANCE;
static bool Error_Detected = false;
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("BACnet Abort: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("BACnet Reject: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -92,14 +95,14 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
/* handle the reply (request) coming back */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_add);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_add);
/* handle any errors coming back */
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
static void print_address_cache(void)
static void print_address_cache(
void)
{
int i, j;
BACNET_ADDRESS address;
@@ -120,7 +123,9 @@ static void print_address_cache(void)
}
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
+30 -25
View File
@@ -28,7 +28,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <errno.h>
#include "bactext.h"
#include "iam.h"
@@ -61,9 +61,11 @@ static bool End_Of_File_Detected = false;
static bool Error_Detected = false;
static uint8_t Current_Invoke_ID = 0;
static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS * src,
static void Atomic_Read_File_Error_Handler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
@@ -74,33 +76,38 @@ static void Atomic_Read_File_Error_Handler(BACNET_ADDRESS * src,
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("\r\nBACnet Abort!\r\n");
printf("Abort Reason: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("Abort Reason: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("\r\nBACnet Reject!\r\n");
printf("Reject Reason: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("Reject Reason: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
static void LocalIAmHandler(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src)
static void LocalIAmHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
{
int len = 0;
uint32_t device_id = 0;
@@ -120,15 +127,14 @@ static void LocalIAmHandler(uint8_t * service_request,
return;
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
LocalIAmHandler);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, LocalIAmHandler);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -143,7 +149,9 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -193,8 +201,7 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
@@ -209,8 +216,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (End_Of_File_Detected || Error_Detected) {
printf("\r\n");
break;
@@ -258,8 +264,7 @@ int main(int argc, char *argv[])
invoke_id =
Send_Atomic_Write_File_Stream
(Target_Device_Object_Instance,
Target_File_Object_Instance, fileStartPosition,
&fileData);
Target_File_Object_Instance, fileStartPosition, &fileData);
Current_Invoke_ID = invoke_id;
} else if (tsm_invoke_id_failed(invoke_id)) {
fprintf(stderr, "\rError: TSM Timeout!\r\n");
+30 -27
View File
@@ -28,10 +28,10 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#include <time.h> /* for time */
#include <string.h>
#include <errno.h>
#include <ctype.h> /* toupper */
#include <ctype.h> /* toupper */
#include "bactext.h"
#include "iam.h"
#include "arf.h"
@@ -71,9 +71,11 @@ static uint8_t Target_Object_Property_Priority = 0;
static BACNET_ADDRESS Target_Address;
static bool Error_Detected = false;
static void MyErrorHandler(BACNET_ADDRESS * src,
static void MyErrorHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code)
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code)
{
/* FIXME: verify src and invoke id */
(void) src;
@@ -84,32 +86,36 @@ static void MyErrorHandler(BACNET_ADDRESS * src,
Error_Detected = true;
}
void MyAbortHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server)
void MyAbortHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
(void) server;
printf("\r\nBACnet Abort!\r\n");
printf("Abort Reason: %s\r\n",
bactext_abort_reason_name(abort_reason));
printf("Abort Reason: %s\r\n", bactext_abort_reason_name(abort_reason));
Error_Detected = true;
}
void MyRejectHandler(BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason)
void MyRejectHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason)
{
/* FIXME: verify src and invoke id */
(void) src;
(void) invoke_id;
printf("\r\nBACnet Reject!\r\n");
printf("Reject Reason: %s\r\n",
bactext_reject_reason_name(reject_reason));
printf("Reject Reason: %s\r\n", bactext_reject_reason_name(reject_reason));
Error_Detected = true;
}
void MyWritePropertySimpleAckHandler(BACNET_ADDRESS * src,
void MyWritePropertySimpleAckHandler(
BACNET_ADDRESS * src,
uint8_t invoke_id)
{
(void) src;
@@ -117,15 +123,14 @@ void MyWritePropertySimpleAckHandler(BACNET_ADDRESS * src,
printf("\r\nWriteProperty Acknowledged!\r\n");
}
static void Init_Service_Handlers(void)
static void Init_Service_Handlers(
void)
{
/* we need to handle who-is
to support dynamic device binding to us */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
/* handle i-am to support binding to other devices */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM,
handler_i_am_bind);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_I_AM, handler_i_am_bind);
/* set the handler for all the services we don't implement
It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
@@ -137,13 +142,14 @@ static void Init_Service_Handlers(void)
apdu_set_confirmed_simple_ack_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
MyWritePropertySimpleAckHandler);
/* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
MyErrorHandler);
apdu_set_error_handler(SERVICE_CONFIRMED_WRITE_PROPERTY, MyErrorHandler);
apdu_set_abort_handler(MyAbortHandler);
apdu_set_reject_handler(MyRejectHandler);
}
int main(int argc, char *argv[])
int main(
int argc,
char *argv[])
{
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
@@ -234,8 +240,7 @@ int main(int argc, char *argv[])
"%s 123 1 0 85 4 100\r\n"
"You could also send a relinquish command:\r\n"
"%s 123 1 0 85 0 0\r\n",
filename_remove_path(argv[0]),
filename_remove_path(argv[0]));
filename_remove_path(argv[0]), filename_remove_path(argv[0]));
}
return 0;
}
@@ -317,8 +322,7 @@ int main(int argc, char *argv[])
timeout_seconds = (Device_APDU_Timeout() / 1000) *
Device_Number_Of_APDU_Retries();
/* try to bind with the device */
Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance);
/* loop forever */
for (;;) {
/* increment timer - exit if timed out */
@@ -333,8 +337,7 @@ int main(int argc, char *argv[])
}
/* at least one second has passed */
if (current_seconds != last_seconds)
tsm_timer_milliseconds(((current_seconds -
last_seconds) * 1000));
tsm_timer_milliseconds(((current_seconds - last_seconds) * 1000));
if (Error_Detected)
break;
/* wait until the device is bound, or timeout and quit */
+19 -9
View File
@@ -39,24 +39,34 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
int abort_encode_apdu(uint8_t * apdu,
uint8_t invoke_id, uint8_t abort_reason, bool server);
int abort_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
uint8_t abort_reason,
bool server);
int abort_decode_service_request(uint8_t * apdu,
unsigned apdu_len, uint8_t * invoke_id, uint8_t * abort_reason);
int abort_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
uint8_t * abort_reason);
#ifdef TEST
#include "ctest.h"
int abort_decode_apdu(uint8_t * apdu,
unsigned apdu_len, uint8_t * invoke_id, uint8_t * abort_reason,
int abort_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
uint8_t * abort_reason,
bool * server);
void testAbort(Test * pTest);
void testAbort(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+36 -19
View File
@@ -41,35 +41,52 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void address_init(void);
void address_init(
void);
void address_add(uint32_t device_id,
unsigned max_apdu, BACNET_ADDRESS * src);
void address_add(
uint32_t device_id,
unsigned max_apdu,
BACNET_ADDRESS * src);
void address_remove_device(uint32_t device_id);
void address_remove_device(
uint32_t device_id);
bool address_get_by_device(uint32_t device_id,
unsigned *max_apdu, BACNET_ADDRESS * src);
bool address_get_by_device(
uint32_t device_id,
unsigned *max_apdu,
BACNET_ADDRESS * src);
bool address_get_by_index(unsigned index,
uint32_t * device_id, unsigned *max_apdu, BACNET_ADDRESS * src);
bool address_get_device_id(BACNET_ADDRESS * src,
uint32_t *device_id);
bool address_get_by_index(
unsigned index,
uint32_t * device_id,
unsigned *max_apdu,
BACNET_ADDRESS * src);
unsigned address_count(void);
bool address_get_device_id(
BACNET_ADDRESS * src,
uint32_t * device_id);
bool address_match(BACNET_ADDRESS * dest, BACNET_ADDRESS * src);
unsigned address_count(
void);
bool address_bind_request(uint32_t device_id,
unsigned *max_apdu, BACNET_ADDRESS * src);
bool address_match(
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src);
void address_add_binding(uint32_t device_id,
unsigned max_apdu, BACNET_ADDRESS * src);
bool address_bind_request(
uint32_t device_id,
unsigned *max_apdu,
BACNET_ADDRESS * src);
void address_add_binding(
uint32_t device_id,
unsigned max_apdu,
BACNET_ADDRESS * src);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+16 -9
View File
@@ -31,28 +31,35 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Analog_Input_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Analog_Input_Valid_Instance(uint32_t object_instance);
unsigned Analog_Input_Count(void);
uint32_t Analog_Input_Index_To_Instance(unsigned index);
char *Analog_Input_Name(uint32_t object_instance);
bool Analog_Input_Valid_Instance(
uint32_t object_instance);
unsigned Analog_Input_Count(
void);
uint32_t Analog_Input_Index_To_Instance(
unsigned index);
char *Analog_Input_Name(
uint32_t object_instance);
int Analog_Input_Encode_Property_APDU(uint8_t * apdu,
int Analog_Input_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testAnalogInput(Test * pTest);
void testAnalogInput(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+30 -17
View File
@@ -33,40 +33,53 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Analog_Output_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Analog_Output_Valid_Instance(uint32_t object_instance);
unsigned Analog_Output_Count(void);
uint32_t Analog_Output_Index_To_Instance(unsigned index);
char *Analog_Output_Name(uint32_t object_instance);
float Analog_Output_Present_Value(uint32_t object_instance);
unsigned Analog_Output_Present_Value_Priority(uint32_t
object_instance);
bool Analog_Output_Present_Value_Set(uint32_t object_instance,
float value, unsigned priority);
bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
bool Analog_Output_Valid_Instance(
uint32_t object_instance);
unsigned Analog_Output_Count(
void);
uint32_t Analog_Output_Index_To_Instance(
unsigned index);
char *Analog_Output_Name(
uint32_t object_instance);
float Analog_Output_Present_Value(
uint32_t object_instance);
unsigned Analog_Output_Present_Value_Priority(
uint32_t object_instance);
bool Analog_Output_Present_Value_Set(
uint32_t object_instance,
float value,
unsigned priority);
bool Analog_Output_Present_Value_Relinquish(
uint32_t object_instance,
int priority);
int Analog_Output_Encode_Property_APDU(uint8_t * apdu,
int Analog_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool Analog_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testAnalogOutput(Test * pTest);
void testAnalogOutput(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+61 -32
View File
@@ -60,7 +60,7 @@ typedef struct _confirmed_service_ack_data {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* generic unconfirmed function handler */
/* Suitable to handle the following services: */
@@ -68,8 +68,11 @@ extern "C" {
/* Unconfirmed_Event_Notification, Unconfirmed_Private_Transfer, */
/* Unconfirmed_Text_Message, Time_Synchronization, Who_Has, */
/* UTC_Time_Synchronization */
typedef void (*unconfirmed_function) (uint8_t * service_request,
uint16_t len, BACNET_ADDRESS * src);
typedef void (
*unconfirmed_function) (
uint8_t * service_request,
uint16_t len,
BACNET_ADDRESS * src);
/* generic confirmed function handler */
/* Suitable to handle the following services: */
@@ -87,72 +90,98 @@ extern "C" {
/* Confirmed_Text_Message, Reinitialize_Device, */
/* VT_Open, VT_Close, VT_Data_Handler, */
/* Authenticate, Request_Key */
typedef void (*confirmed_function) (uint8_t * service_request,
typedef void (
*confirmed_function) (
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
/* generic confirmed simple ack function handler */
typedef void (*confirmed_simple_ack_function) (BACNET_ADDRESS * src,
typedef void (
*confirmed_simple_ack_function) (
BACNET_ADDRESS * src,
uint8_t invoke_id);
/* generic confirmed ack function handler */
typedef void (*confirmed_ack_function) (uint8_t * service_request,
typedef void (
*confirmed_ack_function) (
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data);
/* generic error reply function */
typedef void (*error_function) (BACNET_ADDRESS * src,
typedef void (
*error_function) (
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code);
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code);
/* generic abort reply function */
typedef void (*abort_function) (BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t abort_reason, bool server);
typedef void (
*abort_function) (
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t abort_reason,
bool server);
/* generic reject reply function */
typedef void (*reject_function) (BACNET_ADDRESS * src,
uint8_t invoke_id, uint8_t reject_reason);
typedef void (
*reject_function) (
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason);
void apdu_set_confirmed_ack_handler(BACNET_CONFIRMED_SERVICE
service_choice, confirmed_ack_function pFunction);
void apdu_set_confirmed_ack_handler(
BACNET_CONFIRMED_SERVICE service_choice,
confirmed_ack_function pFunction);
void apdu_set_confirmed_simple_ack_handler(BACNET_CONFIRMED_SERVICE
service_choice, confirmed_simple_ack_function pFunction);
void apdu_set_confirmed_simple_ack_handler(
BACNET_CONFIRMED_SERVICE service_choice,
confirmed_simple_ack_function pFunction);
/* configure reject for confirmed services that are not supported */
void apdu_set_unrecognized_service_handler_handler(confirmed_function
pFunction);
void apdu_set_unrecognized_service_handler_handler(
confirmed_function pFunction);
void apdu_set_confirmed_handler(BACNET_CONFIRMED_SERVICE
service_choice, confirmed_function pFunction);
void apdu_set_confirmed_handler(
BACNET_CONFIRMED_SERVICE service_choice,
confirmed_function pFunction);
void apdu_set_unconfirmed_handler(BACNET_UNCONFIRMED_SERVICE
service_choice, unconfirmed_function pFunction);
void apdu_set_unconfirmed_handler(
BACNET_UNCONFIRMED_SERVICE service_choice,
unconfirmed_function pFunction);
/* returns true if the service is supported by a handler */
bool apdu_service_supported(BACNET_SERVICES_SUPPORTED
service_supported);
bool apdu_service_supported(
BACNET_SERVICES_SUPPORTED service_supported);
void apdu_set_error_handler(BACNET_CONFIRMED_SERVICE service_choice,
void apdu_set_error_handler(
BACNET_CONFIRMED_SERVICE service_choice,
error_function pFunction);
void apdu_set_abort_handler(abort_function pFunction);
void apdu_set_abort_handler(
abort_function pFunction);
void apdu_set_reject_handler(reject_function pFunction);
void apdu_set_reject_handler(
reject_function pFunction);
uint16_t apdu_decode_confirmed_service_request(uint8_t * apdu, /* APDU data */
uint16_t apdu_decode_confirmed_service_request(
uint8_t * apdu, /* APDU data */
uint16_t apdu_len,
BACNET_CONFIRMED_SERVICE_DATA * service_data,
uint8_t * service_choice,
uint8_t ** service_request, uint16_t * service_request_len);
uint8_t ** service_request,
uint16_t * service_request_len);
void apdu_handler(BACNET_ADDRESS * src, /* source address */
uint8_t * apdu, /* APDU data */
void apdu_handler(
BACNET_ADDRESS * src, /* source address */
uint8_t * apdu, /* APDU data */
uint16_t pdu_len); /* for confirmed messages */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+18 -11
View File
@@ -46,30 +46,37 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
bool arcnet_valid(void);
void arcnet_cleanup(void);
bool arcnet_init(char *interface_name);
bool arcnet_valid(
void);
void arcnet_cleanup(
void);
bool arcnet_init(
char *interface_name);
/* function to send a packet out the 802.2 socket */
/* returns zero on success, non-zero on failure */
int arcnet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
int arcnet_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len); /* number of bytes of data */
/* receives an framed packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t arcnet_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t arcnet_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout); /* milliseconds to wait for a packet */
void arcnet_get_my_address(BACNET_ADDRESS * my_address);
void arcnet_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
void arcnet_get_my_address(
BACNET_ADDRESS * my_address);
void arcnet_get_broadcast_address(
BACNET_ADDRESS * dest); /* destination address */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+32 -18
View File
@@ -60,43 +60,57 @@ typedef struct BACnet_Atomic_Read_File_Data {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* Atomic Read File */
/* encode service */
int arf_encode_apdu(uint8_t * apdu,
uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data);
int arf_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_ATOMIC_READ_FILE_DATA * data);
/* decode the service request only */
int arf_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data);
int arf_decode_apdu(uint8_t * apdu,
int arf_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data);
BACNET_ATOMIC_READ_FILE_DATA * data);
int arf_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_ATOMIC_READ_FILE_DATA * data);
/* Atomic Read File Ack */
/* encode service */
int arf_ack_encode_apdu(uint8_t * apdu,
uint8_t invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data);
int arf_ack_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_ATOMIC_READ_FILE_DATA * data);
/* decode the service request only */
int arf_ack_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_ATOMIC_READ_FILE_DATA * data);
int arf_ack_decode_apdu(uint8_t * apdu,
int arf_ack_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id, BACNET_ATOMIC_READ_FILE_DATA * data);
BACNET_ATOMIC_READ_FILE_DATA * data);
int arf_ack_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_ATOMIC_READ_FILE_DATA * data);
#ifdef TEST
#include "ctest.h"
void test_AtomicReadFile(Test * pTest);
void test_AtomicReadFileAck(Test * pTest);
void test_AtomicReadFile(
Test * pTest);
void test_AtomicReadFileAck(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+20 -11
View File
@@ -33,31 +33,40 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Analog_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Analog_Value_Valid_Instance(uint32_t object_instance);
unsigned Analog_Value_Count(void);
uint32_t Analog_Value_Index_To_Instance(unsigned index);
char *Analog_Value_Name(uint32_t object_instance);
bool Analog_Value_Valid_Instance(
uint32_t object_instance);
unsigned Analog_Value_Count(
void);
uint32_t Analog_Value_Index_To_Instance(
unsigned index);
char *Analog_Value_Name(
uint32_t object_instance);
int Analog_Value_Encode_Property_APDU(uint8_t * apdu,
int Analog_Value_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool Analog_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testAnalog_Value(Test * pTest);
void testAnalog_Value(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+32 -18
View File
@@ -56,42 +56,56 @@ typedef struct BACnet_Atomic_Write_File_Data {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* Atomic Write File */
/* encode service */
int awf_encode_apdu(uint8_t * apdu,
uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data);
int awf_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_ATOMIC_WRITE_FILE_DATA * data);
/* decode the service request only */
int awf_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA * data);
int awf_decode_apdu(uint8_t * apdu,
int awf_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data);
BACNET_ATOMIC_WRITE_FILE_DATA * data);
int awf_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_ATOMIC_WRITE_FILE_DATA * data);
/* Atomic Write File Ack */
/* encode service */
int awf_ack_encode_apdu(uint8_t * apdu,
uint8_t invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data);
int awf_ack_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_ATOMIC_WRITE_FILE_DATA * data);
/* decode the service request only */
int awf_ack_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_ATOMIC_WRITE_FILE_DATA * data);
int awf_ack_decode_apdu(uint8_t * apdu,
int awf_ack_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id, BACNET_ATOMIC_WRITE_FILE_DATA * data);
BACNET_ATOMIC_WRITE_FILE_DATA * data);
int awf_ack_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_ATOMIC_WRITE_FILE_DATA * data);
#ifdef TEST
#include "ctest.h"
void test_AtomicWriteFile(Test * pTest);
void test_AtomicWriteFileAck(Test * pTest);
void test_AtomicWriteFile(
Test * pTest);
void test_AtomicWriteFileAck(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+8 -4
View File
@@ -41,12 +41,16 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void bacnet_address_copy(BACNET_ADDRESS * dest, BACNET_ADDRESS * src);
bool bacnet_address_same(BACNET_ADDRESS * dest, BACNET_ADDRESS * src);
void bacnet_address_copy(
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src);
bool bacnet_address_same(
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+49 -30
View File
@@ -45,7 +45,7 @@ struct BACnet_Application_Data_Value;
typedef struct BACnet_Application_Data_Value {
bool context_specific; /* true if context specific data */
uint8_t context_tag; /* only used for context specific data */
uint8_t tag; /* application tag data type */
uint8_t tag; /* application tag data type */
union {
/* NULL - not needed as it is encoded in the tag alone */
#if defined (BACAPP_BOOLEAN)
@@ -63,25 +63,25 @@ typedef struct BACnet_Application_Data_Value {
#if defined (BACAPP_DOUBLE)
double Double;
#endif
#if defined (BACAPP_OCTET_STRING)
#if defined (BACAPP_OCTET_STRING)
BACNET_OCTET_STRING Octet_String;
#endif
#if defined (BACAPP_CHARACTER_STRING)
#if defined (BACAPP_CHARACTER_STRING)
BACNET_CHARACTER_STRING Character_String;
#endif
#if defined (BACAPP_BIT_STRING)
#if defined (BACAPP_BIT_STRING)
BACNET_BIT_STRING Bit_String;
#endif
#if defined (BACAPP_ENUMERATED)
int Enumerated;
#endif
#if defined (BACAPP_DATE)
#if defined (BACAPP_DATE)
BACNET_DATE Date;
#endif
#if defined (BACAPP_TIME)
#if defined (BACAPP_TIME)
BACNET_TIME Time;
#endif
#if defined (BACAPP_OBJECT_ID)
#if defined (BACAPP_OBJECT_ID)
BACNET_OBJECT_ID Object_Id;
#endif
} type;
@@ -91,38 +91,51 @@ typedef struct BACnet_Application_Data_Value {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int bacapp_encode_data(uint8_t * apdu,
#endif /* __cplusplus */
int bacapp_encode_data(
uint8_t * apdu,
BACNET_APPLICATION_DATA_VALUE * value);
int bacapp_decode_application_data(uint8_t * apdu,
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value);
int bacapp_encode_application_data(uint8_t * apdu,
int bacapp_decode_application_data(
uint8_t * apdu,
int max_apdu_len,
BACNET_APPLICATION_DATA_VALUE * value);
int bacapp_decode_context_data(uint8_t * apdu,
int max_apdu_len, BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property);
int bacapp_encode_application_data(
uint8_t * apdu,
BACNET_APPLICATION_DATA_VALUE * value);
int bacapp_encode_context_data(uint8_t * apdu,
int bacapp_decode_context_data(
uint8_t * apdu,
int max_apdu_len,
BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property);
int bacapp_encode_context_data_value(uint8_t * apdu,
uint8_t context_tag_number, BACNET_APPLICATION_DATA_VALUE * value);
int bacapp_encode_context_data(
uint8_t * apdu,
BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property);
BACNET_APPLICATION_TAG bacapp_context_tag_type(BACNET_PROPERTY_ID
property, uint8_t tag_number);
int bacapp_encode_context_data_value(
uint8_t * apdu,
uint8_t context_tag_number,
BACNET_APPLICATION_DATA_VALUE * value);
bool bacapp_copy(BACNET_APPLICATION_DATA_VALUE * dest_value,
BACNET_APPLICATION_TAG bacapp_context_tag_type(
BACNET_PROPERTY_ID property,
uint8_t tag_number);
bool bacapp_copy(
BACNET_APPLICATION_DATA_VALUE * dest_value,
BACNET_APPLICATION_DATA_VALUE * src_value);
/* returns the length of data between an opening tag and a closing tag.
Expects that the first octet contain the opening tag.
Include a value property identifier for context specific data
such as the value received in a WriteProperty request */
int bacapp_data_len(uint8_t * apdu, int max_apdu_len,
int bacapp_data_len(
uint8_t * apdu,
int max_apdu_len,
BACNET_PROPERTY_ID property);
#if PRINT_ENABLED
@@ -134,9 +147,12 @@ extern "C" {
#endif
#ifdef BACAPP_PRINT_ENABLED
bool bacapp_parse_application_data(BACNET_APPLICATION_TAG tag_number,
const char *argv, BACNET_APPLICATION_DATA_VALUE * value);
bool bacapp_print_value(FILE * stream,
bool bacapp_parse_application_data(
BACNET_APPLICATION_TAG tag_number,
const char *argv,
BACNET_APPLICATION_DATA_VALUE * value);
bool bacapp_print_value(
FILE * stream,
BACNET_APPLICATION_DATA_VALUE * value,
BACNET_PROPERTY_ID property);
#else
@@ -147,14 +163,17 @@ extern "C" {
#ifdef TEST
#include "ctest.h"
#include "datetime.h"
bool bacapp_same_value(BACNET_APPLICATION_DATA_VALUE * value,
bool bacapp_same_value(
BACNET_APPLICATION_DATA_VALUE * value,
BACNET_APPLICATION_DATA_VALUE * test_value);
void testBACnetApplicationDataLength(Test * pTest);
void testBACnetApplicationData(Test * pTest);
void testBACnetApplicationDataLength(
Test * pTest);
void testBACnetApplicationData(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+174 -64
View File
@@ -45,133 +45,229 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* from clause 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_tag(uint8_t * apdu, uint8_t tag_number,
bool context_specific, uint32_t len_value_type);
int encode_tag(
uint8_t * apdu,
uint8_t tag_number,
bool context_specific,
uint32_t len_value_type);
/* from clause 20.2.1.3.2 Constructed Data */
/* returns the number of apdu bytes consumed */
int encode_opening_tag(uint8_t * apdu, uint8_t tag_number);
int encode_closing_tag(uint8_t * apdu, uint8_t tag_number);
int decode_tag_number(uint8_t * apdu, uint8_t * tag_number);
int decode_tag_number_and_value(uint8_t * apdu, uint8_t * tag_number,
int encode_opening_tag(
uint8_t * apdu,
uint8_t tag_number);
int encode_closing_tag(
uint8_t * apdu,
uint8_t tag_number);
int decode_tag_number(
uint8_t * apdu,
uint8_t * tag_number);
int decode_tag_number_and_value(
uint8_t * apdu,
uint8_t * tag_number,
uint32_t * value);
/* returns true if the tag is context specific */
bool decode_is_context_specific(uint8_t * apdu);
bool decode_is_context_specific(
uint8_t * apdu);
/* returns true if the tag is an opening tag and matches */
bool decode_is_opening_tag_number(uint8_t * apdu, uint8_t tag_number);
bool decode_is_opening_tag_number(
uint8_t * apdu,
uint8_t tag_number);
/* returns true if the tag is a closing tag and matches */
bool decode_is_closing_tag_number(uint8_t * apdu, uint8_t tag_number);
bool decode_is_closing_tag_number(
uint8_t * apdu,
uint8_t tag_number);
/* returns true if the tag is context specific and matches */
bool decode_is_context_tag(uint8_t * apdu, uint8_t tag_number);
bool decode_is_context_tag(
uint8_t * apdu,
uint8_t tag_number);
/* returns true if the tag is an opening tag */
bool decode_is_opening_tag(uint8_t * apdu);
bool decode_is_opening_tag(
uint8_t * apdu);
/* returns true if the tag is a closing tag */
bool decode_is_closing_tag(uint8_t * apdu);
bool decode_is_closing_tag(
uint8_t * apdu);
/* from clause 20.2.2 Encoding of a Null Value */
int encode_application_null(uint8_t * apdu);
int encode_context_null(uint8_t * apdu, int tag_number);
int encode_application_null(
uint8_t * apdu);
int encode_context_null(
uint8_t * apdu,
int tag_number);
/* from clause 20.2.3 Encoding of a Boolean Value */
int encode_application_boolean(uint8_t * apdu, bool boolean_value);
bool decode_boolean(uint32_t len_value);
int encode_context_boolean(uint8_t * apdu, int tag_number,
int encode_application_boolean(
uint8_t * apdu,
bool boolean_value);
bool decode_context_boolean(uint8_t * apdu);
bool decode_boolean(
uint32_t len_value);
int encode_context_boolean(
uint8_t * apdu,
int tag_number,
bool boolean_value);
bool decode_context_boolean(
uint8_t * apdu);
/* from clause 20.2.10 Encoding of a Bit String Value */
/* returns the number of apdu bytes consumed */
int decode_bitstring(uint8_t * apdu, uint32_t len_value,
int decode_bitstring(
uint8_t * apdu,
uint32_t len_value,
BACNET_BIT_STRING * bit_string);
/* returns the number of apdu bytes consumed */
int encode_bitstring(uint8_t * apdu, BACNET_BIT_STRING * bit_string);
int encode_application_bitstring(uint8_t * apdu,
int encode_bitstring(
uint8_t * apdu,
BACNET_BIT_STRING * bit_string);
int encode_context_bitstring(uint8_t * apdu, int tag_number,
int encode_application_bitstring(
uint8_t * apdu,
BACNET_BIT_STRING * bit_string);
int encode_context_bitstring(
uint8_t * apdu,
int tag_number,
BACNET_BIT_STRING * bit_string);
/* from clause 20.2.6 Encoding of a Real Number Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_application_real(uint8_t * apdu, float value);
int encode_context_real(uint8_t * apdu, int tag_number, float value);
int encode_application_real(
uint8_t * apdu,
float value);
int encode_context_real(
uint8_t * apdu,
int tag_number,
float value);
/* from clause 20.2.14 Encoding of an Object Identifier Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int decode_object_id(uint8_t * apdu, int *object_type,
int decode_object_id(
uint8_t * apdu,
int *object_type,
uint32_t * instance);
int encode_bacnet_object_id(uint8_t * apdu, int object_type,
int encode_bacnet_object_id(
uint8_t * apdu,
int object_type,
uint32_t instance);
int encode_context_object_id(uint8_t * apdu, int tag_number,
int object_type, uint32_t instance);
int encode_application_object_id(uint8_t * apdu, int object_type,
int encode_context_object_id(
uint8_t * apdu,
int tag_number,
int object_type,
uint32_t instance);
int encode_application_object_id(
uint8_t * apdu,
int object_type,
uint32_t instance);
/* from clause 20.2.8 Encoding of an Octet String Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_octet_string(uint8_t * apdu,
int encode_octet_string(
uint8_t * apdu,
BACNET_OCTET_STRING * octet_string);
int encode_application_octet_string(uint8_t * apdu,
int encode_application_octet_string(
uint8_t * apdu,
BACNET_OCTET_STRING * octet_string);
int encode_context_octet_string(uint8_t * apdu,
int tag_number, BACNET_OCTET_STRING * octet_string);
int decode_octet_string(uint8_t * apdu, uint32_t len_value,
int encode_context_octet_string(
uint8_t * apdu,
int tag_number,
BACNET_OCTET_STRING * octet_string);
int decode_octet_string(
uint8_t * apdu,
uint32_t len_value,
BACNET_OCTET_STRING * octet_string);
/* from clause 20.2.9 Encoding of a Character String Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_bacnet_character_string(uint8_t * apdu,
int encode_bacnet_character_string(
uint8_t * apdu,
BACNET_CHARACTER_STRING * char_string);
int encode_application_character_string(uint8_t * apdu,
int encode_application_character_string(
uint8_t * apdu,
BACNET_CHARACTER_STRING * char_string);
int encode_context_character_string(uint8_t * apdu, int tag_number,
int encode_context_character_string(
uint8_t * apdu,
int tag_number,
BACNET_CHARACTER_STRING * char_string);
int decode_character_string(uint8_t * apdu, uint32_t len_value,
int decode_character_string(
uint8_t * apdu,
uint32_t len_value,
BACNET_CHARACTER_STRING * char_string);
/* from clause 20.2.4 Encoding of an Unsigned Integer Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_bacnet_unsigned(uint8_t * apdu, uint32_t value);
int encode_context_unsigned(uint8_t * apdu, int tag_number,
int encode_bacnet_unsigned(
uint8_t * apdu,
uint32_t value);
int encode_application_unsigned(uint8_t * apdu, uint32_t value);
int decode_unsigned(uint8_t * apdu, uint32_t len_value,
int encode_context_unsigned(
uint8_t * apdu,
int tag_number,
uint32_t value);
int encode_application_unsigned(
uint8_t * apdu,
uint32_t value);
int decode_unsigned(
uint8_t * apdu,
uint32_t len_value,
uint32_t * value);
/* 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 */
int encode_bacnet_signed(uint8_t * apdu, int32_t value);
int encode_application_signed(uint8_t * apdu, int32_t value);
int encode_context_signed(uint8_t * apdu, int tag_number,
int encode_bacnet_signed(
uint8_t * apdu,
int32_t value);
int decode_signed(uint8_t * apdu, uint32_t len_value, int32_t * value);
int encode_application_signed(
uint8_t * apdu,
int32_t value);
int encode_context_signed(
uint8_t * apdu,
int tag_number,
int32_t value);
int decode_signed(
uint8_t * apdu,
uint32_t len_value,
int32_t * value);
/* from clause 20.2.11 Encoding of an Enumerated Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int decode_enumerated(uint8_t * apdu, uint32_t len_value, int *value);
int encode_bacnet_enumerated(uint8_t * apdu, int value);
int encode_application_enumerated(uint8_t * apdu, int value);
int encode_context_enumerated(uint8_t * apdu, int tag_number,
int decode_enumerated(
uint8_t * apdu,
uint32_t len_value,
int *value);
int encode_bacnet_enumerated(
uint8_t * apdu,
int value);
int encode_application_enumerated(
uint8_t * apdu,
int value);
int encode_context_enumerated(
uint8_t * apdu,
int tag_number,
int value);
/* from clause 20.2.13 Encoding of a Time Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime);
int encode_application_time(uint8_t * apdu, BACNET_TIME * btime);
int decode_bacnet_time(uint8_t * apdu, BACNET_TIME * btime);
int encode_context_time(uint8_t * apdu, int tag_number,
int encode_bacnet_time(
uint8_t * apdu,
BACNET_TIME * btime);
int encode_application_time(
uint8_t * apdu,
BACNET_TIME * btime);
int decode_bacnet_time(
uint8_t * apdu,
BACNET_TIME * btime);
int encode_context_time(
uint8_t * apdu,
int tag_number,
BACNET_TIME * btime);
/* BACnet Date */
@@ -183,24 +279,38 @@ extern "C" {
/* from clause 20.2.12 Encoding of a Date Value */
/* and 20.2.1 General Rules for Encoding BACnet Tags */
/* returns the number of apdu bytes consumed */
int encode_bacnet_date(uint8_t * apdu, BACNET_DATE * bdate);
int encode_application_date(uint8_t * apdu, BACNET_DATE * bdate);
int encode_context_date(uint8_t * apdu, int tag_number,
int encode_bacnet_date(
uint8_t * apdu,
BACNET_DATE * bdate);
int encode_application_date(
uint8_t * apdu,
BACNET_DATE * bdate);
int encode_context_date(
uint8_t * apdu,
int tag_number,
BACNET_DATE * bdate);
int decode_date(
uint8_t * apdu,
BACNET_DATE * bdate);
int decode_date(uint8_t * apdu, BACNET_DATE * bdate);
/* from clause 20.1.2.4 max-segments-accepted */
/* and clause 20.1.2.5 max-APDU-length-accepted */
/* returns the encoded octet */
uint8_t encode_max_segs_max_apdu(int max_segs, int max_apdu);
int decode_max_segs(uint8_t octet);
int decode_max_apdu(uint8_t octet);
uint8_t encode_max_segs_max_apdu(
int max_segs,
int max_apdu);
int decode_max_segs(
uint8_t octet);
int decode_max_apdu(
uint8_t octet);
/* returns the number of apdu bytes consumed */
int encode_simple_ack(uint8_t * apdu, uint8_t invoke_id,
int encode_simple_ack(
uint8_t * apdu,
uint8_t invoke_id,
uint8_t service_choice);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+2 -2
View File
@@ -71,10 +71,10 @@ struct BACnet_Device_Address {
/* DNET,DLEN,DADR or SNET,SLEN,SADR */
/* the following are used if the device is behind a router */
/* net = 0 indicates local */
uint16_t net; /* BACnet network number */
uint16_t net; /* BACnet network number */
/* LEN = 0 denotes broadcast MAC ADR and ADR field is absent */
/* LEN > 0 specifies length of ADR field */
uint8_t len; /* length of MAC address */
uint8_t len; /* length of MAC address */
uint8_t adr[MAX_MAC_LEN]; /* hwaddr (MAC) address */
};
typedef struct BACnet_Device_Address BACNET_ADDRESS;
+51 -51
View File
@@ -279,12 +279,12 @@ typedef enum {
PROP_RAMP_RATE = 241,
PROP_STEP_INCREMENT = 242,
PROP_SYSTEM_FAILURE_VALUE = 243
/* The special property identifiers all, optional, and required */
/* are reserved for use in the ReadPropertyConditional and */
/* ReadPropertyMultiple services or services not defined in this standard. */
/* Enumerated values 0-511 are reserved for definition by ASHRAE. */
/* Enumerated values 512-4194303 may be used by others subject to the */
/* procedures and constraints described in Clause 23. */
/* The special property identifiers all, optional, and required */
/* are reserved for use in the ReadPropertyConditional and */
/* ReadPropertyMultiple services or services not defined in this standard. */
/* Enumerated values 0-511 are reserved for definition by ASHRAE. */
/* Enumerated values 512-4194303 may be used by others subject to the */
/* procedures and constraints described in Clause 23. */
} BACNET_PROPERTY_ID;
#define MAX_BACNET_PROPERTY_ID 4194303
@@ -294,11 +294,11 @@ typedef enum {
} BACNET_ACTION;
typedef enum {
MIN_BINARY_PV = 0, /* for validating incoming values */
MIN_BINARY_PV = 0, /* for validating incoming values */
BINARY_INACTIVE = 0,
BINARY_ACTIVE = 1,
MAX_BINARY_PV = 1, /* for validating incoming values */
BINARY_NULL = 2 /* our homemade way of storing this info */
MAX_BINARY_PV = 1, /* for validating incoming values */
BINARY_NULL = 2 /* our homemade way of storing this info */
} BACNET_BINARY_PV;
typedef enum {
@@ -538,10 +538,10 @@ typedef enum {
UNITS_SQUARE_METERS_PER_NEWTON = 185,
UNITS_WATTS_PER_METER_PER_DEGREE_KELVIN = 189,
UNITS_WATTS_PER_SQUARE_METER_DEGREE_KELVIN = 141
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* 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 189. */
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* 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 189. */
} BACNET_ENGINEERING_UNITS;
typedef enum {
@@ -573,9 +573,9 @@ typedef enum {
PROGRAM_ERROR_INTERNAL = 2,
PROGRAM_ERROR_PROGRAM = 3,
PROGRAM_ERROR_OTHER = 4
/* 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. */
/* 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. */
} BACNET_PROGRAM_ERROR;
typedef enum {
@@ -592,9 +592,9 @@ typedef enum {
RELIABILITY_CONFIGURATION_ERROR = 10,
RELIABILITY_COMMUNICATION_FAILURE = 12,
RELIABILITY_TRIPPED = 13
/* 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. */
/* 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. */
} BACNET_RELIABILITY;
typedef enum {
@@ -610,13 +610,13 @@ typedef enum {
EVENT_EXTENDED = 9,
EVENT_BUFFER_READY = 10,
EVENT_UNSIGNED_RANGE = 11
/* 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. */
/* It is expected that these enumerated values will correspond to */
/* the use of the complex-event-type CHOICE [6] of the */
/* BACnetNotificationParameters production. */
/* The last enumeration used in this version is 11. */
/* 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. */
/* It is expected that these enumerated values will correspond to */
/* the use of the complex-event-type CHOICE [6] of the */
/* BACnetNotificationParameters production. */
/* The last enumeration used in this version is 11. */
} BACNET_EVENT_TYPE;
typedef enum {
@@ -643,9 +643,9 @@ typedef enum {
LIFE_SAFETY_MODE_AUTOMATIC_RELEASE_DISABLED = 13,
LIFE_SAFETY_MODE_DEFAULT = 14,
MAX_LIFE_SAFETY_MODE = 14
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
} BACNET_LIFE_SAFETY_MODE;
typedef enum {
@@ -691,9 +691,9 @@ typedef enum {
LIFE_SAFETY_STATE_SUPERVISORY = 22,
LIFE_SAFETY_STATE_TEST_SUPERVISORY = 23,
MAX_LIFE_SAFETY_STATE = 0
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
/* Enumerated values 0-255 are reserved for definition by ASHRAE. */
/* Enumerated values 256-65535 may be used by others subject to */
/* procedures and constraints described in Clause 23. */
} BACNET_LIFE_SAFETY_STATE;
typedef enum {
@@ -1035,8 +1035,8 @@ typedef enum {
NETWORK_MESSAGE_INITIALIZE_ROUTING_TABLE_ACK = 7,
NETWORK_MESSAGE_ESTABLISH_CONNECTION_TO_NETWORK = 8,
NETWORK_MESSAGE_DISCONNECT_CONNECTION_TO_NETWORK = 9,
/* X'0A' to X'7F': Reserved for use by ASHRAE, */
/* X'80' to X'FF': Available for vendor proprietary messages */
/* X'0A' to X'7F': Reserved for use by ASHRAE, */
/* X'80' to X'FF': Available for vendor proprietary messages */
NETWORK_MESSAGE_INVALID = 0x100
} BACNET_NETWORK_MESSAGE_TYPE;
@@ -1221,21 +1221,21 @@ typedef enum BACnetShedState {
} BACNET_SHED_STATE;
typedef enum BACnetLightingOperation {
BACNET_LIGHTS_STOP = 0,
BACNET_LIGHTS_FADE_TO = 1,
BACNET_LIGHTS_FADE_TO_OVER = 2,
BACNET_LIGHTS_RAMP_TO = 3,
BACNET_LIGHTS_RAMP_TO_AT_RATE = 4,
BACNET_LIGHTS_RAMP_UP = 5,
BACNET_LIGHTS_RAMP_UP_AT_RATE = 6,
BACNET_LIGHTS_RAMP_DOWN = 7,
BACNET_LIGHTS_RAMP_DOWN_AT_RATE = 8,
BACNET_LIGHTS_STEP_UP = 9,
BACNET_LIGHTS_STEP_DOWN = 10,
BACNET_LIGHTS_STEP_UP_BY = 11,
BACNET_LIGHTS_STEP_DOWN_BY = 12,
BACNET_LIGHTS_GOTO_LEVEL = 13,
BACNET_LIGHTS_RELINQUISH = 14
BACNET_LIGHTS_STOP = 0,
BACNET_LIGHTS_FADE_TO = 1,
BACNET_LIGHTS_FADE_TO_OVER = 2,
BACNET_LIGHTS_RAMP_TO = 3,
BACNET_LIGHTS_RAMP_TO_AT_RATE = 4,
BACNET_LIGHTS_RAMP_UP = 5,
BACNET_LIGHTS_RAMP_UP_AT_RATE = 6,
BACNET_LIGHTS_RAMP_DOWN = 7,
BACNET_LIGHTS_RAMP_DOWN_AT_RATE = 8,
BACNET_LIGHTS_STEP_UP = 9,
BACNET_LIGHTS_STEP_DOWN = 10,
BACNET_LIGHTS_STEP_UP_BY = 11,
BACNET_LIGHTS_STEP_DOWN_BY = 12,
BACNET_LIGHTS_GOTO_LEVEL = 13,
BACNET_LIGHTS_RELINQUISH = 14
} BACNET_LIGHTING_OPERATION;
/* NOTE: BACNET_DAYS_OF_WEEK is different than BACNET_WEEKDAY */
@@ -1247,7 +1247,7 @@ typedef enum BACnetDaysOfWeek {
BACNET_DAYS_OF_WEEK_THURSDAY = 3,
BACNET_DAYS_OF_WEEK_FRIDAY = 4,
BACNET_DAYS_OF_WEEK_SATURDAY = 5,
BACNET_DAYS_OF_WEEK_SUNDAY = 6
BACNET_DAYS_OF_WEEK_SUNDAY = 6
} BACNET_DAYS_OF_WEEK;
#endif /* end of BACENUM_H */
#endif /* end of BACENUM_H */
+20 -11
View File
@@ -40,35 +40,44 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
int bacerror_encode_apdu(uint8_t * apdu,
int bacerror_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_CONFIRMED_SERVICE service,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CODE error_code);
BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code);
int bacerror_decode_service_request(uint8_t * apdu,
int bacerror_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_CONFIRMED_SERVICE * service,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
int bacerror_decode_error_class_and_code(uint8_t * apdu,
int bacerror_decode_error_class_and_code(
uint8_t * apdu,
unsigned apdu_len,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
int bacerror_decode_apdu(uint8_t * apdu,
int bacerror_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_CONFIRMED_SERVICE * service,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
void testBACError(Test * pTest);
void testBACError(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+26 -14
View File
@@ -44,40 +44,52 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void BACfile_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
char *bacfile_name(uint32_t instance);
bool bacfile_valid_instance(uint32_t object_instance);
uint32_t bacfile_count(void);
uint32_t bacfile_index_to_instance(unsigned find_index);
uint32_t bacfile_instance(char *filename);
char *bacfile_name(
uint32_t instance);
bool bacfile_valid_instance(
uint32_t object_instance);
uint32_t bacfile_count(
void);
uint32_t bacfile_index_to_instance(
unsigned find_index);
uint32_t bacfile_instance(
char *filename);
/* this is one way to match up the invoke ID with */
/* the file ID from the AtomicReadFile request. */
/* Another way would be to store the */
/* invokeID and file instance in a list or table */
/* when the request was sent */
uint32_t bacfile_instance_from_tsm(uint8_t invokeID);
uint32_t bacfile_instance_from_tsm(
uint8_t invokeID);
/* handler ACK helper */
bool bacfile_read_data(BACNET_ATOMIC_READ_FILE_DATA * data);
bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA * data);
bool bacfile_read_data(
BACNET_ATOMIC_READ_FILE_DATA * data);
bool bacfile_write_stream_data(
BACNET_ATOMIC_WRITE_FILE_DATA * data);
/* handling for read property service */
int bacfile_encode_property_apdu(uint8_t * apdu,
int bacfile_encode_property_apdu(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
/* handling for write property service */
bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool bacfile_write_property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+45 -19
View File
@@ -40,29 +40,55 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* unsigned value encoding and decoding */
int encode_unsigned16(uint8_t * apdu, uint16_t value);
int decode_unsigned16(uint8_t * apdu, uint16_t * value);
int encode_unsigned24(uint8_t * apdu, uint32_t value);
int decode_unsigned24(uint8_t * apdu, uint32_t * value);
int encode_unsigned32(uint8_t * apdu, uint32_t value);
int decode_unsigned32(uint8_t * apdu, uint32_t * value);
int encode_unsigned16(
uint8_t * apdu,
uint16_t value);
int decode_unsigned16(
uint8_t * apdu,
uint16_t * value);
int encode_unsigned24(
uint8_t * apdu,
uint32_t value);
int decode_unsigned24(
uint8_t * apdu,
uint32_t * value);
int encode_unsigned32(
uint8_t * apdu,
uint32_t value);
int decode_unsigned32(
uint8_t * apdu,
uint32_t * value);
/* signed value encoding and decoding */
int encode_signed8(uint8_t * apdu, int8_t value);
int decode_signed8(uint8_t * apdu, int32_t * value);
int encode_signed16(uint8_t * apdu, int16_t value);
int decode_signed16(uint8_t * apdu, int32_t * value);
int encode_signed24(uint8_t * apdu, int32_t value);
int decode_signed24(uint8_t * apdu, int32_t * value);
int encode_signed32(uint8_t * apdu, int32_t value);
int decode_signed32(uint8_t * apdu, int32_t * value);
int encode_signed8(
uint8_t * apdu,
int8_t value);
int decode_signed8(
uint8_t * apdu,
int32_t * value);
int encode_signed16(
uint8_t * apdu,
int16_t value);
int decode_signed16(
uint8_t * apdu,
int32_t * value);
int encode_signed24(
uint8_t * apdu,
int32_t value);
int decode_signed24(
uint8_t * apdu,
int32_t * value);
int encode_signed32(
uint8_t * apdu,
int32_t value);
int decode_signed32(
uint8_t * apdu,
int32_t * value);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+11 -7
View File
@@ -39,20 +39,24 @@
#include "bacenum.h"
typedef struct {
signed prop_id; /* index number that matches the text */
signed tag_id; /* text pair - use NULL to end the list */
signed prop_id; /* index number that matches the text */
signed tag_id; /* text pair - use NULL to end the list */
} PROP_TAG_DATA;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
signed bacprop_tag_by_index_default(PROP_TAG_DATA * data_list,
signed index, signed default_ret);
signed bacprop_tag_by_index_default(
PROP_TAG_DATA * data_list,
signed index,
signed default_ret);
signed bacprop_property_tag(BACNET_OBJECT_TYPE type, signed prop);
signed bacprop_property_tag(
BACNET_OBJECT_TYPE type,
signed prop);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+11 -8
View File
@@ -40,20 +40,23 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
int decode_real(uint8_t * apdu, float *real_value);
int encode_bacnet_real(float value, uint8_t * apdu);
int decode_real(
uint8_t * apdu,
float *real_value);
int encode_bacnet_real(
float value,
uint8_t * apdu);
#ifdef TEST
#include "ctest.h"
void testBACreal(Test * pTest);
void testBACreal(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+73 -37
View File
@@ -65,23 +65,36 @@ typedef struct BACnet_Octet_String {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void bitstring_init(BACNET_BIT_STRING * bit_string);
void bitstring_set_bit(BACNET_BIT_STRING * bit_string, uint8_t bit_number,
void bitstring_init(
BACNET_BIT_STRING * bit_string);
void bitstring_set_bit(
BACNET_BIT_STRING * bit_string,
uint8_t bit_number,
bool value);
bool bitstring_bit(BACNET_BIT_STRING * bit_string, uint8_t bit_number);
uint8_t bitstring_bits_used(BACNET_BIT_STRING * bit_string);
bool bitstring_bit(
BACNET_BIT_STRING * bit_string,
uint8_t bit_number);
uint8_t bitstring_bits_used(
BACNET_BIT_STRING * bit_string);
/* returns the number of bytes that a bit string is using */
int bitstring_bytes_used(BACNET_BIT_STRING * bit_string);
uint8_t bitstring_bits_capacity(BACNET_BIT_STRING * bit_string);
int bitstring_bytes_used(
BACNET_BIT_STRING * bit_string);
uint8_t bitstring_bits_capacity(
BACNET_BIT_STRING * bit_string);
/* used for encoding and decoding from the APDU */
uint8_t bitstring_octet(BACNET_BIT_STRING * bit_string,
uint8_t bitstring_octet(
BACNET_BIT_STRING * bit_string,
uint8_t octet_index);
bool bitstring_set_octet(BACNET_BIT_STRING * bit_string, uint8_t index,
bool bitstring_set_octet(
BACNET_BIT_STRING * bit_string,
uint8_t index,
uint8_t octet);
bool bitstring_set_bits_used(BACNET_BIT_STRING * bit_string,
uint8_t bytes_used, uint8_t unused_bits);
bool bitstring_set_bits_used(
BACNET_BIT_STRING * bit_string,
uint8_t bytes_used,
uint8_t unused_bits);
bool bitstring_copy(
BACNET_BIT_STRING * dest,
BACNET_BIT_STRING * src);
@@ -89,57 +102,80 @@ extern "C" {
/* returns false if the string exceeds capacity
initialize by using length=0 */
bool characterstring_init(BACNET_CHARACTER_STRING * char_string,
uint8_t encoding, char *value, size_t length);
bool characterstring_init(
BACNET_CHARACTER_STRING * char_string,
uint8_t encoding,
char *value,
size_t length);
/* used for ANSI C-Strings */
bool characterstring_init_ansi(BACNET_CHARACTER_STRING * char_string,
bool characterstring_init_ansi(
BACNET_CHARACTER_STRING * char_string,
char *value);
bool characterstring_copy(BACNET_CHARACTER_STRING * dest,
bool characterstring_copy(
BACNET_CHARACTER_STRING * dest,
BACNET_CHARACTER_STRING * src);
/* returns true if the strings are the same length, encoding, value */
bool characterstring_same(BACNET_CHARACTER_STRING * dest,
bool characterstring_same(
BACNET_CHARACTER_STRING * dest,
BACNET_CHARACTER_STRING * src);
bool characterstring_ansi_same(BACNET_CHARACTER_STRING * dest,
bool characterstring_ansi_same(
BACNET_CHARACTER_STRING * dest,
const char *src);
/* returns false if the string exceeds capacity */
bool characterstring_append(BACNET_CHARACTER_STRING * char_string,
char *value, size_t length);
bool characterstring_append(
BACNET_CHARACTER_STRING * char_string,
char *value,
size_t length);
/* This function sets a new length without changing the value.
If length exceeds capacity, no modification happens and
function returns false. */
bool characterstring_truncate(BACNET_CHARACTER_STRING * char_string,
bool characterstring_truncate(
BACNET_CHARACTER_STRING * char_string,
size_t length);
bool characterstring_set_encoding(BACNET_CHARACTER_STRING *
char_string, uint8_t encoding);
bool characterstring_set_encoding(
BACNET_CHARACTER_STRING * char_string,
uint8_t encoding);
/* Returns the value */
char *characterstring_value(BACNET_CHARACTER_STRING * char_string);
char *characterstring_value(
BACNET_CHARACTER_STRING * char_string);
/* returns the length */
size_t characterstring_length(BACNET_CHARACTER_STRING * char_string);
uint8_t characterstring_encoding(BACNET_CHARACTER_STRING *
char_string);
size_t characterstring_capacity(BACNET_CHARACTER_STRING * char_string);
size_t characterstring_length(
BACNET_CHARACTER_STRING * char_string);
uint8_t characterstring_encoding(
BACNET_CHARACTER_STRING * char_string);
size_t characterstring_capacity(
BACNET_CHARACTER_STRING * char_string);
/* returns false if the string exceeds capacity
initialize by using length=0 */
bool octetstring_init(BACNET_OCTET_STRING * octet_string,
uint8_t * value, size_t length);
bool octetstring_copy(BACNET_OCTET_STRING * dest,
bool octetstring_init(
BACNET_OCTET_STRING * octet_string,
uint8_t * value,
size_t length);
bool octetstring_copy(
BACNET_OCTET_STRING * dest,
BACNET_OCTET_STRING * src);
/* returns false if the string exceeds capacity */
bool octetstring_append(BACNET_OCTET_STRING * octet_string,
uint8_t * value, size_t length);
bool octetstring_append(
BACNET_OCTET_STRING * octet_string,
uint8_t * value,
size_t length);
/* This function sets a new length without changing the value.
If length exceeds capacity, no modification happens and
function returns false. */
bool octetstring_truncate(BACNET_OCTET_STRING * octet_string,
bool octetstring_truncate(
BACNET_OCTET_STRING * octet_string,
size_t length);
/* Returns the value */
uint8_t *octetstring_value(BACNET_OCTET_STRING * octet_string);
uint8_t *octetstring_value(
BACNET_OCTET_STRING * octet_string);
/* Returns the length.*/
size_t octetstring_length(BACNET_OCTET_STRING * octet_string);
size_t octetstring_capacity(BACNET_OCTET_STRING * octet_string);
size_t octetstring_length(
BACNET_OCTET_STRING * octet_string);
size_t octetstring_capacity(
BACNET_OCTET_STRING * octet_string);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+41 -22
View File
@@ -51,31 +51,50 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
const char *bactext_confirmed_service_name(int index);
const char *bactext_unconfirmed_service_name(int index);
const char *bactext_application_tag_name(int index);
const char *bactext_object_type_name(int index);
const char *bactext_property_name(int index);
const char *bactext_engineering_unit_name(int index);
const char *bactext_reject_reason_name(int index);
const char *bactext_abort_reason_name(int index);
const char *bactext_error_class_name(int index);
const char *bactext_error_code_name(int index);
unsigned bactext_property_id(const char *name);
const char *bactext_month_name(int index);
const char *bactext_week_of_month_name(int index);
const char *bactext_day_of_week_name(int index);
const char *bactext_event_state_name(int index);
const char *bactext_binary_present_value_name(int index);
const char *bactext_reliability_name(int index);
const char *bactext_device_status_name(int index);
const char *bactext_segmentation_name(int index);
const char *bactext_confirmed_service_name(
int index);
const char *bactext_unconfirmed_service_name(
int index);
const char *bactext_application_tag_name(
int index);
const char *bactext_object_type_name(
int index);
const char *bactext_property_name(
int index);
const char *bactext_engineering_unit_name(
int index);
const char *bactext_reject_reason_name(
int index);
const char *bactext_abort_reason_name(
int index);
const char *bactext_error_class_name(
int index);
const char *bactext_error_code_name(
int index);
unsigned bactext_property_id(
const char *name);
const char *bactext_month_name(
int index);
const char *bactext_week_of_month_name(
int index);
const char *bactext_day_of_week_name(
int index);
const char *bactext_event_state_name(
int index);
const char *bactext_binary_present_value_name(
int index);
const char *bactext_reliability_name(
int index);
const char *bactext_device_status_name(
int index);
const char *bactext_segmentation_name(
int index);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* BACTEXT_PRINT_ENABLED */
#endif /* __cplusplus */
#endif /* BACTEXT_PRINT_ENABLED */
#endif
+16 -9
View File
@@ -31,29 +31,36 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Binary_Input_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Binary_Input_Valid_Instance(uint32_t object_instance);
unsigned Binary_Input_Count(void);
uint32_t Binary_Input_Index_To_Instance(unsigned index);
char *Binary_Input_Name(uint32_t object_instance);
bool Binary_Input_Valid_Instance(
uint32_t object_instance);
unsigned Binary_Input_Count(
void);
uint32_t Binary_Input_Index_To_Instance(
unsigned index);
char *Binary_Input_Name(
uint32_t object_instance);
int Binary_Input_Encode_Property_APDU(uint8_t * apdu,
int Binary_Input_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testBinaryInput(Test * pTest);
void testBinaryInput(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+4 -3
View File
@@ -3,7 +3,7 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* Big-Endian systems save the most significant byte first. */
/* Sun and Motorola processors, IBM-370s and PDP-10s are big-endian. */
@@ -21,9 +21,10 @@ extern "C" {
/* x[2] = 0x03 */
/* x[3] = 0x04 */
int big_endian(void);
int big_endian(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+34 -19
View File
@@ -51,51 +51,66 @@ extern bool BIP_Debug;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* note: define init and cleanup in your ports section */
/* on Linux, ifname is eth0, ath0, arc0, and others.
on Windows, ifname is the dotted ip address of the interface */
bool bip_init(char *ifname);
bool bip_init(
char *ifname);
/* normal functions... */
void bip_cleanup(void);
void bip_set_socket(int sock_fd);
int bip_socket(void);
bool bip_valid(void);
void bip_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
void bip_get_my_address(BACNET_ADDRESS * my_address);
void bip_cleanup(
void);
void bip_set_socket(
int sock_fd);
int bip_socket(
void);
bool bip_valid(
void);
void bip_get_broadcast_address(
BACNET_ADDRESS * dest); /* destination address */
void bip_get_my_address(
BACNET_ADDRESS * my_address);
/* function to send a packet out the BACnet/IP socket */
/* returns zero on success, non-zero on failure */
int bip_send_pdu(BACNET_ADDRESS * dest, /* destination address */
int bip_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len); /* number of bytes of data */
/* receives a BACnet/IP packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t bip_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout); /* milliseconds to wait for a packet */
/* use host byte order for setting */
void bip_set_port(uint16_t port);
void bip_set_port(
uint16_t port);
/* returns host byte order */
uint16_t bip_get_port(void);
uint16_t bip_get_port(
void);
/* use network byte order for setting */
void bip_set_addr(uint32_t net_address);
void bip_set_addr(
uint32_t net_address);
/* returns host byte order */
uint32_t bip_get_addr(void);
uint32_t bip_get_addr(
void);
/* use network byte order for setting */
void bip_set_broadcast_addr(uint32_t net_address);
void bip_set_broadcast_addr(
uint32_t net_address);
/* returns host byte order */
uint32_t bip_get_broadcast_addr(void);
uint32_t bip_get_broadcast_addr(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+20 -11
View File
@@ -33,32 +33,41 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Binary_Output_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Binary_Output_Valid_Instance(uint32_t object_instance);
unsigned Binary_Output_Count(void);
uint32_t Binary_Output_Index_To_Instance(unsigned index);
char *Binary_Output_Name(uint32_t object_instance);
bool Binary_Output_Valid_Instance(
uint32_t object_instance);
unsigned Binary_Output_Count(
void);
uint32_t Binary_Output_Index_To_Instance(
unsigned index);
char *Binary_Output_Name(
uint32_t object_instance);
int Binary_Output_Encode_Property_APDU(uint8_t * apdu,
int Binary_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool Binary_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testBinaryOutput(Test * pTest);
void testBinaryOutput(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+20 -11
View File
@@ -33,32 +33,41 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Binary_Value_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Binary_Value_Valid_Instance(uint32_t object_instance);
unsigned Binary_Value_Count(void);
uint32_t Binary_Value_Index_To_Instance(unsigned index);
char *Binary_Value_Name(uint32_t object_instance);
bool Binary_Value_Valid_Instance(
uint32_t object_instance);
unsigned Binary_Value_Count(
void);
uint32_t Binary_Value_Index_To_Instance(
unsigned index);
char *Binary_Value_Name(
uint32_t object_instance);
int Binary_Value_Encode_Property_APDU(uint8_t * apdu,
int Binary_Value_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool Binary_Value_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testBinary_Value(Test * pTest);
void testBinary_Value(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+9 -9
View File
@@ -43,21 +43,21 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
uint16_t bvlc_receive(
BACNET_ADDRESS * src, /* returns the source address */
uint8_t * npdu, /* returns the NPDU */
uint8_t * npdu, /* returns the NPDU */
uint16_t max_npdu, /* amount of space available in the NPDU */
unsigned timeout); /* number of milliseconds to wait for a packet */
unsigned timeout); /* number of milliseconds to wait for a packet */
int bvlc_send_pdu(BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
int bvlc_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* */
#endif /* __cplusplus */
#endif /* */
+1 -1
View File
@@ -67,4 +67,4 @@
#endif /* end of header file */
#endif /* end of header file */
+52 -27
View File
@@ -35,56 +35,81 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* unconfirmed requests */
void Send_WhoIs(int32_t low_limit, int32_t high_limit);
void Send_WhoIs(
int32_t low_limit,
int32_t high_limit);
void Send_WhoHas_Object(int32_t low_limit,
void Send_WhoHas_Object(
int32_t low_limit,
int32_t high_limit,
BACNET_OBJECT_TYPE object_type, uint32_t object_instance);
void Send_WhoHas_Name(int32_t low_limit,
int32_t high_limit, char *object_name);
void Send_I_Have(uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, char *object_name);
uint32_t object_instance);
/* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
void Send_WhoHas_Name(
int32_t low_limit,
int32_t high_limit,
char *object_name);
void Send_I_Have(
uint32_t device_id,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property, int32_t array_index);
char *object_name);
/* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Write_Property_Request(uint32_t device_id, /* destination device */
uint8_t Send_Read_Property_Request(
uint32_t device_id, /* destination device */
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
int32_t array_index);
/* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Write_Property_Request(
uint32_t device_id, /* destination device */
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_PROPERTY_ID object_property,
BACNET_APPLICATION_DATA_VALUE * object_value,
uint8_t priority, int32_t array_index);
uint8_t priority,
int32_t array_index);
/* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
BACNET_REINITIALIZED_STATE state, char *password);
uint8_t Send_Reinitialize_Device_Request(
uint32_t device_id,
BACNET_REINITIALIZED_STATE state,
char *password);
/* returns the invoke ID for confirmed request, or 0 if failed */
uint8_t Send_Device_Communication_Control_Request(uint32_t device_id, uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password); /* NULL=optional */
uint8_t Send_Device_Communication_Control_Request(
uint32_t device_id,
uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE state,
char *password); /* NULL=optional */
void Send_TimeSync(BACNET_DATE * bdate, BACNET_TIME * btime);
void Send_TimeSyncUTC(BACNET_DATE * bdate, BACNET_TIME * btime);
void Send_TimeSync(
BACNET_DATE * bdate,
BACNET_TIME * btime);
void Send_TimeSyncUTC(
BACNET_DATE * bdate,
BACNET_TIME * btime);
uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id,
uint32_t file_instance, int fileStartPosition,
unsigned requestedOctetCount);
uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
uint8_t Send_Atomic_Read_File_Stream(
uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, BACNET_OCTET_STRING * fileData);
int fileStartPosition,
unsigned requestedOctetCount);
uint8_t Send_Atomic_Write_File_Stream(
uint32_t device_id,
uint32_t file_instance,
int fileStartPosition,
BACNET_OCTET_STRING * fileData);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+23 -23
View File
@@ -7,29 +7,29 @@
/* declare a single physical layer using your compiler define.
see datalink.h for possible defines. */
#if !(defined(BACDL_ETHERNET) || defined(BACDL_ARCNET) || defined(BACDL_MSTP) || defined(BACDL_BIP) || defined(BACDL_TEST))
#define BACDL_BIP
#define BACDL_BIP
#endif
/* optional debug info for BACnet/IP datalink layers */
#if defined(BACDL_BIP)
#if !defined(USE_INADDR)
#define USE_INADDR 1
#endif
#if !defined(USE_INADDR)
#define USE_INADDR 1
#endif
#endif
/* Define your processor architecture as
Big Endian (PowerPC,68K,Sparc) or Little Endian (Intel,AVR)
ARM and MIPS can be either - what is your setup? */
#if !defined(BIG_ENDIAN)
#define BIG_ENDIAN 0
#define BIG_ENDIAN 0
#endif
/* Define your Vendor Identifier assigned by ASHRAE */
#if !defined(BACNET_VENDOR_ID)
#define BACNET_VENDOR_ID 260
#define BACNET_VENDOR_ID 260
#endif
#if !defined(BACNET_VENDOR_NAME)
#define BACNET_VENDOR_NAME "BACnet Stack at SourceForge"
#define BACNET_VENDOR_NAME "BACnet Stack at SourceForge"
#endif
/* Max number of bytes in an APDU. */
@@ -39,7 +39,7 @@
/* Lon=206, MS/TP=480, ARCNET=480, Ethernet=1476, BACnet/IP=64K */
#if !defined(MAX_APDU)
/* #define MAX_APDU 50 */
#define MAX_APDU 480
#define MAX_APDU 480
/* #define MAX_APDU 1476 */
#endif
@@ -49,7 +49,7 @@
/* Configure from 1..255 for number of outstanding confirmed */
/* requests available. */
#if !defined(MAX_TSM_TRANSACTIONS)
#define MAX_TSM_TRANSACTIONS 255
#define MAX_TSM_TRANSACTIONS 255
#endif
/* The address cache is used for binding to BACnet devices */
/* The number of entries corresponds to the number of */
@@ -57,30 +57,30 @@
/* If your device is a simple server and does not need to bind, */
/* then you don't need to use this. */
#if !defined(MAX_ADDRESS_CACHE)
#define MAX_ADDRESS_CACHE 255
#define MAX_ADDRESS_CACHE 255
#endif
/* some modules have debugging enabled using PRINT_ENABLED */
#if !defined(PRINT_ENABLED)
#define PRINT_ENABLED 0
#define PRINT_ENABLED 0
#endif
/* BACAPP decodes WriteProperty service requests
Choose the datatypes that your application supports */
#if defined (BACAPP_ALL)
#define BACAPP_NULL
#define BACAPP_BOOLEAN
#define BACAPP_UNSIGNED
#define BACAPP_SIGNED
#define BACAPP_REAL
#define BACAPP_NULL
#define BACAPP_BOOLEAN
#define BACAPP_UNSIGNED
#define BACAPP_SIGNED
#define BACAPP_REAL
/* FIXME: not implemented #define BACAPP_DOUBLE */
#define BACAPP_OCTET_STRING
#define BACAPP_CHARACTER_STRING
#define BACAPP_BIT_STRING
#define BACAPP_ENUMERATED
#define BACAPP_DATE
#define BACAPP_TIME
#define BACAPP_OBJECT_ID
#define BACAPP_OCTET_STRING
#define BACAPP_CHARACTER_STRING
#define BACAPP_BIT_STRING
#define BACAPP_ENUMERATED
#define BACAPP_DATE
#define BACAPP_TIME
#define BACAPP_OBJECT_ID
#endif
#endif
+49 -25
View File
@@ -67,54 +67,78 @@ typedef struct BACnet_Subscribe_COV_Data {
BACNET_OBJECT_ID monitoredObjectIdentifier;
bool cancellationRequest; /* true if this is a cancellation request */
bool issueConfirmedNotifications; /* optional */
unsigned lifetime; /* optional */
unsigned lifetime; /* optional */
BACNET_PROPERTY_REFERENCE monitoredProperty;
bool covIncrementPresent; /* true if present */
float covIncrement; /* optional */
float covIncrement; /* optional */
} BACNET_SUBSCRIBE_COV_DATA;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
int ucov_notify_encode_apdu(uint8_t * apdu, BACNET_COV_DATA * data);
int ucov_notify_encode_apdu(
uint8_t * apdu,
BACNET_COV_DATA * data);
int ucov_notify_decode_apdu(uint8_t * apdu,
unsigned apdu_len, BACNET_COV_DATA * data);
int ucov_notify_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
BACNET_COV_DATA * data);
int ucov_notify_send(uint8_t * buffer, BACNET_COV_DATA * data);
int ucov_notify_send(
uint8_t * buffer,
BACNET_COV_DATA * data);
int ccov_notify_encode_apdu(uint8_t * apdu,
uint8_t invoke_id, BACNET_COV_DATA * data);
int ccov_notify_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_COV_DATA * data);
int ccov_notify_decode_apdu(uint8_t * apdu,
unsigned apdu_len, uint8_t * invoke_id, BACNET_COV_DATA * data);
int ccov_notify_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
BACNET_COV_DATA * data);
/* common for both confirmed and unconfirmed */
int cov_notify_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_COV_DATA * data);
int cov_notify_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
BACNET_COV_DATA * data);
int cov_subscribe_property_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_property_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_property_encode_adpu(uint8_t * apdu,
uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_property_encode_adpu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_encode_adpu(uint8_t * apdu,
uint8_t invoke_id, BACNET_SUBSCRIBE_COV_DATA * data);
int cov_subscribe_encode_adpu(
uint8_t * apdu,
uint8_t invoke_id,
BACNET_SUBSCRIBE_COV_DATA * data);
#ifdef TEST
#include "ctest.h"
void testCOVNotify(Test * pTest);
void testCOVSubscribeProperty(Test * pTest);
void testCOVSubscribe(Test * pTest);
void testCOVNotify(
Test * pTest);
void testCOVSubscribeProperty(
Test * pTest);
void testCOVSubscribe(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+8 -4
View File
@@ -40,12 +40,16 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
uint8_t CRC_Calc_Header(uint8_t dataValue, uint8_t crcValue);
uint16_t CRC_Calc_Data(uint8_t dataValue, uint16_t crcValue);
uint8_t CRC_Calc_Header(
uint8_t dataValue,
uint8_t crcValue);
uint16_t CRC_Calc_Data(
uint8_t dataValue,
uint16_t crcValue);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+23 -13
View File
@@ -69,16 +69,16 @@
#elif defined(BACDL_BIP)
#include "bip.h"
#ifdef BBMD_ENABLED
#include "bvlc.h"
#include "bvlc.h"
#endif
#define datalink_init bip_init
#ifdef BBMD_ENABLED
#define datalink_send_pdu bvlc_send_pdu
#define datalink_receive bvlc_receive
#define datalink_send_pdu bvlc_send_pdu
#define datalink_receive bvlc_receive
#else
#define datalink_send_pdu bip_send_pdu
#define datalink_receive bip_receive
#define datalink_send_pdu bip_send_pdu
#define datalink_receive bip_receive
#endif
#define datalink_cleanup bip_cleanup
#define datalink_get_broadcast_address bip_get_broadcast_address
@@ -87,14 +87,24 @@
#else
#include "npdu.h"
extern int datalink_send_pdu(BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data, uint8_t * pdu, unsigned pdu_len);
extern uint16_t datalink_receive(BACNET_ADDRESS * src,
uint8_t * pdu, uint16_t max_pdu, unsigned timeout);
extern void datalink_cleanup(void);
extern void datalink_get_broadcast_address(BACNET_ADDRESS * dest);
extern void datalink_get_my_address(BACNET_ADDRESS * my_address);
extern void datalink_set_interface(char *ifname);
extern int datalink_send_pdu(
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data,
uint8_t * pdu,
unsigned pdu_len);
extern uint16_t datalink_receive(
BACNET_ADDRESS * src,
uint8_t * pdu,
uint16_t max_pdu,
unsigned timeout);
extern void datalink_cleanup(
void);
extern void datalink_get_broadcast_address(
BACNET_ADDRESS * dest);
extern void datalink_get_my_address(
BACNET_ADDRESS * my_address);
extern void datalink_set_interface(
char *ifname);
#endif
+57 -27
View File
@@ -49,10 +49,10 @@ typedef enum BACnet_Weekday {
/* date */
typedef struct BACnet_Date {
uint16_t year; /* AD */
uint8_t month; /* 1=Jan */
uint8_t day; /* 1..31 */
uint8_t wday; /* 1=Monday-7=Sunday */
uint16_t year; /* AD */
uint8_t month; /* 1=Jan */
uint8_t day; /* 1..31 */
uint8_t wday; /* 1=Monday-7=Sunday */
} BACNET_DATE;
/* time */
@@ -70,45 +70,75 @@ typedef struct BACnet_DateTime {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* utility initialization functions */
void datetime_set_date(BACNET_DATE * bdate,
uint16_t year, uint8_t month, uint8_t day);
void datetime_set_time(BACNET_TIME * btime,
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths);
void datetime_set(BACNET_DATE_TIME * bdatetime,
BACNET_DATE * bdate, BACNET_TIME * btime);
void datetime_set_values(BACNET_DATE_TIME * bdatetime,
uint16_t year, uint8_t month, uint8_t day,
uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths);
void datetime_set_date(
BACNET_DATE * bdate,
uint16_t year,
uint8_t month,
uint8_t day);
void datetime_set_time(
BACNET_TIME * btime,
uint8_t hour,
uint8_t minute,
uint8_t seconds,
uint8_t hundredths);
void datetime_set(
BACNET_DATE_TIME * bdatetime,
BACNET_DATE * bdate,
BACNET_TIME * btime);
void datetime_set_values(
BACNET_DATE_TIME * bdatetime,
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t seconds,
uint8_t hundredths);
/* utility comparison functions:
if the date/times are the same, return is 0
if date1 is before date2, returns negative
if date1 is after date2, returns positive */
int datetime_compare_date(BACNET_DATE * date1, BACNET_DATE * date2);
int datetime_compare_time(BACNET_TIME * time1, BACNET_TIME * time2);
int datetime_compare(BACNET_DATE_TIME * datetime1,
int datetime_compare_date(
BACNET_DATE * date1,
BACNET_DATE * date2);
int datetime_compare_time(
BACNET_TIME * time1,
BACNET_TIME * time2);
int datetime_compare(
BACNET_DATE_TIME * datetime1,
BACNET_DATE_TIME * datetime2);
/* utility copy functions */
void datetime_copy_date(BACNET_DATE * date1, BACNET_DATE * date2);
void datetime_copy_time(BACNET_TIME * time1, BACNET_TIME * time2);
void datetime_copy(BACNET_DATE_TIME * datetime1,
void datetime_copy_date(
BACNET_DATE * date1,
BACNET_DATE * date2);
void datetime_copy_time(
BACNET_TIME * time1,
BACNET_TIME * time2);
void datetime_copy(
BACNET_DATE_TIME * datetime1,
BACNET_DATE_TIME * datetime2);
/* utility add function */
void datetime_add_minutes(BACNET_DATE_TIME * bdatetime,
void datetime_add_minutes(
BACNET_DATE_TIME * bdatetime,
uint32_t minutes);
/* date and time wildcards */
bool datetime_wildcard(BACNET_DATE_TIME * bdatetime);
void datetime_wildcard_set(BACNET_DATE_TIME * bdatetime);
void datetime_date_wildcard_set(BACNET_DATE * bdate);
void datetime_time_wildcard_set(BACNET_TIME * btime);
bool datetime_wildcard(
BACNET_DATE_TIME * bdatetime);
void datetime_wildcard_set(
BACNET_DATE_TIME * bdatetime);
void datetime_date_wildcard_set(
BACNET_DATE * bdate);
void datetime_time_wildcard_set(
BACNET_TIME * btime);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DATE_TIME_H */
#endif /* __cplusplus */
#endif /* DATE_TIME_H */
+29 -15
View File
@@ -41,28 +41,40 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* return the status */
BACNET_COMMUNICATION_ENABLE_DISABLE dcc_enable_status(void);
bool dcc_communication_enabled(void);
bool dcc_communication_disabled(void);
bool dcc_communication_initiation_disabled(void);
BACNET_COMMUNICATION_ENABLE_DISABLE dcc_enable_status(
void);
bool dcc_communication_enabled(
void);
bool dcc_communication_disabled(
void);
bool dcc_communication_initiation_disabled(
void);
/* return the time */
uint32_t dcc_duration_seconds(void);
uint32_t dcc_duration_seconds(
void);
/* called every second or so. If more than one second,
then seconds should be the number of seconds to tick away */
void dcc_timer_seconds(uint32_t seconds);
void dcc_timer_seconds(
uint32_t seconds);
/* setup the communication values */
bool dcc_set_status_duration(BACNET_COMMUNICATION_ENABLE_DISABLE
status, uint16_t minutes);
bool dcc_set_status_duration(
BACNET_COMMUNICATION_ENABLE_DISABLE status,
uint16_t minutes);
/* encode service */
int dcc_encode_apdu(uint8_t * apdu, uint8_t invoke_id, uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable, BACNET_CHARACTER_STRING * password); /* NULL=optional */
int dcc_encode_apdu(
uint8_t * apdu,
uint8_t invoke_id,
uint16_t timeDuration, /* 0=optional */
BACNET_COMMUNICATION_ENABLE_DISABLE enable_disable,
BACNET_CHARACTER_STRING * password); /* NULL=optional */
/* decode the service request only */
int dcc_decode_service_request(uint8_t * apdu,
int dcc_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
uint16_t * timeDuration,
BACNET_COMMUNICATION_ENABLE_DISABLE * enable_disable,
@@ -70,17 +82,19 @@ extern "C" {
#ifdef TEST
#include "ctest.h"
int dcc_decode_apdu(uint8_t * apdu,
int dcc_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
uint8_t * invoke_id,
uint16_t * timeDuration,
BACNET_COMMUNICATION_ENABLE_DISABLE * enable_disable,
BACNET_CHARACTER_STRING * password);
void test_DeviceCommunicationControl(Test * pTest);
void test_DeviceCommunicationControl(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+79 -40
View File
@@ -42,71 +42,110 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Device_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
uint32_t Device_Object_Instance_Number(void);
bool Device_Set_Object_Instance_Number(uint32_t object_id);
bool Device_Valid_Object_Instance_Number(uint32_t object_id);
unsigned Device_Object_List_Count(void);
bool Device_Object_List_Identifier(unsigned array_index,
int *object_type, uint32_t * instance);
uint32_t Device_Object_Instance_Number(
void);
bool Device_Set_Object_Instance_Number(
uint32_t object_id);
bool Device_Valid_Object_Instance_Number(
uint32_t object_id);
unsigned Device_Object_List_Count(
void);
bool Device_Object_List_Identifier(
unsigned array_index,
int *object_type,
uint32_t * instance);
BACNET_DEVICE_STATUS Device_System_Status(void);
void Device_Set_System_Status(BACNET_DEVICE_STATUS status);
BACNET_DEVICE_STATUS Device_System_Status(
void);
void Device_Set_System_Status(
BACNET_DEVICE_STATUS status);
const char *Device_Vendor_Name(void);
const char *Device_Vendor_Name(
void);
uint16_t Device_Vendor_Identifier(void);
uint16_t Device_Vendor_Identifier(
void);
const char *Device_Model_Name(void);
bool Device_Set_Model_Name(const char *name, size_t length);
const char *Device_Firmware_Revision(void);
const char *Device_Application_Software_Version(void);
bool Device_Set_Application_Software_Version(const char *name,
const char *Device_Model_Name(
void);
bool Device_Set_Model_Name(
const char *name,
size_t length);
const char *Device_Description(void);
bool Device_Set_Description(const char *name, size_t length);
const char *Device_Firmware_Revision(
void);
const char *Device_Location(void);
bool Device_Set_Location(const char *name, size_t length);
const char *Device_Application_Software_Version(
void);
bool Device_Set_Application_Software_Version(
const char *name,
size_t length);
const char *Device_Description(
void);
bool Device_Set_Description(
const char *name,
size_t length);
const char *Device_Location(
void);
bool Device_Set_Location(
const char *name,
size_t length);
/* some stack-centric constant values - no set methods */
uint8_t Device_Protocol_Version(void);
uint8_t Device_Protocol_Revision(void);
uint16_t Device_Max_APDU_Length_Accepted(void);
BACNET_SEGMENTATION Device_Segmentation_Supported(void);
uint8_t Device_Protocol_Version(
void);
uint8_t Device_Protocol_Revision(
void);
uint16_t Device_Max_APDU_Length_Accepted(
void);
BACNET_SEGMENTATION Device_Segmentation_Supported(
void);
uint16_t Device_APDU_Timeout(void);
void Device_Set_APDU_Timeout(uint16_t timeout);
uint16_t Device_APDU_Timeout(
void);
void Device_Set_APDU_Timeout(
uint16_t timeout);
uint8_t Device_Number_Of_APDU_Retries(void);
void Device_Set_Number_Of_APDU_Retries(uint8_t retries);
uint8_t Device_Number_Of_APDU_Retries(
void);
void Device_Set_Number_Of_APDU_Retries(
uint8_t retries);
uint8_t Device_Database_Revision(void);
void Device_Set_Database_Revision(uint8_t revision);
uint8_t Device_Database_Revision(
void);
void Device_Set_Database_Revision(
uint8_t revision);
bool Device_Valid_Object_Name(const char *object_name,
int *object_type, uint32_t * object_instance);
char *Device_Valid_Object_Id(int object_type,
bool Device_Valid_Object_Name(
const char *object_name,
int *object_type,
uint32_t * object_instance);
char *Device_Valid_Object_Id(
int object_type,
uint32_t object_instance);
int Device_Encode_Property_APDU(uint8_t * apdu,
int Device_Encode_Property_APDU(
uint8_t * apdu,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Device_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool Device_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+35 -21
View File
@@ -46,29 +46,33 @@
#define MAX_MPDU (MAX_HEADER+MAX_PDU)
typedef struct dlmstp_packet {
bool ready; /* true if ready to be sent or received */
bool ready; /* true if ready to be sent or received */
BACNET_ADDRESS address; /* source address */
uint8_t frame_type; /* type of message */
uint16_t pdu_len; /* packet length */
uint8_t frame_type; /* type of message */
uint16_t pdu_len; /* packet length */
uint8_t pdu[MAX_MPDU]; /* packet */
} DLMSTP_PACKET;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
bool dlmstp_init(char *ifname);
void dlmstp_cleanup(void);
bool dlmstp_init(
char *ifname);
void dlmstp_cleanup(
void);
/* returns number of bytes sent on success, negative on failure */
int dlmstp_send_pdu(BACNET_ADDRESS * dest, /* destination address */
int dlmstp_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len); /* number of bytes of data */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t dlmstp_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t dlmstp_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout); /* milliseconds to wait for a packet */
@@ -79,29 +83,39 @@ extern "C" {
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(uint8_t max_info_frames);
uint8_t dlmstp_max_info_frames(void);
void dlmstp_set_max_info_frames(
uint8_t max_info_frames);
uint8_t dlmstp_max_info_frames(
void);
/* This parameter represents the value of the Max_Master property of the */
/* node's Device object. The value of Max_Master specifies the highest */
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(uint8_t max_master);
uint8_t dlmstp_max_master(void);
void dlmstp_set_max_master(
uint8_t max_master);
uint8_t dlmstp_max_master(
void);
/* MAC address 0-127 */
void dlmstp_set_mac_address(uint8_t my_address);
uint8_t dlmstp_mac_address(void);
void dlmstp_set_mac_address(
uint8_t my_address);
uint8_t dlmstp_mac_address(
void);
void dlmstp_get_my_address(BACNET_ADDRESS * my_address);
void dlmstp_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
void dlmstp_get_my_address(
BACNET_ADDRESS * my_address);
void dlmstp_get_broadcast_address(
BACNET_ADDRESS * dest); /* destination address */
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
void dlmstp_set_baud_rate(uint32_t baud);
uint32_t dlmstp_baud_rate(void);
void dlmstp_set_baud_rate(
uint32_t baud);
uint32_t dlmstp_baud_rate(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+20 -12
View File
@@ -46,31 +46,39 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
bool ethernet_valid(void);
void ethernet_cleanup(void);
bool ethernet_init(char *interface_name);
bool ethernet_valid(
void);
void ethernet_cleanup(
void);
bool ethernet_init(
char *interface_name);
/* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(BACNET_ADDRESS * dest, /* destination address */
int ethernet_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len); /* number of bytes of data */
/* receives an 802.2 framed packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t ethernet_receive(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t ethernet_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout); /* milliseconds to wait for a packet */
void ethernet_set_my_address(BACNET_ADDRESS * my_address);
void ethernet_get_my_address(BACNET_ADDRESS * my_address);
void ethernet_get_broadcast_address(BACNET_ADDRESS * dest); /* destination address */
void ethernet_set_my_address(
BACNET_ADDRESS * my_address);
void ethernet_get_my_address(
BACNET_ADDRESS * my_address);
void ethernet_get_broadcast_address(
BACNET_ADDRESS * dest); /* destination address */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+4 -3
View File
@@ -36,11 +36,12 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
char *filename_remove_path(const char *filename_in);
char *filename_remove_path(
const char *filename_in);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+53 -29
View File
@@ -34,72 +34,96 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void handler_unrecognized_service(uint8_t * service_request,
void handler_unrecognized_service(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * dest,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_who_is(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_who_is(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_who_has(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_who_has(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_i_am_add(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_i_am_add(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_i_am_bind(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_i_am_bind(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_read_property(uint8_t * service_request,
void handler_read_property(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_read_property_ack(uint8_t * service_request,
void handler_read_property_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data);
void handler_write_property(uint8_t * service_request,
void handler_write_property(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_atomic_read_file(uint8_t * service_request,
void handler_atomic_read_file(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_atomic_read_file_ack(uint8_t * service_request,
void handler_atomic_read_file_ack(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA * service_data);
void handler_atomic_write_file(uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src, BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_reinitialize_device(uint8_t * service_request,
void handler_atomic_write_file(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_device_communication_control(uint8_t * service_request,
void handler_reinitialize_device(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_i_have(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_device_communication_control(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA * service_data);
void handler_timesync(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_i_have(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_timesync_utc(uint8_t * service_request,
uint16_t service_len, BACNET_ADDRESS * src);
void handler_timesync(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_timesync_utc(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src);
void handler_read_property_multiple(
uint8_t * service_request,
@@ -108,7 +132,7 @@ extern "C" {
BACNET_CONFIRMED_SERVICE_DATA * service_data);
/* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */
or sets the error, and returns -1 */
/* resides in h_rp.c */
int Encode_Property_APDU(
uint8_t * apdu,
@@ -123,5 +147,5 @@ extern "C" {
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+25 -14
View File
@@ -42,33 +42,44 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
int iam_encode_apdu(uint8_t * apdu,
int iam_encode_apdu(
uint8_t * apdu,
uint32_t device_id,
unsigned max_apdu, int segmentation, uint16_t vendor_id);
unsigned max_apdu,
int segmentation,
uint16_t vendor_id);
int iam_decode_service_request(uint8_t * apdu,
int iam_decode_service_request(
uint8_t * apdu,
uint32_t * pDevice_id,
unsigned *pMax_apdu, int *pSegmentation, uint16_t * pVendor_id);
unsigned *pMax_apdu,
int *pSegmentation,
uint16_t * pVendor_id);
int iam_encode_pdu(
uint8_t * buffer,
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data);
int iam_send(uint8_t * buffer);
uint8_t * buffer,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data);
int iam_send(
uint8_t * buffer);
#ifdef TEST
#include "ctest.h"
int iam_decode_apdu(uint8_t * apdu,
int iam_decode_apdu(
uint8_t * apdu,
uint32_t * pDevice_id,
unsigned *pMax_apdu, int *pSegmentation, uint16_t * pVendor_id);
unsigned *pMax_apdu,
int *pSegmentation,
uint16_t * pVendor_id);
void testIAm(Test * pTest);
void testIAm(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+15 -8
View File
@@ -46,22 +46,29 @@ typedef struct BACnet_I_Have_Data {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
int ihave_encode_apdu(uint8_t * apdu, BACNET_I_HAVE_DATA * data);
int ihave_encode_apdu(
uint8_t * apdu,
BACNET_I_HAVE_DATA * data);
int ihave_decode_service_request(uint8_t * apdu,
unsigned apdu_len, BACNET_I_HAVE_DATA * data);
int ihave_decode_service_request(
uint8_t * apdu,
unsigned apdu_len,
BACNET_I_HAVE_DATA * data);
int ihave_decode_apdu(uint8_t * apdu,
unsigned apdu_len, BACNET_I_HAVE_DATA * data);
int ihave_decode_apdu(
uint8_t * apdu,
unsigned apdu_len,
BACNET_I_HAVE_DATA * data);
#ifdef TEST
#include "ctest.h"
void testIHave(Test * pTest);
void testIHave(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+34 -18
View File
@@ -40,56 +40,72 @@
/* index and text pairs */
typedef struct {
unsigned index; /* index number that matches the text */
unsigned index; /* index number that matches the text */
const char *pString; /* text pair - use NULL to end the list */
} INDTEXT_DATA;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* Searches for a matching string and returns the index to the string
in the parameter found_index.
If the string is not found, false is returned
If the string is found, true is returned and the found_index contains
the first index where the string was found. */
bool indtext_by_string(INDTEXT_DATA * data_list,
const char *search_name, unsigned *found_index);
bool indtext_by_string(
INDTEXT_DATA * data_list,
const char *search_name,
unsigned *found_index);
/* case insensitive version */
bool indtext_by_istring(INDTEXT_DATA * data_list,
const char *search_name, unsigned *found_index);
bool indtext_by_istring(
INDTEXT_DATA * data_list,
const char *search_name,
unsigned *found_index);
/* Searches for a matching string and returns the index to the string
or the default_index if the string is not found. */
unsigned indtext_by_string_default(INDTEXT_DATA * data_list,
const char *search_name, unsigned default_index);
unsigned indtext_by_string_default(
INDTEXT_DATA * data_list,
const char *search_name,
unsigned default_index);
/* case insensitive version */
unsigned indtext_by_istring_default(INDTEXT_DATA * data_list,
const char *search_name, unsigned default_index);
unsigned indtext_by_istring_default(
INDTEXT_DATA * data_list,
const char *search_name,
unsigned default_index);
/* for a given index, return the matching string,
or NULL if not found */
const char *indtext_by_index(INDTEXT_DATA * data_list, unsigned index);
const char *indtext_by_index(
INDTEXT_DATA * data_list,
unsigned index);
/* for a given index, return the matching string,
or default_name if not found */
const char *indtext_by_index_default(INDTEXT_DATA * data_list,
unsigned index, const char *default_name);
const char *indtext_by_index_default(
INDTEXT_DATA * data_list,
unsigned index,
const char *default_name);
/* for a given index, return the matching string,
or default_name if not found.
if the index is before the split,
the before_split_default_name is used */
const char *indtext_by_index_split_default(INDTEXT_DATA * data_list,
const char *indtext_by_index_split_default(
INDTEXT_DATA * data_list,
int index,
int split_index,
const char *before_split_default_name, const char *default_name);
const char *before_split_default_name,
const char *default_name);
/* returns the number of elements in the list */
unsigned indtext_count(INDTEXT_DATA * data_list);
unsigned indtext_count(
INDTEXT_DATA * data_list);
#ifdef TEST
#include "ctest.h"
void testIndexText(Test * pTest);
void testIndexText(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+34 -15
View File
@@ -42,52 +42,71 @@
/* list data and datatype */
struct Keylist_Node {
KEY key; /* unique number that is sorted in the list */
void *data; /* pointer to some data that is stored */
KEY key; /* unique number that is sorted in the list */
void *data; /* pointer to some data that is stored */
};
typedef struct Keylist {
struct Keylist_Node **array; /* array of nodes */
int count; /* number of nodes in this list - more effecient than loop */
int size; /* number of available nodes on this list - can grow or shrink */
int count; /* number of nodes in this list - more effecient than loop */
int size; /* number of available nodes on this list - can grow or shrink */
} KEYLIST_TYPE;
typedef KEYLIST_TYPE *OS_Keylist;
/* returns head of the list or NULL on failure. */
OS_Keylist Keylist_Create(void);
OS_Keylist Keylist_Create(
void);
/* delete specified list */
/* note: you should pop all the nodes off the list first. */
void Keylist_Delete(OS_Keylist list);
void Keylist_Delete(
OS_Keylist list);
/* inserts a node into its sorted position */
/* returns the index where it was added */
int Keylist_Data_Add(OS_Keylist list, KEY key, void *data);
int Keylist_Data_Add(
OS_Keylist list,
KEY key,
void *data);
/* deletes a node specified by its key */
/* returns the data from the node */
void *Keylist_Data_Delete(OS_Keylist list, KEY key);
void *Keylist_Data_Delete(
OS_Keylist list,
KEY key);
/* deletes a node specified by its index */
/* returns the data from the node */
void *Keylist_Data_Delete_By_Index(OS_Keylist list, int index);
void *Keylist_Data_Delete_By_Index(
OS_Keylist list,
int index);
/* returns the data from last node, and removes it from the list */
void *Keylist_Data_Pop(OS_Keylist list);
void *Keylist_Data_Pop(
OS_Keylist list);
/* returns the data from the node specified by key */
void *Keylist_Data(OS_Keylist list, KEY key);
void *Keylist_Data(
OS_Keylist list,
KEY key);
/* returns the data specified by key */
void *Keylist_Data_Index(OS_Keylist list, int index);
void *Keylist_Data_Index(
OS_Keylist list,
int index);
/* return the key at the given index */
KEY Keylist_Key(OS_Keylist list, int index);
KEY Keylist_Key(
OS_Keylist list,
int index);
/* returns the next empty key from the list */
KEY Keylist_Next_Empty_Key(OS_Keylist list, KEY key);
KEY Keylist_Next_Empty_Key(
OS_Keylist list,
KEY key);
/* returns the number of items in the list */
int Keylist_Count(OS_Keylist list);
int Keylist_Count(
OS_Keylist list);
#endif
+22 -12
View File
@@ -33,34 +33,44 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Load_Control_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
void Load_Control_State_Machine_Handler(void);
void Load_Control_State_Machine_Handler(
void);
bool Load_Control_Valid_Instance(uint32_t object_instance);
unsigned Load_Control_Count(void);
uint32_t Load_Control_Index_To_Instance(unsigned index);
char *Load_Control_Name(uint32_t object_instance);
bool Load_Control_Valid_Instance(
uint32_t object_instance);
unsigned Load_Control_Count(
void);
uint32_t Load_Control_Index_To_Instance(
unsigned index);
char *Load_Control_Name(
uint32_t object_instance);
int Load_Control_Encode_Property_APDU(uint8_t * apdu,
int Load_Control_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
bool Load_Control_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testLoadControl(Test * pTest);
void testLoadControl(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+32 -19
View File
@@ -33,37 +33,50 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
bool Analog_Output_Valid_Instance(uint32_t object_instance);
unsigned Lighting_Output_Count(void);
uint32_t Lighting_Output_Index_To_Instance(unsigned index);
char *Lighting_Output_Name(uint32_t object_instance);
float Lighting_Output_Present_Value(uint32_t object_instance);
unsigned Lighting_Output_Present_Value_Priority(uint32_t
object_instance);
bool Lighting_Output_Present_Value_Set(uint32_t object_instance,
float value, unsigned priority);
bool Lighting_Output_Present_Value_Relinquish(uint32_t object_instance,
bool Analog_Output_Valid_Instance(
uint32_t object_instance);
unsigned Lighting_Output_Count(
void);
uint32_t Lighting_Output_Index_To_Instance(
unsigned index);
char *Lighting_Output_Name(
uint32_t object_instance);
float Lighting_Output_Present_Value(
uint32_t object_instance);
unsigned Lighting_Output_Present_Value_Priority(
uint32_t object_instance);
bool Lighting_Output_Present_Value_Set(
uint32_t object_instance,
float value,
unsigned priority);
bool Lighting_Output_Present_Value_Relinquish(
uint32_t object_instance,
int priority);
/* ReadProperty service support */
int Lighting_Output_Encode_Property_APDU(uint8_t * apdu,
/* ReadProperty service support */
int Lighting_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
/* WriteProperty service support */
bool Lighting_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
/* WriteProperty service support */
bool Lighting_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testLightingOutput(Test * pTest);
void testLightingOutput(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+19 -11
View File
@@ -33,33 +33,41 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Life_Safety_Point_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Life_Safety_Point_Valid_Instance(uint32_t object_instance);
unsigned Life_Safety_Point_Count(void);
uint32_t Life_Safety_Point_Index_To_Instance(unsigned index);
char *Life_Safety_Point_Name(uint32_t object_instance);
bool Life_Safety_Point_Valid_Instance(
uint32_t object_instance);
unsigned Life_Safety_Point_Count(
void);
uint32_t Life_Safety_Point_Index_To_Instance(
unsigned index);
char *Life_Safety_Point_Name(
uint32_t object_instance);
int Life_Safety_Point_Encode_Property_APDU(uint8_t * apdu,
int Life_Safety_Point_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Life_Safety_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *
wp_data, BACNET_ERROR_CLASS * error_class,
bool Life_Safety_Point_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testLifeSafetyPoint(Test * pTest);
void testLifeSafetyPoint(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+19 -11
View File
@@ -33,33 +33,41 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void Multistate_Output_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary);
bool Multistate_Output_Valid_Instance(uint32_t object_instance);
unsigned Multistate_Output_Count(void);
uint32_t Multistate_Output_Index_To_Instance(unsigned index);
char *Multistate_Output_Name(uint32_t object_instance);
bool Multistate_Output_Valid_Instance(
uint32_t object_instance);
unsigned Multistate_Output_Count(
void);
uint32_t Multistate_Output_Index_To_Instance(
unsigned index);
char *Multistate_Output_Name(
uint32_t object_instance);
int Multistate_Output_Encode_Property_APDU(uint8_t * apdu,
int Multistate_Output_Encode_Property_APDU(
uint8_t * apdu,
uint32_t object_instance,
BACNET_PROPERTY_ID property,
int32_t array_index,
BACNET_ERROR_CLASS * error_class, BACNET_ERROR_CODE * error_code);
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
bool Multistate_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *
wp_data, BACNET_ERROR_CLASS * error_class,
bool Multistate_Output_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef TEST
#include "ctest.h"
void testMultistateOutput(Test * pTest);
void testMultistateOutput(
Test * pTest);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+26 -18
View File
@@ -194,14 +194,18 @@ struct mstp_port_struct_t {
/* denote intervals between N-1 and N */
/* Note: done here as functions - put into timer task or ISR
so that you can be atomic on 8 bit microcontrollers */
uint16_t (*SilenceTimer)(void);
void (*SilenceTimerReset)(void);
uint16_t(
*SilenceTimer) (
void);
void (
*SilenceTimerReset) (
void);
/* A timer used to measure and generate Reply Postponed frames. It is */
/* incremented by a timer process and is cleared by the Master Node State */
/* Machine when a Data Expecting Reply Answer activity is completed. */
/* note: we always send a reply postponed since a message other than
the reply may be in the transmit queue */
the reply may be in the transmit queue */
/* uint16_t ReplyPostponedTimer; */
/* Used to store the Source Address of a received frame. */
@@ -256,32 +260,36 @@ struct mstp_port_struct_t {
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
void MSTP_Init(volatile struct mstp_port_struct_t *mstp_port);
void MSTP_Receive_Frame_FSM(volatile struct mstp_port_struct_t
void MSTP_Init(
volatile struct mstp_port_struct_t *mstp_port);
void MSTP_Receive_Frame_FSM(
volatile struct mstp_port_struct_t
*mstp_port);
bool MSTP_Master_Node_FSM(volatile struct mstp_port_struct_t
bool MSTP_Master_Node_FSM(
volatile struct mstp_port_struct_t
*mstp_port);
/* returns true if line is active */
bool MSTP_Line_Active(volatile struct mstp_port_struct_t *mstp_port);
bool MSTP_Line_Active(
volatile struct mstp_port_struct_t *mstp_port);
uint16_t MSTP_Create_Frame(
uint8_t * buffer, /* where frame is loaded */
uint8_t * buffer, /* where frame is loaded */
uint16_t buffer_len, /* amount of space available */
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint16_t data_len); /* number of bytes of data (up to 501) */
void MSTP_Create_And_Send_Frame(
volatile struct mstp_port_struct_t *mstp_port, /* port to send from */
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint8_t frame_type, /* type of frame to send - see defines */
uint8_t destination, /* destination address */
uint8_t source, /* source address */
uint8_t * data, /* any data to be sent - may be null */
uint16_t data_len);
/* functions used by the MS/TP state machine to put or get data */
@@ -293,15 +301,15 @@ extern "C" {
/* Return: amount of PDU data */
uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t *mstp_port,
unsigned timeout); /* milliseconds to wait for a packet */
unsigned timeout); /* milliseconds to wait for a packet */
/* for the MS/TP state machine to use for getting the reply for
Data-Expecting-Reply Frame */
/* Return: amount of PDU data */
uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t *mstp_port,
unsigned timeout); /* milliseconds to wait for a packet */
unsigned timeout); /* milliseconds to wait for a packet */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+8 -6
View File
@@ -37,14 +37,16 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
const char *mstptext_receive_state(int index);
const char *mstptext_master_state(int index);
const char *mstptext_frame_type(int index);
const char *mstptext_receive_state(
int index);
const char *mstptext_master_state(
int index);
const char *mstptext_frame_type(
int index);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif
+24 -13
View File
@@ -48,34 +48,45 @@ typedef struct bacnet_npdu_data_t {
BACNET_MESSAGE_PRIORITY priority;
/* optional network message info */
BACNET_NETWORK_MESSAGE_TYPE network_message_type; /* optional */
uint16_t vendor_id; /* optional, if net message type is > 0x80 */
uint16_t vendor_id; /* optional, if net message type is > 0x80 */
uint8_t hop_count;
} BACNET_NPDU_DATA;
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
uint8_t npdu_encode_max_seg_max_apdu(int max_segs, int max_apdu);
uint8_t npdu_encode_max_seg_max_apdu(
int max_segs,
int max_apdu);
int npdu_encode_pdu(uint8_t * npdu,
int npdu_encode_pdu(
uint8_t * npdu,
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data);
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data);
void npdu_encode_npdu_data(BACNET_NPDU_DATA * npdu,
bool data_expecting_reply, BACNET_MESSAGE_PRIORITY priority);
void npdu_encode_npdu_data(
BACNET_NPDU_DATA * npdu,
bool data_expecting_reply,
BACNET_MESSAGE_PRIORITY priority);
void npdu_copy_data(BACNET_NPDU_DATA * dest, BACNET_NPDU_DATA * src);
void npdu_copy_data(
BACNET_NPDU_DATA * dest,
BACNET_NPDU_DATA * src);
int npdu_decode(uint8_t * npdu,
int npdu_decode(
uint8_t * npdu,
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src, BACNET_NPDU_DATA * npdu_data);
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data);
void npdu_handler(BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
void npdu_handler(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t pdu_len); /* length PDU */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif

Some files were not shown because too many files have changed in this diff Show More