Merge pull request #3 from bacnet-stack/issue-1-Indent_and_style_for_source_code

Issue 1 indent and style for source code
This commit is contained in:
Steve Karg
2019-10-24 16:46:46 -05:00
committed by GitHub
215 changed files with 19438 additions and 26079 deletions
-9
View File
@@ -1,9 +0,0 @@
#--indent-cases
--indent-classes
--indent-switches
--indent=spaces=4
#--max-instatement-indent=4
#--min-conditional-indent=0
--brackets=linux
--convert-tabs
--mode=c
+10
View File
@@ -0,0 +1,10 @@
---
BasedOnStyle: Google
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
BreakBeforeBraces: Linux
IndentWidth: 4
SortIncludes: false
...
Vendored
-1
View File
@@ -1 +0,0 @@
-kr -nut -nlp -ip4 -cli4 -bfda -nbc -nbbo -c0 -cd0 -cp0 -di0 -l79 -nhnl
+5
View File
@@ -122,6 +122,11 @@ mstpsnap: ports/linux/mstpsnap.mak
bdk-atxx4-mstp: ports/bdk-atxx4-mstp/Makefile bdk-atxx4-mstp: ports/bdk-atxx4-mstp/Makefile
$(MAKE) -s -C ports/bdk-atxx4-mstp clean all $(MAKE) -s -C ports/bdk-atxx4-mstp clean all
pretty:
find ./src -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \;
find ./include -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \;
find ./demo -iname *.h -o -iname *.c -exec clang-format -i -style=file -fallback-style=none {} \;
clean: clean:
$(MAKE) -s -C lib clean $(MAKE) -s -C lib clean
$(MAKE) -s -C demo clean $(MAKE) -s -C demo clean
+19 -27
View File
@@ -54,11 +54,8 @@ static bool Target_Server = true;
/* flag for signalling errors */ /* flag for signalling errors */
static bool Error_Detected = false; static bool Error_Detected = false;
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -67,9 +64,7 @@ void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
(void)src; (void)src;
@@ -78,8 +73,7 @@ void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
/* we need to handle who-is /* we need to handle who-is
@@ -87,8 +81,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -101,8 +94,7 @@ static void Init_Service_Handlers(
static void print_usage(char *filename) static void print_usage(char *filename)
{ {
printf("Usage: %s [abort-reason [invoke-id [server]]]\n", printf("Usage: %s [abort-reason [invoke-id [server]]]\n", filename);
filename);
printf(" [--dnet][--dadr][--mac]\n"); printf(" [--dnet][--dadr][--mac]\n");
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
} }
@@ -110,7 +102,8 @@ static void print_usage(char *filename)
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Send BACnet Abort message to the network.\n"); printf("Send BACnet Abort message to the network.\n");
printf("--mac A\n" printf(
"--mac A\n"
"Optional destination BACnet mac address." "Optional destination BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
@@ -122,12 +115,14 @@ static void print_help(char *filename)
"and 65535 is network broadcast.\n" "and 65535 is network broadcast.\n"
"\n" "\n"
"--dadr A\n" "--dadr A\n"
"Optional BACnet mac address on the destination BACnet network number.\n" "Optional BACnet mac address on the destination BACnet network "
"number.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
"\n"); "\n");
printf("abort-reason:\n" printf(
"abort-reason:\n"
" number from 0 to 65535\n" " number from 0 to 65535\n"
"invoke-id:\n" "invoke-id:\n"
" number from 1 to 255\n" " number from 1 to 255\n"
@@ -138,9 +133,7 @@ static void print_help(char *filename)
filename); filename);
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
long dnet = -1; long dnet = -1;
BACNET_MAC_ADDRESS mac = {0}; BACNET_MAC_ADDRESS mac = {0};
@@ -160,8 +153,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2016 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2016 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0; return 0;
@@ -239,11 +234,8 @@ int main(
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
/* send the request */ /* send the request */
Send_Abort_To_Network(&Handler_Transmit_Buffer[0], Send_Abort_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
&dest, Target_Abort_Reason, Target_Server);
Target_Invoke_ID,
Target_Abort_Reason,
Target_Server);
return 0; return 0;
} }
+31 -41
View File
@@ -65,9 +65,7 @@ static char *Communication_Password = NULL;
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyErrorHandler( static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
@@ -79,11 +77,8 @@ static void MyErrorHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -93,9 +88,7 @@ void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
@@ -105,8 +98,7 @@ void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyDeviceCommunicationControlSimpleAckHandler( void MyDeviceCommunicationControlSimpleAckHandler(BACNET_ADDRESS *src,
BACNET_ADDRESS * src,
uint8_t invoke_id) uint8_t invoke_id)
{ {
(void)src; (void)src;
@@ -114,8 +106,7 @@ void MyDeviceCommunicationControlSimpleAckHandler(
printf("DeviceCommunicationControl Acknowledged!\n"); printf("DeviceCommunicationControl Acknowledged!\n");
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
/* we need to handle who-is /* we need to handle who-is
@@ -125,8 +116,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -134,8 +124,8 @@ static void Init_Service_Handlers(
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control); handler_device_communication_control);
/* handle the ack coming back */ /* handle the ack coming back */
apdu_set_confirmed_simple_ack_handler apdu_set_confirmed_simple_ack_handler(
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
MyDeviceCommunicationControlSimpleAckHandler); MyDeviceCommunicationControlSimpleAckHandler);
/* handle any errors coming back */ /* handle any errors coming back */
apdu_set_error_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, apdu_set_error_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
@@ -152,11 +142,16 @@ static void print_usage(char *filename)
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Send BACnet DeviceCommunicationControl service to device.\n" printf(
"\n" "The device-instance can be 0 to %lu.\n" "Send BACnet DeviceCommunicationControl service to device.\n"
"Possible state values:\n" " 0=enable\n" " 1=disable\n" "\n"
"The device-instance can be 0 to %lu.\n"
"Possible state values:\n"
" 0=enable\n"
" 1=disable\n"
" 2=disable-initiation\n" " 2=disable-initiation\n"
"The timeout can be 0 for infinite, or a value in minutes for disable.\n" "The timeout can be 0 for infinite, or a value in minutes for "
"disable.\n"
"The optional password is a character string of 1 to 20 characters.\n" "The optional password is a character string of 1 to 20 characters.\n"
"\nExample:\n" "\nExample:\n"
"If you want disable Device Communications in Device 123\n" "If you want disable Device Communications in Device 123\n"
@@ -165,13 +160,9 @@ static void print_help(char *filename)
(unsigned long)(BACNET_MAX_INSTANCE - 1), filename); (unsigned long)(BACNET_MAX_INSTANCE - 1), filename);
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
BACNET_ADDRESS src = { BACNET_ADDRESS src = {0}; /* address where message came from */
0
}; /* address where message came from */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */ unsigned timeout = 100; /* milliseconds */
unsigned max_apdu = 0; unsigned max_apdu = 0;
@@ -193,8 +184,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0; return 0;
@@ -230,8 +223,7 @@ int main(
last_seconds = time(NULL); last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */ /* try to bind with the device */
found = found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address); &Target_Address);
if (!found) { if (!found) {
Send_WhoIs(Target_Device_Object_Instance, Send_WhoIs(Target_Device_Object_Instance,
@@ -251,21 +243,19 @@ int main(
} }
/* at least one second has passed */ /* at least one second has passed */
if (current_seconds != last_seconds) if (current_seconds != last_seconds)
tsm_timer_milliseconds((uint16_t) ((current_seconds - tsm_timer_milliseconds(
last_seconds) * 1000)); (uint16_t)((current_seconds - last_seconds) * 1000));
if (Error_Detected) if (Error_Detected)
break; break;
/* wait until the device is bound, or timeout and quit */ /* wait until the device is bound, or timeout and quit */
if (!found) { if (!found) {
found = found = address_bind_request(Target_Device_Object_Instance,
address_bind_request(Target_Device_Object_Instance, &max_apdu, &max_apdu, &Target_Address);
&Target_Address);
} }
if (found) { if (found) {
if (invoke_id == 0) { if (invoke_id == 0) {
invoke_id = invoke_id = Send_Device_Communication_Control_Request(
Send_Device_Communication_Control_Request Target_Device_Object_Instance,
(Target_Device_Object_Instance,
Communication_Timeout_Minutes, Communication_State, Communication_Timeout_Minutes, Communication_State,
Communication_Password); Communication_Password);
} else if (tsm_invoke_id_free(invoke_id)) } else if (tsm_invoke_id_free(invoke_id))
+124 -139
View File
@@ -58,7 +58,6 @@
#include "keylist.h" #include "keylist.h"
#include "bacepics.h" #include "bacepics.h"
/* (Doxygen note: The next two lines pull all the following Javadoc /* (Doxygen note: The next two lines pull all the following Javadoc
* into the BACEPICS module.) */ * into the BACEPICS module.) */
/** @addtogroup BACEPICS /** @addtogroup BACEPICS
@@ -139,11 +138,9 @@ static struct property_value_list_t Property_Value_List[] = {
{PROP_PROTOCOL_SERVICES_SUPPORTED, NULL}, {PROP_PROTOCOL_SERVICES_SUPPORTED, NULL},
{PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL}, {PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED, NULL},
{PROP_DESCRIPTION, NULL}, {PROP_DESCRIPTION, NULL},
{-1, NULL} {-1, NULL}};
};
static BACNET_APPLICATION_DATA_VALUE *object_property_value( static BACNET_APPLICATION_DATA_VALUE *object_property_value(int32_t property_id)
int32_t property_id)
{ {
BACNET_APPLICATION_DATA_VALUE *value = NULL; BACNET_APPLICATION_DATA_VALUE *value = NULL;
int32_t index = 0; int32_t index = 0;
@@ -180,9 +177,7 @@ static bool Optional_Properties = false;
#define PRINT_ERRORS 1 #define PRINT_ERRORS 1
#endif #endif
static void MyErrorHandler( static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
@@ -201,11 +196,8 @@ static void MyErrorHandler(
} }
} }
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
@@ -227,9 +219,7 @@ void MyAbortHandler(
} }
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
@@ -250,9 +240,7 @@ void MyRejectHandler(
} }
} }
void MyReadPropertyAckHandler( void MyReadPropertyAckHandler(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
@@ -263,8 +251,7 @@ void MyReadPropertyAckHandler(
(service_data->invoke_id == Request_Invoke_ID)) { (service_data->invoke_id == Request_Invoke_ID)) {
rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); rp_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rp_data) { if (rp_data) {
len = len = rp_ack_fully_decode_service_request(service_request,
rp_ack_fully_decode_service_request(service_request,
service_len, rp_data); service_len, rp_data);
} }
if (len > 0) { if (len > 0) {
@@ -281,9 +268,7 @@ void MyReadPropertyAckHandler(
} }
void MyReadPropertyMultipleAckHandler( void MyReadPropertyMultipleAckHandler(
uint8_t * service_request, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
int len = 0; int len = 0;
@@ -293,8 +278,7 @@ void MyReadPropertyMultipleAckHandler(
(service_data->invoke_id == Request_Invoke_ID)) { (service_data->invoke_id == Request_Invoke_ID)) {
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rpm_data) { if (rpm_data) {
len = len = rpm_ack_decode_service_request(service_request, service_len,
rpm_ack_decode_service_request(service_request, service_len,
rpm_data); rpm_data);
} }
if (len > 0) { if (len > 0) {
@@ -311,8 +295,7 @@ void MyReadPropertyMultipleAckHandler(
} }
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
@@ -332,8 +315,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -348,7 +330,6 @@ static void Init_Service_Handlers(
apdu_set_reject_handler(MyRejectHandler); apdu_set_reject_handler(MyRejectHandler);
} }
/** Determine if this is a writable property, and, if so, /** Determine if this is a writable property, and, if so,
* note that in the EPICS output. * note that in the EPICS output.
* This function may need a lot of customization for different implementations. * This function may need a lot of customization for different implementations.
@@ -358,8 +339,7 @@ static void Init_Service_Handlers(
* @param rpm_property [in] Points to structure holding the Property, * @param rpm_property [in] Points to structure holding the Property,
* Value, and Error information. * Value, and Error information.
*/ */
void CheckIsWritableProperty( void CheckIsWritableProperty(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
/* uint32_t object_instance, */ /* uint32_t object_instance, */
BACNET_PROPERTY_REFERENCE *rpm_property) BACNET_PROPERTY_REFERENCE *rpm_property)
{ {
@@ -439,9 +419,7 @@ void CheckIsWritableProperty(
fprintf(stdout, " Writable"); fprintf(stdout, " Writable");
} }
static const char *protocol_services_supported_text(size_t bit_index)
static const char *protocol_services_supported_text(
size_t bit_index)
{ {
bool is_confirmed = false; bool is_confirmed = false;
size_t text_index = 0; size_t text_index = 0;
@@ -475,8 +453,7 @@ static const char *protocol_services_supported_text(
* @return True if success. Or otherwise. * @return True if success. Or otherwise.
*/ */
bool PrettyPrintPropertyValue( bool PrettyPrintPropertyValue(FILE *stream,
FILE * stream,
BACNET_OBJECT_PROPERTY_VALUE *object_value) BACNET_OBJECT_PROPERTY_VALUE *object_value)
{ {
BACNET_APPLICATION_DATA_VALUE *value = NULL; BACNET_APPLICATION_DATA_VALUE *value = NULL;
@@ -493,13 +470,15 @@ bool PrettyPrintPropertyValue(
len = bitstring_bits_used(&value->type.Bit_String); len = bitstring_bits_used(&value->type.Bit_String);
fprintf(stream, "( \n "); fprintf(stream, "( \n ");
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
fprintf(stream, "%s", bitstring_bit(&value->type.Bit_String, fprintf(
(uint8_t) i) ? "T" : "F"); stream, "%s",
bitstring_bit(&value->type.Bit_String, (uint8_t)i) ? "T" : "F");
if (i < len - 1) if (i < len - 1)
fprintf(stream, ","); fprintf(stream, ",");
else else
fprintf(stream, " "); fprintf(stream, " ");
/* Tried with 8 per line, but with the comments, got way too long. */ /* Tried with 8 per line, but with the comments, got way too long.
*/
if ((i == (len - 1)) || ((i % 4) == 3)) { /* line break every 4 */ if ((i == (len - 1)) || ((i % 4) == 3)) { /* line break every 4 */
fprintf(stream, " -- "); /* EPICS comments begin with "--" */ fprintf(stream, " -- "); /* EPICS comments begin with "--" */
/* Now rerun the same 4 bits, but print labels for true ones */ /* Now rerun the same 4 bits, but print labels for true ones */
@@ -539,7 +518,6 @@ bool PrettyPrintPropertyValue(
return status; return status;
} }
/** Print out the value(s) for one Property. /** Print out the value(s) for one Property.
* This function may be called repeatedly for one property if we are walking * This function may be called repeatedly for one property if we are walking
* through a list (Using_Walked_List is True) to show just one value of the * through a list (Using_Walked_List is True) to show just one value of the
@@ -550,8 +528,7 @@ bool PrettyPrintPropertyValue(
* @param rpm_property [in] Points to structure holding the Property, * @param rpm_property [in] Points to structure holding the Property,
* Value, and Error information. * Value, and Error information.
*/ */
void PrintReadPropertyData( void PrintReadPropertyData(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_REFERENCE *rpm_property) BACNET_PROPERTY_REFERENCE *rpm_property)
{ {
@@ -577,7 +554,8 @@ void PrintReadPropertyData(
object_value.object_instance = object_instance; object_value.object_instance = object_instance;
if ((value != NULL) && (value->next != NULL)) { if ((value != NULL) && (value->next != NULL)) {
/* Then this is an array of values. /* Then this is an array of values.
* But are we showing Values? We (VTS3) want ? instead of {?,?} to show up. */ * But are we showing Values? We (VTS3) want ? instead of {?,?} to show
* up. */
switch (rpm_property->propertyIdentifier) { switch (rpm_property->propertyIdentifier) {
/* Screen the Properties that can be arrays or Sequences */ /* Screen the Properties that can be arrays or Sequences */
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
@@ -620,25 +598,28 @@ void PrintReadPropertyData(
if (Using_Walked_List) { if (Using_Walked_List) {
if ((rpm_property->propertyArrayIndex == 0) && if ((rpm_property->propertyArrayIndex == 0) &&
(value->tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)) { (value->tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)) {
/* Grab the value of the Object List length - don't print it! */ /* Grab the value of the Object List length - don't
* print it! */
Walked_List_Length = value->type.Unsigned_Int; Walked_List_Length = value->type.Unsigned_Int;
if (rpm_property->propertyIdentifier == if (rpm_property->propertyIdentifier ==
PROP_OBJECT_LIST) PROP_OBJECT_LIST)
Object_List_Length = value->type.Unsigned_Int; Object_List_Length = value->type.Unsigned_Int;
break; break;
} else } else
assert(Walked_List_Index == (uint32_t) assert(Walked_List_Index ==
rpm_property->propertyArrayIndex); (uint32_t)rpm_property->propertyArrayIndex);
} else { } else {
Walked_List_Index++; Walked_List_Index++;
/* If we got the whole Object List array in one RP call, keep /* If we got the whole Object List array in one RP call,
* the Index and List_Length in sync as we cycle through. */ * keep the Index and List_Length in sync as we cycle
* through. */
if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST) if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST)
Object_List_Length = ++Object_List_Index; Object_List_Length = ++Object_List_Index;
} }
if (Walked_List_Index == 1) { if (Walked_List_Index == 1) {
/* If the array is empty (nothing for this first entry), /* If the array is empty (nothing for this first entry),
* Make it VTS3-friendly and don't show "Null" as a value. */ * Make it VTS3-friendly and don't show "Null" as a value.
*/
if (value->tag == BACNET_APPLICATION_TAG_NULL) { if (value->tag == BACNET_APPLICATION_TAG_NULL) {
fprintf(stdout, "?\n "); fprintf(stdout, "?\n ");
break; break;
@@ -655,7 +636,10 @@ void PrintReadPropertyData(
if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST) { if (rpm_property->propertyIdentifier == PROP_OBJECT_LIST) {
if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) { if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) {
assert(value->tag == BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not right here */ assert(
value->tag ==
BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not
right here */
break; break;
} }
/* Store the object list so we can interrogate /* Store the object list so we can interrogate
@@ -666,9 +650,11 @@ void PrintReadPropertyData(
/* We don't have anything to put in the data pointer /* We don't have anything to put in the data pointer
* yet, so just leave it null. The key is Key here. */ * yet, so just leave it null. The key is Key here. */
Keylist_Data_Add(Object_List, object_list_element, NULL); Keylist_Data_Add(Object_List, object_list_element, NULL);
} else if (rpm_property->propertyIdentifier == PROP_STATE_TEXT) { } else if (rpm_property->propertyIdentifier ==
/* Make sure it fits within 31 chars for original VTS3 limitation. PROP_STATE_TEXT) {
* If longer, take first 15 dash, and last 15 chars. */ /* Make sure it fits within 31 chars for original VTS3
* limitation. If longer, take first 15 dash, and last 15
* chars. */
if (value->type.Character_String.length > 31) { if (value->type.Character_String.length > 31) {
int iLast15idx = int iLast15idx =
value->type.Character_String.length - 15; value->type.Character_String.length - 15;
@@ -682,14 +668,18 @@ void PrintReadPropertyData(
} else if (rpm_property->propertyIdentifier == } else if (rpm_property->propertyIdentifier ==
PROP_SUBORDINATE_LIST) { PROP_SUBORDINATE_LIST) {
if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) { if (value->tag != BACNET_APPLICATION_TAG_OBJECT_ID) {
assert(value->tag == BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not right here */ assert(
value->tag ==
BACNET_APPLICATION_TAG_OBJECT_ID); /* Something not
right here */
break; break;
} }
/* TODO: handle Sequence of { Device ObjID, Object ID }, */ /* TODO: handle Sequence of { Device ObjID, Object ID }, */
isSequence = true; isSequence = true;
} }
/* If the object is a Sequence, it needs its own bracketing braces */ /* If the object is a Sequence, it needs its own bracketing
* braces */
if (isSequence) if (isSequence)
fprintf(stdout, "{"); fprintf(stdout, "{");
bacapp_print_value(stdout, &object_value); bacapp_print_value(stdout, &object_value);
@@ -773,15 +763,13 @@ void PrintReadPropertyData(
value = value->next; /* next or NULL */ value = value->next; /* next or NULL */
free(old_value); free(old_value);
} /* End while loop */ } /* End while loop */
} }
/** Print the property identifier name to stdout, /** Print the property identifier name to stdout,
* handling the proprietary property numbers. * handling the proprietary property numbers.
* @param propertyIdentifier [in] The property identifier number. * @param propertyIdentifier [in] The property identifier number.
*/ */
static void Print_Property_Identifier( static void Print_Property_Identifier(unsigned propertyIdentifier)
unsigned propertyIdentifier)
{ {
if (propertyIdentifier < 512) { if (propertyIdentifier < 512) {
fprintf(stdout, "%s", bactext_property_name(propertyIdentifier)); fprintf(stdout, "%s", bactext_property_name(propertyIdentifier));
@@ -791,8 +779,7 @@ static void Print_Property_Identifier(
} }
/* Build a list of device properties to request with RPM. */ /* Build a list of device properties to request with RPM. */
static void BuildPropRequest( static void BuildPropRequest(BACNET_READ_ACCESS_DATA *rpm_object)
BACNET_READ_ACCESS_DATA * rpm_object)
{ {
int i; int i;
/* To start with, StartNextObject() has prepopulated one propEntry, /* To start with, StartNextObject() has prepopulated one propEntry,
@@ -824,8 +811,7 @@ static void BuildPropRequest(
* @return The invokeID of the message sent, or 0 if reached the end * @return The invokeID of the message sent, or 0 if reached the end
* of the property list. * of the property list.
*/ */
static uint8_t Read_Properties( static uint8_t Read_Properties(uint32_t device_instance,
uint32_t device_instance,
BACNET_OBJECT_ID *pMyObject) BACNET_OBJECT_ID *pMyObject)
{ {
uint8_t invoke_id = 0; uint8_t invoke_id = 0;
@@ -841,8 +827,7 @@ static uint8_t Read_Properties(
*/ */
property_list_special(pMyObject->type, &PropertyListStruct); property_list_special(pMyObject->type, &PropertyListStruct);
if (Optional_Properties) { if (Optional_Properties) {
Property_List_Length = Property_List_Length = PropertyListStruct.Required.count +
PropertyListStruct.Required.count +
PropertyListStruct.Optional.count; PropertyListStruct.Optional.count;
} else { } else {
Property_List_Length = PropertyListStruct.Required.count; Property_List_Length = PropertyListStruct.Required.count;
@@ -879,7 +864,8 @@ static uint8_t Read_Properties(
array_index = BACNET_ARRAY_ALL; array_index = BACNET_ARRAY_ALL;
switch (prop) { switch (prop) {
/* These are all potentially long arrays, so they may abort */ /* These are all potentially long arrays, so they may abort
*/
case PROP_OBJECT_LIST: case PROP_OBJECT_LIST:
case PROP_STATE_TEXT: case PROP_STATE_TEXT:
case PROP_STRUCTURED_OBJECT_LIST: case PROP_STRUCTURED_OBJECT_LIST:
@@ -892,7 +878,6 @@ static uint8_t Read_Properties(
invoke_id = invoke_id =
Send_Read_Property_Request(device_instance, pMyObject->type, Send_Read_Property_Request(device_instance, pMyObject->type,
pMyObject->instance, prop, array_index); pMyObject->instance, prop, array_index);
} }
return invoke_id; return invoke_id;
@@ -909,8 +894,7 @@ static uint8_t Read_Properties(
* if the RPM got good data, or GET_PROPERTY_REQUEST if we have to * if the RPM got good data, or GET_PROPERTY_REQUEST if we have to
* singly process the list of Properties. * singly process the list of Properties.
*/ */
EPICS_STATES ProcessRPMData( EPICS_STATES ProcessRPMData(BACNET_READ_ACCESS_DATA *rpm_data,
BACNET_READ_ACCESS_DATA * rpm_data,
EPICS_STATES myState) EPICS_STATES myState)
{ {
BACNET_READ_ACCESS_DATA *old_rpm_data; BACNET_READ_ACCESS_DATA *old_rpm_data;
@@ -1003,15 +987,18 @@ EPICS_STATES ProcessRPMData(
static void print_usage(char *filename) static void print_usage(char *filename)
{ {
printf("Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]" printf(
" device-instance\n", filename); "Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]"
" device-instance\n",
filename);
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
} }
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Generates Full EPICS file, including Object and Property List\n"); printf("Generates Full EPICS file, including Object and Property List\n");
printf("device-instance:\n" printf(
"device-instance:\n"
"BACnet Device Object Instance number that you are\n" "BACnet Device Object Instance number that you are\n"
"trying to communicate to. This number will be used\n" "trying to communicate to. This number will be used\n"
"to try and bind with the device using Who-Is and\n" "to try and bind with the device using Who-Is and\n"
@@ -1031,9 +1018,7 @@ static void print_help(char *filename)
printf("e.g., bacepics 2701876 > epics-2701876.tpi \n"); printf("e.g., bacepics 2701876 > epics-2701876.tpi \n");
} }
int CheckCommandLineArgs( int CheckCommandLineArgs(int argc, char *argv[])
int argc,
char *argv[])
{ {
int i; int i;
bool bFoundTarget = false; bool bFoundTarget = false;
@@ -1049,8 +1034,10 @@ int CheckCommandLineArgs(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
exit(0); exit(0);
@@ -1087,8 +1074,7 @@ int CheckCommandLineArgs(
fprintf(stderr, fprintf(stderr,
"Must provide a Target MAC before DNET \n"); "Must provide a Target MAC before DNET \n");
if (++i < argc) if (++i < argc)
Target_Address.net = Target_Address.net = (uint16_t)strtol(argv[i], NULL, 0);
(uint16_t) strtol(argv[i], NULL, 0);
/* Used strtol so dest.net can be either 0x1234 or 4660 */ /* Used strtol so dest.net can be either 0x1234 or 4660 */
break; break;
case 't': case 't':
@@ -1112,8 +1098,7 @@ int CheckCommandLineArgs(
Provided_Targ_MAC = true; Provided_Targ_MAC = true;
break; break;
} else } else
printf("ERROR: invalid Target MAC %s \n", printf("ERROR: invalid Target MAC %s \n", argv[i]);
argv[i]);
/* And fall through to print_usage */ /* And fall through to print_usage */
} }
/* Either break or fall through, as above */ /* Either break or fall through, as above */
@@ -1145,8 +1130,7 @@ int CheckCommandLineArgs(
return 0; /* All OK if we reach here */ return 0; /* All OK if we reach here */
} }
void PrintHeading( void PrintHeading()
)
{ {
BACNET_APPLICATION_DATA_VALUE *value = NULL; BACNET_APPLICATION_DATA_VALUE *value = NULL;
BACNET_OBJECT_PROPERTY_VALUE property_value; BACNET_OBJECT_PROPERTY_VALUE property_value;
@@ -1187,7 +1171,8 @@ void PrintHeading(
printf("Product Description: \"%s\"\n\n", printf("Product Description: \"%s\"\n\n",
characterstring_value(&value->type.Character_String)); characterstring_value(&value->type.Character_String));
} else { } else {
printf("Product Description: " printf(
"Product Description: "
"\"your product description here\"\n\n"); "\"your product description here\"\n\n");
} }
printf("BIBBs Supported:\n"); printf("BIBBs Supported:\n");
@@ -1217,8 +1202,8 @@ void PrintHeading(
printf("BACnet Standard Application Services Supported:\n"); printf("BACnet Standard Application Services Supported:\n");
printf("{\n"); printf("{\n");
value = object_property_value(PROP_PROTOCOL_SERVICES_SUPPORTED); value = object_property_value(PROP_PROTOCOL_SERVICES_SUPPORTED);
/* We have to process this bit string and determine which Object Types we have, /* We have to process this bit string and determine which Object Types we
* and show them * have, and show them
*/ */
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING)) { if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING)) {
int i, len = bitstring_bits_used(&value->type.Bit_String); int i, len = bitstring_bits_used(&value->type.Bit_String);
@@ -1251,8 +1236,7 @@ void PrintHeading(
printf("-- SubscribeCOVProperty Initiate Execute\n"); printf("-- SubscribeCOVProperty Initiate Execute\n");
#ifdef BAC_ROUTING #ifdef BAC_ROUTING
if (Target_Address.net == 0) { if (Target_Address.net == 0) {
printf printf("-- Note: The following Routing Services are Supported:\n");
("-- Note: The following Routing Services are Supported:\n");
printf("-- Who-Is-Router-To-Network Initiate Execute\n"); printf("-- Who-Is-Router-To-Network Initiate Execute\n");
printf("-- I-Am-Router-To-Network Initiate Execute\n"); printf("-- I-Am-Router-To-Network Initiate Execute\n");
printf("-- Initialize-Routing-Table Execute\n"); printf("-- Initialize-Routing-Table Execute\n");
@@ -1265,8 +1249,8 @@ void PrintHeading(
printf("Standard Object-Types Supported:\n"); printf("Standard Object-Types Supported:\n");
printf("{\n"); printf("{\n");
value = object_property_value(PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED); value = object_property_value(PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED);
/* We have to process this bit string and determine which Object Types we have, /* We have to process this bit string and determine which Object Types we
* and show them * have, and show them
*/ */
if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING)) { if ((value != NULL) && (value->tag == BACNET_APPLICATION_TAG_BIT_STRING)) {
int i, len = bitstring_bits_used(&value->type.Bit_String); int i, len = bitstring_bits_used(&value->type.Bit_String);
@@ -1360,8 +1344,12 @@ void PrintHeading(
printf("{\n"); printf("{\n");
printf(" unsigned-integer: <minimum: 0; maximum: 4294967295>\n"); printf(" unsigned-integer: <minimum: 0; maximum: 4294967295>\n");
printf(" signed-integer: <minimum: -2147483647; maximum: 2147483647>\n"); printf(" signed-integer: <minimum: -2147483647; maximum: 2147483647>\n");
printf(" real: <minimum: -3.40282347E38; maximum: 3.40282347E38; resolution: 1.0>\n"); printf(
printf(" double: <minimum: 2.2250738585072016E-38; maximum: 1.7976931348623157E38; resolution: 0.0001>\n"); " real: <minimum: -3.40282347E38; maximum: 3.40282347E38; resolution: "
"1.0>\n");
printf(
" double: <minimum: 2.2250738585072016E-38; maximum: "
"1.7976931348623157E38; resolution: 0.0001>\n");
printf(" date: <minimum: 01-January-1970; maximum: 31-December-2038>\n"); printf(" date: <minimum: 01-January-1970; maximum: 31-December-2038>\n");
printf(" octet-string: <maximum length string: 122>\n"); printf(" octet-string: <maximum length string: 122>\n");
printf(" character-string: <maximum length string: 122>\n"); printf(" character-string: <maximum length string: 122>\n");
@@ -1389,10 +1377,8 @@ void Print_Device_Heading(void)
printf(" {\n"); /* And opening brace for the first object */ printf(" {\n"); /* And opening brace for the first object */
} }
/* Initialize fields for a new Object */ /* Initialize fields for a new Object */
void StartNextObject( void StartNextObject(BACNET_READ_ACCESS_DATA *rpm_object,
BACNET_READ_ACCESS_DATA * rpm_object,
BACNET_OBJECT_ID *pNewObject) BACNET_OBJECT_ID *pNewObject)
{ {
BACNET_PROPERTY_REFERENCE *rpm_property; BACNET_PROPERTY_REFERENCE *rpm_property;
@@ -1417,12 +1403,11 @@ void StartNextObject(
* *
* *
* @param argc [in] Arg count. * @param argc [in] Arg count.
* @param argv [in] Takes one to four arguments, processed in CheckCommandLineArgs(). * @param argv [in] Takes one to four arguments, processed in
* CheckCommandLineArgs().
* @return 0 on success. * @return 0 on success.
*/ */
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
BACNET_ADDRESS src; /* address where message came from */ BACNET_ADDRESS src; /* address where message came from */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
@@ -1468,8 +1453,7 @@ int main(
} }
#endif #endif
/* try to bind with the target device */ /* try to bind with the target device */
found = found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
address_bind_request(Target_Device_Object_Instance, &max_apdu,
&Target_Address); &Target_Address);
if (!found) { if (!found) {
if (Provided_Targ_MAC) { if (Provided_Targ_MAC) {
@@ -1501,24 +1485,22 @@ int main(
current_seconds = time(NULL); current_seconds = time(NULL);
/* Has at least one second passed ? */ /* Has at least one second passed ? */
if (current_seconds != last_seconds) { if (current_seconds != last_seconds) {
tsm_timer_milliseconds((uint16_t) ((current_seconds - tsm_timer_milliseconds(
last_seconds) * 1000)); (uint16_t)((current_seconds - last_seconds) * 1000));
} }
/* OK to proceed; see what we are up to now */ /* OK to proceed; see what we are up to now */
switch (myState) { switch (myState) {
case INITIAL_BINDING: case INITIAL_BINDING:
/* returns 0 bytes on timeout */ /* returns 0 bytes on timeout */
pdu_len = pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process; normally is some initial error */ /* process; normally is some initial error */
if (pdu_len) { if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len); npdu_handler(&src, &Rx_Buf[0], pdu_len);
} }
/* will wait until the device is bound, or timeout and quit */ /* will wait until the device is bound, or timeout and quit */
found = found = address_bind_request(Target_Device_Object_Instance,
address_bind_request(Target_Device_Object_Instance,
&max_apdu, &Target_Address); &max_apdu, &Target_Address);
if (!found) { if (!found) {
/* increment timer - exit if timed out */ /* increment timer - exit if timed out */
@@ -1545,9 +1527,8 @@ int main(
last_seconds = current_seconds; last_seconds = current_seconds;
StartNextObject(rpm_object, &myObject); StartNextObject(rpm_object, &myObject);
BuildPropRequest(rpm_object); BuildPropRequest(rpm_object);
Request_Invoke_ID = Request_Invoke_ID = Send_Read_Property_Multiple_Request(
Send_Read_Property_Multiple_Request(buffer, MAX_PDU, buffer, MAX_PDU, Target_Device_Object_Instance, rpm_object);
Target_Device_Object_Instance, rpm_object);
if (Request_Invoke_ID > 0) { if (Request_Invoke_ID > 0) {
elapsed_seconds = 0; elapsed_seconds = 0;
} else { } else {
@@ -1575,9 +1556,8 @@ int main(
last_seconds = current_seconds; last_seconds = current_seconds;
StartNextObject(rpm_object, &myObject); StartNextObject(rpm_object, &myObject);
Request_Invoke_ID = Request_Invoke_ID = Send_Read_Property_Multiple_Request(
Send_Read_Property_Multiple_Request(buffer, MAX_PDU, buffer, MAX_PDU, Target_Device_Object_Instance, rpm_object);
Target_Device_Object_Instance, rpm_object);
if (Request_Invoke_ID > 0) { if (Request_Invoke_ID > 0) {
elapsed_seconds = 0; elapsed_seconds = 0;
if (myState == GET_LIST_OF_ALL_REQUEST) if (myState == GET_LIST_OF_ALL_REQUEST)
@@ -1591,8 +1571,7 @@ int main(
case GET_ALL_RESPONSE: case GET_ALL_RESPONSE:
case GET_LIST_OF_ALL_RESPONSE: case GET_LIST_OF_ALL_RESPONSE:
/* returns 0 bytes on timeout */ /* returns 0 bytes on timeout */
pdu_len = pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */ /* process */
if (pdu_len) { if (pdu_len) {
@@ -1603,9 +1582,8 @@ int main(
(Request_Invoke_ID == (Request_Invoke_ID ==
Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.service_data.invoke_id)) {
Read_Property_Multiple_Data.new_data = false; Read_Property_Multiple_Data.new_data = false;
myState = myState = ProcessRPMData(
ProcessRPMData(Read_Property_Multiple_Data.rpm_data, Read_Property_Multiple_Data.rpm_data, myState);
myState);
if (tsm_invoke_id_free(Request_Invoke_ID)) { if (tsm_invoke_id_free(Request_Invoke_ID)) {
Request_Invoke_ID = 0; Request_Invoke_ID = 0;
} else { } else {
@@ -1626,7 +1604,8 @@ int main(
/* Was it because the Device can't do RPM? */ /* Was it because the Device can't do RPM? */
Has_RPM = false; Has_RPM = false;
myState = GET_PROPERTY_REQUEST; myState = GET_PROPERTY_REQUEST;
} else if (Last_Error_Code == } else if (
Last_Error_Code ==
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) { ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED) {
myState = GET_PROPERTY_REQUEST; myState = GET_PROPERTY_REQUEST;
StartNextObject(rpm_object, &myObject); StartNextObject(rpm_object, &myObject);
@@ -1660,7 +1639,8 @@ int main(
myState = PRINT_HEADING; myState = PRINT_HEADING;
/* just press ahead without the data */ /* just press ahead without the data */
else else
myState = NEXT_OBJECT; /* Give up and move on to the next. */ myState =
NEXT_OBJECT; /* Give up and move on to the next. */
Error_Count++; Error_Count++;
} }
break; break;
@@ -1683,8 +1663,7 @@ int main(
case GET_PROPERTY_RESPONSE: case GET_PROPERTY_RESPONSE:
/* returns 0 bytes on timeout */ /* returns 0 bytes on timeout */
pdu_len = pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
/* process */ /* process */
if (pdu_len) { if (pdu_len) {
@@ -1695,11 +1674,10 @@ int main(
(Request_Invoke_ID == (Request_Invoke_ID ==
Read_Property_Multiple_Data.service_data.invoke_id)) { Read_Property_Multiple_Data.service_data.invoke_id)) {
Read_Property_Multiple_Data.new_data = false; Read_Property_Multiple_Data.new_data = false;
PrintReadPropertyData(Read_Property_Multiple_Data. PrintReadPropertyData(
rpm_data->object_type, Read_Property_Multiple_Data.rpm_data->object_type,
Read_Property_Multiple_Data.rpm_data->object_instance, Read_Property_Multiple_Data.rpm_data->object_instance,
Read_Property_Multiple_Data.rpm_data-> Read_Property_Multiple_Data.rpm_data->listOfProperties);
listOfProperties);
if (tsm_invoke_id_free(Request_Invoke_ID)) { if (tsm_invoke_id_free(Request_Invoke_ID)) {
Request_Invoke_ID = 0; Request_Invoke_ID = 0;
} else { } else {
@@ -1727,14 +1705,16 @@ int main(
if ((Last_Error_Class != ERROR_CLASS_PROPERTY) && if ((Last_Error_Class != ERROR_CLASS_PROPERTY) &&
(Last_Error_Code != ERROR_CODE_UNKNOWN_PROPERTY)) { (Last_Error_Code != ERROR_CODE_UNKNOWN_PROPERTY)) {
if (IsLongArray) { if (IsLongArray) {
/* Change to using a Walked List and retry this property */ /* Change to using a Walked List and retry this
* property */
Using_Walked_List = true; Using_Walked_List = true;
Walked_List_Index = Walked_List_Length = 0; Walked_List_Index = Walked_List_Length = 0;
} else { } else {
/* OK, skip this one and try the next property. */ /* OK, skip this one and try the next property.
*/
fprintf(stdout, " -- Failed to get "); fprintf(stdout, " -- Failed to get ");
Print_Property_Identifier(Property_List Print_Property_Identifier(
[Property_List_Index]); Property_List[Property_List_Index]);
fprintf(stdout, " \n"); fprintf(stdout, " \n");
Error_Count++; Error_Count++;
Property_List_Index++; Property_List_Index++;
@@ -1764,7 +1744,8 @@ int main(
/* Don't think we'll ever actually reach this point. */ /* Don't think we'll ever actually reach this point. */
elapsed_seconds = 0; elapsed_seconds = 0;
Request_Invoke_ID = 0; Request_Invoke_ID = 0;
myState = NEXT_OBJECT; /* Give up and move on to the next. */ myState =
NEXT_OBJECT; /* Give up and move on to the next. */
Error_Count++; Error_Count++;
} }
break; break;
@@ -1777,12 +1758,14 @@ int main(
if (ShowDeviceObjectOnly) { if (ShowDeviceObjectOnly) {
/* Closing brace for the Device Object */ /* Closing brace for the Device Object */
printf(" }, \n"); printf(" }, \n");
/* done with all Objects, signal end of this while loop */ /* done with all Objects, signal end of this while loop
*/
myObject.type = MAX_BACNET_OBJECT_TYPE; myObject.type = MAX_BACNET_OBJECT_TYPE;
break; break;
} }
} }
/* Advance to the next object, as long as it's not the Device object */ /* Advance to the next object, as long as it's not the Device
* object */
do { do {
Object_List_Index++; Object_List_Index++;
if (Object_List_Index < Keylist_Count(Object_List)) { if (Object_List_Index < Keylist_Count(Object_List)) {
@@ -1798,12 +1781,14 @@ int main(
printf(" { \n"); printf(" { \n");
/* Test code: /* Test code:
if ( myObject.type == OBJECT_STRUCTURED_VIEW ) if ( myObject.type == OBJECT_STRUCTURED_VIEW )
printf( " -- Structured View %d \n", myObject.instance ); printf( " -- Structured View %d \n",
myObject.instance );
*/ */
} else { } else {
/* Closing brace for the last Object */ /* Closing brace for the last Object */
printf(" } \n"); printf(" } \n");
/* done with all Objects, signal end of this while loop */ /* done with all Objects, signal end of this while loop
*/
myObject.type = MAX_BACNET_OBJECT_TYPE; myObject.type = MAX_BACNET_OBJECT_TYPE;
} }
if (Has_RPM) if (Has_RPM)
@@ -1814,7 +1799,8 @@ int main(
} }
} while (myObject.type == OBJECT_DEVICE); } while (myObject.type == OBJECT_DEVICE);
/* Else, don't re-do the Device Object; move to the next object. */ /* Else, don't re-do the Device Object; move to the next object.
*/
break; break;
default: default:
@@ -1841,8 +1827,7 @@ int main(
/* Closing brace for all Objects, if we got any, and closing footer */ /* Closing brace for all Objects, if we got any, and closing footer */
if (myState != INITIAL_BINDING) { if (myState != INITIAL_BINDING) {
printf("} \n"); printf("} \n");
printf printf("End of BACnet Protocol Implementation Conformance Statement\n");
("End of BACnet Protocol Implementation Conformance Statement\n");
printf("\n"); printf("\n");
} }
+18 -25
View File
@@ -55,11 +55,8 @@ static uint16_t Target_Service = SERVICE_CONFIRMED_READ_PROPERTY;
/* flag for signalling errors */ /* flag for signalling errors */
static bool Error_Detected = false; static bool Error_Detected = false;
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -68,9 +65,7 @@ void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
(void)src; (void)src;
@@ -79,8 +74,7 @@ void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
/* we need to handle who-is /* we need to handle who-is
@@ -88,8 +82,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -111,7 +104,8 @@ static void print_usage(char *filename)
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Send BACnet Error message to the network.\n"); printf("Send BACnet Error message to the network.\n");
printf("--mac A\n" printf(
"--mac A\n"
"Optional destination BACnet mac address." "Optional destination BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
@@ -123,12 +117,14 @@ static void print_help(char *filename)
"and 65535 is network broadcast.\n" "and 65535 is network broadcast.\n"
"\n" "\n"
"--dadr A\n" "--dadr A\n"
"Optional BACnet mac address on the destination BACnet network number.\n" "Optional BACnet mac address on the destination BACnet network "
"number.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
"\n"); "\n");
printf("error-class:\n" printf(
"error-class:\n"
" number from 0 to 65535\n" " number from 0 to 65535\n"
"error-code:\n" "error-code:\n"
" number from 0 to 65535\n" " number from 0 to 65535\n"
@@ -141,9 +137,7 @@ static void print_help(char *filename)
filename); filename);
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
long dnet = -1; long dnet = -1;
BACNET_MAC_ADDRESS mac = {0}; BACNET_MAC_ADDRESS mac = {0};
@@ -163,8 +157,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2016 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2016 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0; return 0;
@@ -245,11 +241,8 @@ int main(
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
/* send the request */ /* send the request */
Send_Error_To_Network(&Handler_Transmit_Buffer[0], Send_Error_To_Network(&Handler_Transmit_Buffer[0], &dest, Target_Invoke_ID,
&dest, Target_Service, Target_Error_Class,
Target_Invoke_ID,
Target_Service,
Target_Error_Class,
Target_Error_Code); Target_Error_Code);
return 0; return 0;
+15 -25
View File
@@ -60,7 +60,8 @@
#include "vmac.h" #include "vmac.h"
#endif #endif
/** @file gateway/main.c Example virtual gateway application using the BACnet Stack. */ /** @file gateway/main.c Example virtual gateway application using the BACnet
* Stack. */
/* Prototypes */ /* Prototypes */
@@ -79,14 +80,11 @@ int DNET_list[2] = {
VIRTUAL_DNET, -1 /* Need -1 terminator */ VIRTUAL_DNET, -1 /* Need -1 terminator */
}; };
/** Initialize the Device Objects and each of the child Object instances. /** Initialize the Device Objects and each of the child Object instances.
* @param first_object_instance Set the first (gateway) Device to this * @param first_object_instance Set the first (gateway) Device to this
instance number, and subsequent devices to incremented values. instance number, and subsequent devices to incremented values.
*/ */
static void Devices_Init( static void Devices_Init(uint32_t first_object_instance)
uint32_t first_object_instance)
{ {
int i; int i;
char nameText[MAX_DEV_NAME_LEN]; char nameText[MAX_DEV_NAME_LEN];
@@ -95,8 +93,7 @@ static void Devices_Init(
/* Gateway Device has already been initialized. /* Gateway Device has already been initialized.
* But give it a better Description. */ * But give it a better Description. */
Routed_Device_Set_Description(DEV_DESCR_GATEWAY, Routed_Device_Set_Description(DEV_DESCR_GATEWAY, strlen(DEV_DESCR_GATEWAY));
strlen(DEV_DESCR_GATEWAY));
/* Now initialize the remote Device objects. */ /* Now initialize the remote Device objects. */
for (i = 1; i < MAX_NUM_DEVICES; i++) { for (i = 1; i < MAX_NUM_DEVICES; i++) {
@@ -111,15 +108,12 @@ static void Devices_Init(
Add_Routed_Device((first_object_instance + i), &name_string, descText); Add_Routed_Device((first_object_instance + i), &name_string, descText);
} }
} }
/** Initialize the handlers we will utilize. /** Initialize the handlers we will utilize.
* @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler * @see Device_Init, apdu_set_unconfirmed_handler, apdu_set_confirmed_handler
*/ */
static void Init_Service_Handlers( static void Init_Service_Handlers(uint32_t first_object_instance)
uint32_t first_object_instance)
{ {
Device_Init(NULL); Device_Init(NULL);
Routing_Device_Init(first_object_instance); Routing_Device_Init(first_object_instance);
@@ -135,8 +129,7 @@ static void Init_Service_Handlers(
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has); apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* set the handler for all the services we don't implement */ /* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */ /* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* Set the handlers for any confirmed services that we support. */ /* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */ /* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
@@ -176,8 +169,7 @@ static void Init_Service_Handlers(
* device.) This is sure to be unique! The port number stays the same. * device.) This is sure to be unique! The port number stays the same.
* - For MS/TP, [Steve inserts a good idea here] * - For MS/TP, [Steve inserts a good idea here]
*/ */
static void Initialize_Device_Addresses( static void Initialize_Device_Addresses()
)
{ {
int i = 0; /* First entry is Gateway Device */ int i = 0; /* First entry is Gateway Device */
uint32_t virtual_mac = 0; uint32_t virtual_mac = 0;
@@ -239,7 +231,6 @@ static void Initialize_Device_Addresses(
#endif #endif
/* broadcast an I-Am for each routed Device now */ /* broadcast an I-Am for each routed Device now */
Send_I_Am(&Handler_Transmit_Buffer[0]); Send_I_Am(&Handler_Transmit_Buffer[0]);
} }
} }
@@ -255,13 +246,9 @@ static void Initialize_Device_Addresses(
* @param argv [in] Takes one argument: the Device Instance #. * @param argv [in] Takes one argument: the Device Instance #.
* @return 0 on success. * @return 0 on success.
*/ */
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
BACNET_ADDRESS src = { BACNET_ADDRESS src = {0}; /* address where message came from */
0
}; /* address where message came from */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
unsigned timeout = 1000; /* milliseconds */ unsigned timeout = 1000; /* milliseconds */
time_t last_seconds = 0; time_t last_seconds = 0;
@@ -286,9 +273,12 @@ int main(
exit(1); exit(1);
} }
} }
printf("BACnet Router Demo\n" "BACnet Stack Version %s\n" printf(
"BACnet Device ID: %u\n" "Max APDU: %d\n", BACnet_Version, "BACnet Router Demo\n"
first_object_instance, MAX_APDU); "BACnet Stack Version %s\n"
"BACnet Device ID: %u\n"
"Max APDU: %d\n",
BACnet_Version, first_object_instance, MAX_APDU);
Init_Service_Handlers(first_object_instance); Init_Service_Handlers(first_object_instance);
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
+35 -34
View File
@@ -73,9 +73,7 @@ static bool Recieved_Ack = false;
static bool More_Events = false; static bool More_Events = false;
static BACNET_OBJECT_ID LastReceivedObjectIdentifier; static BACNET_OBJECT_ID LastReceivedObjectIdentifier;
static void MyErrorHandler( static void MyErrorHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
@@ -88,11 +86,8 @@ static void MyErrorHandler(
} }
} }
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
(void)server; (void)server;
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
@@ -103,9 +98,7 @@ void MyAbortHandler(
} }
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
if (address_match(&Target_Address, src) && if (address_match(&Target_Address, src) &&
@@ -126,9 +119,7 @@ void MyRejectHandler(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void My_Get_Event_Ack_Handler( void My_Get_Event_Ack_Handler(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
@@ -138,19 +129,20 @@ void My_Get_Event_Ack_Handler(
for (i = 0; i < MAX_OBJ_IDS_IN_GE_ACK - 1; i++) for (i = 0; i < MAX_OBJ_IDS_IN_GE_ACK - 1; i++)
data[i].next = &data[i + 1]; data[i].next = &data[i + 1];
printf("Recieved Ack. Saved invoke ID was %i, service returned %i\n", Request_Invoke_ID, service_data->invoke_id); printf("Recieved Ack. Saved invoke ID was %i, service returned %i\n",
Request_Invoke_ID, service_data->invoke_id);
if (service_data->invoke_id == Request_Invoke_ID) { if (service_data->invoke_id == Request_Invoke_ID) {
len = getevent_ack_decode_service_request(service_request, len = getevent_ack_decode_service_request(service_request, service_len,
service_len, &data[0], &More_Events);
&data[0], printf("Decode of Ack returned length %i. MoreEvents flag was %i \n",
&More_Events); len, More_Events);
printf("Decode of Ack returned length %i. MoreEvents flag was %i \n", len, More_Events);
if (len > 0) { if (len > 0) {
ge_ack_print_data(&(data[0]), Target_Device_Object_Instance); ge_ack_print_data(&(data[0]), Target_Device_Object_Instance);
if (More_Events) { if (More_Events) {
BACNET_GET_EVENT_INFORMATION_DATA *lastData = &(data[0]); BACNET_GET_EVENT_INFORMATION_DATA *lastData = &(data[0]);
while (lastData->next) lastData = lastData->next; while (lastData->next)
lastData = lastData->next;
LastReceivedObjectIdentifier = lastData->objectIdentifier; LastReceivedObjectIdentifier = lastData->objectIdentifier;
} }
} }
@@ -181,10 +173,17 @@ static void Init_Service_Handlers(void)
apdu_set_reject_handler(MyRejectHandler); apdu_set_reject_handler(MyRejectHandler);
} }
static int print_help(char *exe_name){ static int print_help(char *exe_name)
printf("Usage:\n" "\n" "%s device-instance [--help]\n" "\n" {
" Send BACnet GetEventInformation service retruequest to given device, and wait\n" printf(
" for responses.\n\n", exe_name); "Usage:\n"
"\n"
"%s device-instance [--help]\n"
"\n"
" Send BACnet GetEventInformation service retruequest to given "
"device, and wait\n"
" for responses.\n\n",
exe_name);
return 1; return 1;
} }
@@ -221,11 +220,11 @@ int main(int argc, char *argv[])
last_seconds = time(NULL); last_seconds = time(NULL);
timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries();
/* try to bind with the device */ /* try to bind with the device */
found = address_bind_request(Target_Device_Object_Instance, found = address_bind_request(Target_Device_Object_Instance, &max_apdu,
&max_apdu,
&Target_Address); &Target_Address);
if (!found) { if (!found) {
Send_WhoIs(Target_Device_Object_Instance, Target_Device_Object_Instance); Send_WhoIs(Target_Device_Object_Instance,
Target_Device_Object_Instance);
} }
/* loop forever */ /* loop forever */
for (;;) { for (;;) {
@@ -234,14 +233,16 @@ int main(int argc, char *argv[])
/* at least one second has passed */ /* at least one second has passed */
if (current_seconds != last_seconds) if (current_seconds != last_seconds)
tsm_timer_milliseconds((uint16_t) ((current_seconds - last_seconds) * 1000)); tsm_timer_milliseconds(
(uint16_t)((current_seconds - last_seconds) * 1000));
if (Error_Detected){break;} if (Error_Detected) {
break;
}
/* wait until the device is bound, or timeout and quit */ /* wait until the device is bound, or timeout and quit */
if (!found) { if (!found) {
found = address_bind_request(Target_Device_Object_Instance, found = address_bind_request(Target_Device_Object_Instance,
&max_apdu, &max_apdu, &Target_Address);
&Target_Address);
} }
if (found) { if (found) {
if (Request_Invoke_ID == 0) { if (Request_Invoke_ID == 0) {
@@ -249,8 +250,8 @@ int main(int argc, char *argv[])
Request_Invoke_ID = Send_GetEvent(&Target_Address, NULL); Request_Invoke_ID = Send_GetEvent(&Target_Address, NULL);
} else if (More_Events) { } else if (More_Events) {
printf("\nSending another GetEventInformation request ...\n"); printf("\nSending another GetEventInformation request ...\n");
Request_Invoke_ID = Send_GetEvent(&Target_Address, Request_Invoke_ID = Send_GetEvent(
&LastReceivedObjectIdentifier); &Target_Address, &LastReceivedObjectIdentifier);
More_Events = false; More_Events = false;
} else if (tsm_invoke_id_free(Request_Invoke_ID)) { } else if (tsm_invoke_id_free(Request_Invoke_ID)) {
if (Recieved_Ack) { if (Recieved_Ack) {
+14 -24
View File
@@ -52,7 +52,6 @@ static long bbmd_mask = 0xFFFFFFFF;
static int bbmd_result = 0; static int bbmd_result = 0;
static BBMD_TABLE_ENTRY BBMD_Table_Entry; static BBMD_TABLE_ENTRY BBMD_Table_Entry;
/* Simple setters for BBMD registration variables. */ /* Simple setters for BBMD registration variables. */
/** Sets the IPv4 address for BBMD registration. /** Sets the IPv4 address for BBMD registration.
@@ -61,8 +60,7 @@ static BBMD_TABLE_ENTRY BBMD_Table_Entry;
* @param address - IPv4 address (long) of BBMD to register with, * @param address - IPv4 address (long) of BBMD to register with,
* in network byte order. * in network byte order.
*/ */
void dlenv_bbmd_address_set( void dlenv_bbmd_address_set(long address)
long address)
{ {
bbmd_address = address; bbmd_address = address;
} }
@@ -71,8 +69,7 @@ void dlenv_bbmd_address_set(
* Default if not set is 0xBAC0. * Default if not set is 0xBAC0.
* @param port - The port number (provided in network byte order). * @param port - The port number (provided in network byte order).
*/ */
void dlenv_bbmd_port_set( void dlenv_bbmd_port_set(int port)
int port)
{ {
bbmd_port = port; bbmd_port = port;
} }
@@ -81,8 +78,7 @@ void dlenv_bbmd_port_set(
* Default if not set is 60000 (1000 minutes). * Default if not set is 60000 (1000 minutes).
* @param ttl_secs - The Lease Time, in seconds. * @param ttl_secs - The Lease Time, in seconds.
*/ */
void dlenv_bbmd_ttl_set( void dlenv_bbmd_ttl_set(int ttl_secs)
int ttl_secs)
{ {
bbmd_timetolive_seconds = ttl_secs; bbmd_timetolive_seconds = ttl_secs;
} }
@@ -95,8 +91,7 @@ void dlenv_bbmd_ttl_set(
* 0 if no registration request was made, or * 0 if no registration request was made, or
* -1 if registration attempt failed. * -1 if registration attempt failed.
*/ */
int dlenv_bbmd_result( int dlenv_bbmd_result(void)
void)
{ {
if ((bbmd_result > 0) && if ((bbmd_result > 0) &&
(bvlc_get_last_result() == BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK)) (bvlc_get_last_result() == BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK))
@@ -120,8 +115,7 @@ int dlenv_bbmd_result(
* 0 if no registration request is sent, or * 0 if no registration request is sent, or
* -1 if registration fails. * -1 if registration fails.
*/ */
int dlenv_register_as_foreign_device( int dlenv_register_as_foreign_device(void)
void)
{ {
int retval = 0; int retval = 0;
#if defined(BACDL_BIP) #if defined(BACDL_BIP)
@@ -188,11 +182,11 @@ int dlenv_register_as_foreign_device(
sprintf(bbmd_env, "BACNET_BDT_MASK_%u", entry_number); sprintf(bbmd_env, "BACNET_BDT_MASK_%u", entry_number);
pEnv = getenv(bbmd_env); pEnv = getenv(bbmd_env);
if (pEnv) { if (pEnv) {
c = sscanf(pEnv, "%3u.%3u.%3u.%3u", c = sscanf(pEnv, "%3u.%3u.%3u.%3u", &a[0], &a[1], &a[2],
&a[0],&a[1],&a[2],&a[3]); &a[3]);
if (c == 4) { if (c == 4) {
bbmd_mask = bbmd_mask = ((a[0] & 0xFF) << 24) |
((a[0]&0xFF)<<24)|((a[1]&0xFF)<<16)| ((a[1] & 0xFF) << 16) |
((a[2] & 0xFF) << 8) | (a[3] & 0xFF); ((a[2] & 0xFF) << 8) | (a[3] & 0xFF);
} }
} }
@@ -331,8 +325,7 @@ static void dlenv_network_port_init(void)
* Call this function to renew our Foreign Device Registration * Call this function to renew our Foreign Device Registration
* @param elapsed_seconds Number of seconds that have elapsed since last called. * @param elapsed_seconds Number of seconds that have elapsed since last called.
*/ */
void dlenv_maintenance_timer( void dlenv_maintenance_timer(uint16_t elapsed_seconds)
uint16_t elapsed_seconds)
{ {
#if defined(BACDL_BIP) #if defined(BACDL_BIP)
if (BBMD_Timer_Seconds) { if (BBMD_Timer_Seconds) {
@@ -402,8 +395,7 @@ void dlenv_maintenance_timer(
* communications. Default is 47808 (0xBAC0). * communications. Default is 47808 (0xBAC0).
* - BACNET_BIP6_BROADCAST - FF05::BAC0 or FF02::BAC0 or ... * - BACNET_BIP6_BROADCAST - FF05::BAC0 or FF02::BAC0 or ...
*/ */
void dlenv_init( void dlenv_init(void)
void)
{ {
char *pEnv = NULL; char *pEnv = NULL;
@@ -419,13 +411,11 @@ void dlenv_init(
BACNET_IP6_ADDRESS addr; BACNET_IP6_ADDRESS addr;
pEnv = getenv("BACNET_BIP6_BROADCAST"); pEnv = getenv("BACNET_BIP6_BROADCAST");
if (pEnv) { if (pEnv) {
bvlc6_address_set(&addr, bvlc6_address_set(&addr, (uint16_t)strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0,
(uint16_t) strtol(pEnv, NULL, 0), 0, 0, 0, 0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID);
BIP6_MULTICAST_GROUP_ID);
bip6_set_broadcast_addr(&addr); bip6_set_broadcast_addr(&addr);
} else { } else {
bvlc6_address_set(&addr, bvlc6_address_set(&addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID); BIP6_MULTICAST_GROUP_ID);
bip6_set_broadcast_addr(&addr); bip6_set_broadcast_addr(&addr);
} }
+40 -48
View File
@@ -42,13 +42,11 @@
#include "handlers.h" #include "handlers.h"
#include "device.h" #include "device.h"
/** @file h_alarm_ack.c Handles Alarm Acknowledgment. */ /** @file h_alarm_ack.c Handles Alarm Acknowledgment. */
static alarm_ack_function Alarm_Ack[MAX_BACNET_OBJECT_TYPE]; static alarm_ack_function Alarm_Ack[MAX_BACNET_OBJECT_TYPE];
void handler_alarm_ack_set( void handler_alarm_ack_set(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
alarm_ack_function pFunction) alarm_ack_function pFunction)
{ {
if (object_type < MAX_BACNET_OBJECT_TYPE) { if (object_type < MAX_BACNET_OBJECT_TYPE) {
@@ -72,9 +70,7 @@ void handler_alarm_ack_set(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_alarm_ack( void handler_alarm_ack(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -90,32 +86,29 @@ void handler_alarm_ack(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Alarm Ack: Segmented message. Sending Abort!\n"); fprintf(stderr, "Alarm Ack: Segmented message. Sending Abort!\n");
#endif #endif
goto AA_ABORT; goto AA_ABORT;
} }
len = len = alarm_ack_decode_service_request(service_request, service_len, &data);
alarm_ack_decode_service_request(service_request, service_len, &data);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len <= 0) if (len <= 0)
fprintf(stderr, "Alarm Ack: Unable to decode Request!\n"); fprintf(stderr, "Alarm Ack: Unable to decode Request!\n");
#endif #endif
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Alarm Ack: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "Alarm Ack: Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -123,7 +116,8 @@ void handler_alarm_ack(
} }
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"Alarm Ack Operation: Received acknowledge for object id (%d, %lu) from %s for process id %lu \n", "Alarm Ack Operation: Received acknowledge for object id (%d, %lu) "
"from %s for process id %lu \n",
data.eventObjectIdentifier.type, data.eventObjectIdentifier.type,
(unsigned long)data.eventObjectIdentifier.instance, (unsigned long)data.eventObjectIdentifier.instance,
data.ackSource.value, (unsigned long)data.ackProcessIdentifier); data.ackSource.value, (unsigned long)data.ackProcessIdentifier);
@@ -131,38 +125,36 @@ void handler_alarm_ack(
/* BACnet Testing Observed Incident oi00105 /* BACnet Testing Observed Incident oi00105
ACK of a non-existent object returned the incorrect error code ACK of a non-existent object returned the incorrect error code
Revealed by BACnet Test Client v1.8.16 ( www.bac-test.com/bacnet-test-client-download ) Revealed by BACnet Test Client v1.8.16 (
BC 135.1: 9.1.3.3-A www.bac-test.com/bacnet-test-client-download ) BC 135.1: 9.1.3.3-A Any
Any discussions can be directed to edward@bac-test.com */ discussions can be directed to edward@bac-test.com */
if (!Device_Valid_Object_Id(data.eventObjectIdentifier.type, data.eventObjectIdentifier.instance)) if (!Device_Valid_Object_Id(data.eventObjectIdentifier.type,
{ data.eventObjectIdentifier.instance)) {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT, ERROR_CODE_UNKNOWN_OBJECT); ERROR_CODE_UNKNOWN_OBJECT);
} } else if (Alarm_Ack[data.eventObjectIdentifier.type]) {
else if (Alarm_Ack[data.eventObjectIdentifier.type]) {
ack_result = ack_result =
Alarm_Ack[data.eventObjectIdentifier.type](&data, &error_code); Alarm_Ack[data.eventObjectIdentifier.type](&data, &error_code);
switch (ack_result) { switch (ack_result) {
case 1: case 1:
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM); SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: " "Sending Simple Ack!\n"); fprintf(stderr,
"Alarm Acknowledge: "
"Sending Simple Ack!\n");
#endif #endif
break; break;
case -1: case -1:
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM,
error_code); ERROR_CLASS_OBJECT, error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: error %s!\n", fprintf(stderr, "Alarm Acknowledge: error %s!\n",
bactext_error_code_name(error_code)); bactext_error_code_name(error_code));
@@ -170,34 +162,34 @@ void handler_alarm_ack(
break; break;
default: default:
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_OTHER, true); ABORT_REASON_OTHER, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: abort other!\n"); fprintf(stderr, "Alarm Acknowledge: abort other!\n");
#endif #endif
break; break;
} }
} else { } else {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, SERVICE_CONFIRMED_ACKNOWLEDGE_ALARM, ERROR_CLASS_OBJECT,
ERROR_CLASS_OBJECT, ERROR_CODE_NO_ALARM_CONFIGURED); ERROR_CODE_NO_ALARM_CONFIGURED);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Alarm Acknowledge: error %s!\n", fprintf(stderr, "Alarm Acknowledge: error %s!\n",
bactext_error_code_name(ERROR_CODE_NO_ALARM_CONFIGURED)); bactext_error_code_name(ERROR_CODE_NO_ALARM_CONFIGURED));
#endif #endif
} }
AA_ABORT: AA_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Alarm Acknowledge: " "Failed to send PDU (%s)!\n", fprintf(stderr,
"Alarm Acknowledge: "
"Failed to send PDU (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
+16 -25
View File
@@ -96,9 +96,7 @@ shall be TRUE, otherwise FALSE.
*/ */
#if defined(BACFILE) #if defined(BACFILE)
void handler_atomic_read_file( void handler_atomic_read_file(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -118,14 +116,12 @@ void handler_atomic_read_file(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "ARF: Segmented Message. Sending Abort!\n"); fprintf(stderr, "ARF: Segmented Message. Sending Abort!\n");
#endif #endif
@@ -134,9 +130,9 @@ void handler_atomic_read_file(
len = arf_decode_service_request(service_request, service_len, &data); len = arf_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */ /* bad decoding - send an abort */
if (len < 0) { if (len < 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Bad Encoding. Sending Abort!\n"); fprintf(stderr, "Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -154,13 +150,11 @@ void handler_atomic_read_file(
data.type.stream.fileStartPosition, data.type.stream.fileStartPosition,
data.type.stream.requestedOctetCount); data.type.stream.requestedOctetCount);
#endif #endif
len = len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
} else { } else {
len = len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Too Big To Send (%d >= %d). Sending Abort!\n", fprintf(stderr, "Too Big To Send (%d >= %d). Sending Abort!\n",
@@ -180,8 +174,7 @@ void handler_atomic_read_file(
data.type.record.fileStartRecord, data.type.record.fileStartRecord,
data.type.record.RecordCount); data.type.record.RecordCount);
#endif #endif
len = len = arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
arf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
} else { } else {
error = true; error = true;
@@ -202,15 +195,13 @@ void handler_atomic_read_file(
error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE; error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE;
} }
if (error) { if (error) {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_READ_FILE, SERVICE_CONFIRMED_ATOMIC_READ_FILE, error_class, error_code);
error_class, error_code);
} }
ARF_ABORT: ARF_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
+1 -3
View File
@@ -51,9 +51,7 @@
/* use the description as the file name. */ /* use the description as the file name. */
#if defined(BACFILE) #if defined(BACFILE)
void handler_atomic_read_file_ack( void handler_atomic_read_file_ack(
uint8_t * service_request, uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data)
{ {
int len = 0; int len = 0;
+14 -22
View File
@@ -76,9 +76,7 @@ standard.
*/ */
#if defined(BACFILE) #if defined(BACFILE)
void handler_atomic_write_file( void handler_atomic_write_file(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -98,14 +96,12 @@ void handler_atomic_write_file(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Segmented Message. Sending Abort!\n"); fprintf(stderr, "Segmented Message. Sending Abort!\n");
#endif #endif
@@ -114,9 +110,9 @@ void handler_atomic_write_file(
len = awf_decode_service_request(service_request, service_len, &data); len = awf_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */ /* bad decoding - send an abort */
if (len < 0) { if (len < 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Bad Encoding. Sending Abort!\n"); fprintf(stderr, "Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -132,8 +128,7 @@ void handler_atomic_write_file(
data.type.stream.fileStartPosition, data.type.stream.fileStartPosition,
(int)octetstring_length(&data.fileData[0])); (int)octetstring_length(&data.fileData[0]));
#endif #endif
len = len = awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
} else { } else {
error = true; error = true;
@@ -147,8 +142,7 @@ void handler_atomic_write_file(
data.type.record.fileStartRecord, data.type.record.fileStartRecord,
data.type.record.returnedRecordCount); data.type.record.returnedRecordCount);
#endif #endif
len = len = awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
awf_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
} else { } else {
error = true; error = true;
@@ -169,15 +163,13 @@ void handler_atomic_write_file(
error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE; error_code = ERROR_CODE_INCONSISTENT_OBJECT_TYPE;
} }
if (error) { if (error) {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, SERVICE_CONFIRMED_ATOMIC_WRITE_FILE, error_class, error_code);
error_class, error_code);
} }
AWF_ABORT: AWF_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
+84 -158
View File
@@ -61,7 +61,8 @@ static uint16_t BVLC6_Buffer_Len;
#ifndef MAX_BBMD6_ENTRIES #ifndef MAX_BBMD6_ENTRIES
#define MAX_BBMD6_ENTRIES 128 #define MAX_BBMD6_ENTRIES 128
#endif #endif
static BACNET_IP6_BROADCAST_DISTRIBUTION_TABLE_ENTRY BBMD_Table[MAX_BBMD6_ENTRIES]; static BACNET_IP6_BROADCAST_DISTRIBUTION_TABLE_ENTRY
BBMD_Table[MAX_BBMD6_ENTRIES];
/* Foreign Device Table */ /* Foreign Device Table */
#ifndef MAX_FD6_ENTRIES #ifndef MAX_FD6_ENTRIES
#define MAX_FD6_ENTRIES 128 #define MAX_FD6_ENTRIES 128
@@ -74,8 +75,7 @@ static BACNET_IP6_FOREIGN_DEVICE_TABLE_ENTRY FD_Table[MAX_FD6_ENTRIES];
* *
* @param seconds - number of elapsed seconds since the last call * @param seconds - number of elapsed seconds since the last call
*/ */
void bbmd6_maintenance_timer( void bbmd6_maintenance_timer(time_t seconds)
time_t seconds)
{ {
unsigned i = 0; unsigned i = 0;
@@ -104,8 +104,7 @@ void bbmd6_maintenance_timer(
* *
* @return true if the address was set * @return true if the address was set
*/ */
static bool bbmd6_address_from_vmac( static bool bbmd6_address_from_vmac(BACNET_IP6_ADDRESS *addr,
BACNET_IP6_ADDRESS *addr,
struct vmac_data *vmac) struct vmac_data *vmac)
{ {
bool status = false; bool status = false;
@@ -130,8 +129,7 @@ static bool bbmd6_address_from_vmac(
* *
* @return true if the address was set * @return true if the address was set
*/ */
static bool bbmd6_address_to_vmac( static bool bbmd6_address_to_vmac(struct vmac_data *vmac,
struct vmac_data *vmac,
BACNET_IP6_ADDRESS *addr) BACNET_IP6_ADDRESS *addr)
{ {
bool status = false; bool status = false;
@@ -157,9 +155,7 @@ static bool bbmd6_address_to_vmac(
* *
* @return true if the VMAC address was added * @return true if the VMAC address was added
*/ */
static bool bbmd6_add_vmac( static bool bbmd6_add_vmac(uint32_t device_id, BACNET_IP6_ADDRESS *addr)
uint32_t device_id,
BACNET_IP6_ADDRESS *addr)
{ {
bool status = false; bool status = false;
struct vmac_data *vmac; struct vmac_data *vmac;
@@ -186,8 +182,7 @@ static bool bbmd6_add_vmac(
* *
* @return true if the IPv6 from sin match me * @return true if the IPv6 from sin match me
*/ */
static bool bbmd6_address_match_self( static bool bbmd6_address_match_self(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
BACNET_IP6_ADDRESS my_addr = {{0}}; BACNET_IP6_ADDRESS my_addr = {{0}};
bool status = false; bool status = false;
@@ -211,8 +206,7 @@ static bool bbmd6_address_match_self(
* *
* @return true if the address was in the VMAC table * @return true if the address was in the VMAC table
*/ */
static bool bbmd6_address_from_bacnet_address( static bool bbmd6_address_from_bacnet_address(BACNET_IP6_ADDRESS *addr,
BACNET_IP6_ADDRESS * addr,
uint32_t *vmac_src, uint32_t *vmac_src,
BACNET_ADDRESS *baddr) BACNET_ADDRESS *baddr)
{ {
@@ -226,8 +220,7 @@ static bool bbmd6_address_from_bacnet_address(
vmac = VMAC_Find_By_Key(device_id); vmac = VMAC_Find_By_Key(device_id);
if (vmac) { if (vmac) {
debug_printf("BVLC6: Found VMAC %lu (len=%u).\n", debug_printf("BVLC6: Found VMAC %lu (len=%u).\n",
(unsigned long)device_id, (unsigned long)device_id, (unsigned)vmac->mac_len);
(unsigned)vmac->mac_len);
status = bbmd6_address_from_vmac(addr, vmac); status = bbmd6_address_from_vmac(addr, vmac);
if (vmac_src) { if (vmac_src) {
*vmac_src = device_id; *vmac_src = device_id;
@@ -239,8 +232,6 @@ static bool bbmd6_address_from_bacnet_address(
return status; return status;
} }
/** /**
* The common send function for BACnet/IPv6 application layer * The common send function for BACnet/IPv6 application layer
* *
@@ -253,11 +244,8 @@ static bool bbmd6_address_from_bacnet_address(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
int bip6_send_pdu( int bip6_send_pdu(BACNET_ADDRESS *dest, BACNET_NPDU_DATA *npdu_data,
BACNET_ADDRESS * dest, uint8_t *pdu, unsigned pdu_len)
BACNET_NPDU_DATA * npdu_data,
uint8_t * pdu,
unsigned pdu_len)
{ {
BACNET_IP6_ADDRESS bvlc_dest = {{0}}; BACNET_IP6_ADDRESS bvlc_dest = {{0}};
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
@@ -281,8 +269,8 @@ int bip6_send_pdu(
} else { } else {
bip6_get_broadcast_addr(&bvlc_dest); bip6_get_broadcast_addr(&bvlc_dest);
vmac_src = Device_Object_Instance_Number(); vmac_src = Device_Object_Instance_Number();
mtu_len = bvlc6_encode_original_broadcast( mtu_len = bvlc6_encode_original_broadcast(mtu, sizeof(mtu),
mtu, sizeof(mtu), vmac_src, pdu, pdu_len); vmac_src, pdu, pdu_len);
debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n"); debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n");
} }
} else if ((dest->net > 0) && (dest->len == 0)) { } else if ((dest->net > 0) && (dest->len == 0)) {
@@ -294,16 +282,16 @@ int bip6_send_pdu(
bip6_get_broadcast_addr(&bvlc_dest); bip6_get_broadcast_addr(&bvlc_dest);
} }
vmac_src = Device_Object_Instance_Number(); vmac_src = Device_Object_Instance_Number();
mtu_len = bvlc6_encode_original_broadcast( mtu_len = bvlc6_encode_original_broadcast(mtu, sizeof(mtu), vmac_src,
mtu, sizeof(mtu), vmac_src, pdu, pdu_len); pdu, pdu_len);
debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n"); debug_printf("BVLC6: Sent Original-Broadcast-NPDU.\n");
} else if (dest->mac_len == 3) { } else if (dest->mac_len == 3) {
/* valid unicast */ /* valid unicast */
bbmd6_address_from_bacnet_address(&bvlc_dest, &vmac_dst, dest); bbmd6_address_from_bacnet_address(&bvlc_dest, &vmac_dst, dest);
debug_printf("BVLC6: Sending to VMAC %lu.\n", (unsigned long)vmac_dst); debug_printf("BVLC6: Sending to VMAC %lu.\n", (unsigned long)vmac_dst);
vmac_src = Device_Object_Instance_Number(); vmac_src = Device_Object_Instance_Number();
mtu_len = bvlc6_encode_original_unicast( mtu_len = bvlc6_encode_original_unicast(mtu, sizeof(mtu), vmac_src,
mtu, sizeof(mtu), vmac_src, vmac_dst, pdu, pdu_len); vmac_dst, pdu, pdu_len);
debug_printf("BVLC6: Sent Original-Unicast-NPDU.\n"); debug_printf("BVLC6: Sent Original-Unicast-NPDU.\n");
} else { } else {
debug_printf("BVLC6: Send failure. Invalid Address.\n"); debug_printf("BVLC6: Send failure. Invalid Address.\n");
@@ -323,9 +311,7 @@ int bip6_send_pdu(
* @param npdu - the bytes of NPDU+APDU data to send * @param npdu - the bytes of NPDU+APDU data to send
* @param npdu_len - the number of bytes of NPDU+APDU data to send * @param npdu_len - the number of bytes of NPDU+APDU data to send
*/ */
static void bbmd6_send_pdu_bdt( static void bbmd6_send_pdu_bdt(uint8_t *mtu, unsigned int mtu_len)
uint8_t * mtu,
unsigned int mtu_len)
{ {
BACNET_IP6_ADDRESS my_addr = {{0}}; BACNET_IP6_ADDRESS my_addr = {{0}};
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
@@ -352,9 +338,7 @@ static void bbmd6_send_pdu_bdt(
* @param npdu - the bytes of NPDU+APDU data to send * @param npdu - the bytes of NPDU+APDU data to send
* @param npdu_len - the number of bytes of NPDU+APDU data to send * @param npdu_len - the number of bytes of NPDU+APDU data to send
*/ */
static void bbmd6_send_pdu_fdt( static void bbmd6_send_pdu_fdt(uint8_t *mtu, unsigned int mtu_len)
uint8_t * mtu,
unsigned int mtu_len)
{ {
BACNET_IP6_ADDRESS my_addr = {{0}}; BACNET_IP6_ADDRESS my_addr = {{0}};
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
@@ -381,10 +365,8 @@ static void bbmd6_send_pdu_fdt(
* @param npdu - the bytes of NPDU+APDU data to send * @param npdu - the bytes of NPDU+APDU data to send
* @param npdu_len - the number of bytes of NPDU+APDU data to send * @param npdu_len - the number of bytes of NPDU+APDU data to send
*/ */
static void bbmd6_send_forward_npdu( static void bbmd6_send_forward_npdu(BACNET_IP6_ADDRESS *address,
BACNET_IP6_ADDRESS *address, uint32_t vmac_src, uint8_t *npdu,
uint32_t vmac_src,
uint8_t * npdu,
unsigned int npdu_len) unsigned int npdu_len)
{ {
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
@@ -424,9 +406,7 @@ static void bbmd6_send_forward_npdu(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
static int bvlc6_send_result( static int bvlc6_send_result(BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src,
BACNET_IP6_ADDRESS *dest_addr,
uint32_t vmac_src,
uint16_t result_code) uint16_t result_code)
{ {
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
@@ -448,16 +428,14 @@ static int bvlc6_send_result(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
static int bvlc6_send_address_resolution_ack( static int bvlc6_send_address_resolution_ack(BACNET_IP6_ADDRESS *dest_addr,
BACNET_IP6_ADDRESS *dest_addr,
uint32_t vmac_src, uint32_t vmac_src,
uint32_t vmac_dst) uint32_t vmac_dst)
{ {
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0; uint16_t mtu_len = 0;
mtu_len = bvlc6_encode_address_resolution_ack( mtu_len = bvlc6_encode_address_resolution_ack(&mtu[0], sizeof(mtu),
&mtu[0], sizeof(mtu),
vmac_src, vmac_dst); vmac_src, vmac_dst);
return bip6_send_mpdu(dest_addr, mtu, mtu_len); return bip6_send_mpdu(dest_addr, mtu, mtu_len);
@@ -476,15 +454,12 @@ static int bvlc6_send_address_resolution_ack(
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
static int bvlc6_send_virtual_address_resolution_ack( static int bvlc6_send_virtual_address_resolution_ack(
BACNET_IP6_ADDRESS *dest_addr, BACNET_IP6_ADDRESS *dest_addr, uint32_t vmac_src, uint32_t vmac_dst)
uint32_t vmac_src,
uint32_t vmac_dst)
{ {
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0; uint16_t mtu_len = 0;
mtu_len = bvlc6_encode_virtual_address_resolution_ack( mtu_len = bvlc6_encode_virtual_address_resolution_ack(&mtu[0], sizeof(mtu),
&mtu[0], sizeof(mtu),
vmac_src, vmac_dst); vmac_src, vmac_dst);
return bip6_send_mpdu(dest_addr, mtu, mtu_len); return bip6_send_mpdu(dest_addr, mtu, mtu_len);
@@ -497,8 +472,7 @@ static int bvlc6_send_virtual_address_resolution_ack(
* @param pdu - The received NPDU+APDU buffer. * @param pdu - The received NPDU+APDU buffer.
* @param pdu_len - How many bytes in NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer.
*/ */
static void bbmd6_virtual_address_resolution_handler( static void bbmd6_virtual_address_resolution_handler(BACNET_IP6_ADDRESS *addr,
BACNET_IP6_ADDRESS *addr,
uint8_t *pdu, uint8_t *pdu,
uint16_t pdu_len) uint16_t pdu_len)
{ {
@@ -511,8 +485,7 @@ static void bbmd6_virtual_address_resolution_handler(
if (bbmd6_address_match_self(addr)) { if (bbmd6_address_match_self(addr)) {
/* ignore messages from my IPv6 address */ /* ignore messages from my IPv6 address */
} else { } else {
function_len = bvlc6_decode_virtual_address_resolution( function_len = bvlc6_decode_virtual_address_resolution(pdu, pdu_len,
pdu, pdu_len,
&vmac_src); &vmac_src);
if (function_len) { if (function_len) {
bbmd6_add_vmac(vmac_src, addr); bbmd6_add_vmac(vmac_src, addr);
@@ -520,8 +493,8 @@ static void bbmd6_virtual_address_resolution_handler(
to the B/IPv6 node that originally initiated to the B/IPv6 node that originally initiated
the Address-Resolution message. */ the Address-Resolution message. */
vmac_me = Device_Object_Instance_Number(); vmac_me = Device_Object_Instance_Number();
bvlc6_send_virtual_address_resolution_ack( bvlc6_send_virtual_address_resolution_ack(addr, vmac_me,
addr, vmac_me, vmac_src); vmac_src);
} }
} }
} }
@@ -535,9 +508,7 @@ static void bbmd6_virtual_address_resolution_handler(
* @param pdu_len - How many bytes in NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer.
*/ */
static void bbmd6_virtual_address_resolution_ack_handler( static void bbmd6_virtual_address_resolution_ack_handler(
BACNET_IP6_ADDRESS *addr, BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len)
uint8_t * pdu,
uint16_t pdu_len)
{ {
int function_len = 0; int function_len = 0;
uint32_t vmac_src = 0; uint32_t vmac_src = 0;
@@ -549,8 +520,7 @@ static void bbmd6_virtual_address_resolution_ack_handler(
/* ignore messages from my IPv6 address */ /* ignore messages from my IPv6 address */
} else { } else {
function_len = bvlc6_decode_virtual_address_resolution_ack( function_len = bvlc6_decode_virtual_address_resolution_ack(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &vmac_dst);
&vmac_src, &vmac_dst);
if (function_len) { if (function_len) {
bbmd6_add_vmac(vmac_src, addr); bbmd6_add_vmac(vmac_src, addr);
} }
@@ -565,10 +535,8 @@ static void bbmd6_virtual_address_resolution_ack_handler(
* @param pdu - The received NPDU+APDU buffer. * @param pdu - The received NPDU+APDU buffer.
* @param pdu_len - How many bytes in NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer.
*/ */
static void bbmd6_address_resolution_handler( static void bbmd6_address_resolution_handler(BACNET_IP6_ADDRESS *addr,
BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len)
uint8_t * pdu,
uint16_t pdu_len)
{ {
int function_len = 0; int function_len = 0;
uint32_t vmac_src = 0; uint32_t vmac_src = 0;
@@ -581,8 +549,7 @@ static void bbmd6_address_resolution_handler(
/* ignore messages from my IPv6 address */ /* ignore messages from my IPv6 address */
} else { } else {
function_len = bvlc6_decode_address_resolution( function_len = bvlc6_decode_address_resolution(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &vmac_target);
&vmac_src, &vmac_target);
if (function_len) { if (function_len) {
bbmd6_add_vmac(vmac_src, addr); bbmd6_add_vmac(vmac_src, addr);
vmac_me = Device_Object_Instance_Number(); vmac_me = Device_Object_Instance_Number();
@@ -590,8 +557,7 @@ static void bbmd6_address_resolution_handler(
/* The Address-Resolution-ACK message is unicast /* The Address-Resolution-ACK message is unicast
to the B/IPv6 node that originally initiated to the B/IPv6 node that originally initiated
the Address-Resolution message. */ the Address-Resolution message. */
bvlc6_send_address_resolution_ack( bvlc6_send_address_resolution_ack(addr, vmac_me, vmac_src);
addr, vmac_me, vmac_src);
} }
} }
} }
@@ -605,10 +571,8 @@ static void bbmd6_address_resolution_handler(
* @param pdu - The received NPDU+APDU buffer. * @param pdu - The received NPDU+APDU buffer.
* @param pdu_len - How many bytes in NPDU+APDU buffer. * @param pdu_len - How many bytes in NPDU+APDU buffer.
*/ */
static void bbmd6_address_resolution_ack_handler( static void bbmd6_address_resolution_ack_handler(BACNET_IP6_ADDRESS *addr,
BACNET_IP6_ADDRESS *addr, uint8_t *pdu, uint16_t pdu_len)
uint8_t * pdu,
uint16_t pdu_len)
{ {
int function_len = 0; int function_len = 0;
uint32_t vmac_src = 0; uint32_t vmac_src = 0;
@@ -620,8 +584,7 @@ static void bbmd6_address_resolution_ack_handler(
/* ignore messages from my IPv6 address */ /* ignore messages from my IPv6 address */
} else { } else {
function_len = bvlc6_decode_address_resolution_ack( function_len = bvlc6_decode_address_resolution_ack(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &vmac_dst);
&vmac_src, &vmac_dst);
if (function_len) { if (function_len) {
bbmd6_add_vmac(vmac_src, addr); bbmd6_add_vmac(vmac_src, addr);
} }
@@ -640,10 +603,8 @@ static void bbmd6_address_resolution_ack_handler(
* *
* @return number of bytes offset into the NPDU for APDU, or 0 if handled * @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/ */
static int handler_bbmd6_for_non_bbmd( static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr,
BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, uint8_t *mtu,
BACNET_ADDRESS * src,
uint8_t * mtu,
uint16_t mtu_len) uint16_t mtu_len)
{ {
uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION; uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION;
@@ -660,16 +621,16 @@ static int handler_bbmd6_for_non_bbmd(
uint16_t offset = 0; uint16_t offset = 0;
BACNET_IP6_ADDRESS fwd_address = {{0}}; BACNET_IP6_ADDRESS fwd_address = {{0}};
header_len = bvlc6_decode_header(mtu, mtu_len, &message_type, header_len =
&message_length); bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length);
if (header_len == 4) { if (header_len == 4) {
BVLC6_Function_Code = message_type; BVLC6_Function_Code = message_type;
pdu = &mtu[header_len]; pdu = &mtu[header_len];
pdu_len = mtu_len - header_len; pdu_len = mtu_len - header_len;
switch (BVLC6_Function_Code) { switch (BVLC6_Function_Code) {
case BVLC6_RESULT: case BVLC6_RESULT:
function_len = bvlc6_decode_result(pdu, pdu_len, &vmac_src, function_len =
&result_code); bvlc6_decode_result(pdu, pdu_len, &vmac_src, &result_code);
if (function_len) { if (function_len) {
BVLC6_Result_Code = result_code; BVLC6_Result_Code = result_code;
/* The Virtual MAC address table shall be updated /* The Virtual MAC address table shall be updated
@@ -702,9 +663,7 @@ static int handler_bbmd6_for_non_bbmd(
debug_printf("BIP6: Original-Unicast-NPDU is me!.\n"); debug_printf("BIP6: Original-Unicast-NPDU is me!.\n");
} else { } else {
function_len = bvlc6_decode_original_unicast( function_len = bvlc6_decode_original_unicast(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &vmac_dst, NULL, 0, &npdu_len);
&vmac_src, &vmac_dst,
NULL, 0, &npdu_len);
if (function_len) { if (function_len) {
if (vmac_dst == Device_Object_Instance_Number()) { if (vmac_dst == Device_Object_Instance_Number()) {
/* The Virtual MAC address table shall be updated /* The Virtual MAC address table shall be updated
@@ -731,9 +690,7 @@ static int handler_bbmd6_for_non_bbmd(
debug_printf("BIP6: Original-Broadcast-NPDU is me!\n"); debug_printf("BIP6: Original-Broadcast-NPDU is me!\n");
} else { } else {
function_len = bvlc6_decode_original_broadcast( function_len = bvlc6_decode_original_broadcast(
pdu, pdu_len, pdu, pdu_len, &vmac_src, NULL, 0, &npdu_len);
&vmac_src,
NULL, 0, &npdu_len);
if (function_len) { if (function_len) {
/* The Virtual MAC address table shall be updated /* The Virtual MAC address table shall be updated
using the respective parameter values of the using the respective parameter values of the
@@ -743,7 +700,8 @@ static int handler_bbmd6_for_non_bbmd(
offset = header_len + (function_len - npdu_len); offset = header_len + (function_len - npdu_len);
} else { } else {
debug_printf( debug_printf(
"BIP6: Original-Broadcast-NPDU: Unable to decode!\n"); "BIP6: Original-Broadcast-NPDU: Unable to "
"decode!\n");
} }
} }
break; break;
@@ -754,9 +712,8 @@ static int handler_bbmd6_for_non_bbmd(
debug_printf("BIP6: Forwarded-NPDU is me!\n"); debug_printf("BIP6: Forwarded-NPDU is me!\n");
} else { } else {
function_len = bvlc6_decode_forwarded_npdu( function_len = bvlc6_decode_forwarded_npdu(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &fwd_address, NULL, 0,
&vmac_src, &fwd_address, &npdu_len);
NULL, 0, &npdu_len);
if (function_len) { if (function_len) {
/* The Virtual MAC address table shall be updated /* The Virtual MAC address table shall be updated
using the respective parameter values of the using the respective parameter values of the
@@ -784,7 +741,8 @@ static int handler_bbmd6_for_non_bbmd(
bbmd6_virtual_address_resolution_handler(addr, pdu, pdu_len); bbmd6_virtual_address_resolution_handler(addr, pdu, pdu_len);
break; break;
case BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK: case BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK:
bbmd6_virtual_address_resolution_ack_handler(addr, pdu, pdu_len); bbmd6_virtual_address_resolution_ack_handler(addr, pdu,
pdu_len);
break; break;
case BVLC6_SECURE_BVLL: case BVLC6_SECURE_BVLL:
break; break;
@@ -814,11 +772,8 @@ static int handler_bbmd6_for_non_bbmd(
* *
* @return number of bytes offset into the NPDU for APDU, or 0 if handled * @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/ */
static int handler_bbmd6_for_bbmd( static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src,
BACNET_IP6_ADDRESS *addr, uint8_t *mtu, uint16_t mtu_len)
BACNET_ADDRESS * src,
uint8_t * mtu,
uint16_t mtu_len)
{ {
uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION; uint16_t result_code = BVLC6_RESULT_SUCCESSFUL_COMPLETION;
uint32_t vmac_me = 0; uint32_t vmac_me = 0;
@@ -837,16 +792,16 @@ static int handler_bbmd6_for_bbmd(
uint16_t offset = 0; uint16_t offset = 0;
BACNET_IP6_ADDRESS fwd_address = {{0}}; BACNET_IP6_ADDRESS fwd_address = {{0}};
header_len = bvlc6_decode_header(mtu, mtu_len, &message_type, header_len =
&message_length); bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length);
if (header_len == 4) { if (header_len == 4) {
BVLC6_Function_Code = message_type; BVLC6_Function_Code = message_type;
pdu = &mtu[header_len]; pdu = &mtu[header_len];
pdu_len = mtu_len - header_len; pdu_len = mtu_len - header_len;
switch (BVLC6_Function_Code) { switch (BVLC6_Function_Code) {
case BVLC6_RESULT: case BVLC6_RESULT:
function_len = bvlc6_decode_result(pdu, pdu_len, &vmac_src, function_len =
&result_code); bvlc6_decode_result(pdu, pdu_len, &vmac_src, &result_code);
if (function_len) { if (function_len) {
BVLC6_Result_Code = result_code; BVLC6_Result_Code = result_code;
/* The Virtual MAC address table shall be updated /* The Virtual MAC address table shall be updated
@@ -880,9 +835,7 @@ static int handler_bbmd6_for_bbmd(
offset = 0; offset = 0;
} else { } else {
function_len = bvlc6_decode_original_unicast( function_len = bvlc6_decode_original_unicast(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &vmac_dst, NULL, 0, &npdu_len);
&vmac_src, &vmac_dst,
NULL, 0, &npdu_len);
if (function_len) { if (function_len) {
if (vmac_dst == Device_Object_Instance_Number()) { if (vmac_dst == Device_Object_Instance_Number()) {
/* The Virtual MAC address table shall be updated /* The Virtual MAC address table shall be updated
@@ -898,9 +851,7 @@ static int handler_bbmd6_for_bbmd(
case BVLC6_ORIGINAL_BROADCAST_NPDU: case BVLC6_ORIGINAL_BROADCAST_NPDU:
debug_printf("BIP6: Received Original-Broadcast-NPDU.\n"); debug_printf("BIP6: Received Original-Broadcast-NPDU.\n");
function_len = bvlc6_decode_original_broadcast( function_len = bvlc6_decode_original_broadcast(
pdu, pdu_len, pdu, pdu_len, &vmac_src, NULL, 0, &npdu_len);
&vmac_src,
NULL, 0, &npdu_len);
if (function_len) { if (function_len) {
offset = header_len + (function_len - npdu_len); offset = header_len + (function_len - npdu_len);
npdu = &mtu[offset]; npdu = &mtu[offset];
@@ -912,8 +863,7 @@ static int handler_bbmd6_for_bbmd(
be unicast to each foreign device currently in be unicast to each foreign device currently in
the BBMD's FDT */ the BBMD's FDT */
BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu( BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu(
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer), &BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src, addr,
vmac_src, addr,
npdu, npdu_len); npdu, npdu_len);
bbmd6_send_pdu_bdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len); bbmd6_send_pdu_bdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len);
bbmd6_send_pdu_fdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len); bbmd6_send_pdu_fdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len);
@@ -929,9 +879,7 @@ static int handler_bbmd6_for_bbmd(
case BVLC6_FORWARDED_NPDU: case BVLC6_FORWARDED_NPDU:
debug_printf("BIP6: Received Forwarded-NPDU.\n"); debug_printf("BIP6: Received Forwarded-NPDU.\n");
function_len = bvlc6_decode_forwarded_npdu( function_len = bvlc6_decode_forwarded_npdu(
pdu, pdu_len, pdu, pdu_len, &vmac_src, &fwd_address, NULL, 0, &npdu_len);
&vmac_src, &fwd_address,
NULL, 0, &npdu_len);
if (function_len) { if (function_len) {
offset = header_len + (function_len - npdu_len); offset = header_len + (function_len - npdu_len);
npdu = &mtu[offset]; npdu = &mtu[offset];
@@ -941,11 +889,11 @@ static int handler_bbmd6_for_bbmd(
transmit it via multicast to B/IPv6 devices in the transmit it via multicast to B/IPv6 devices in the
local multicast domain. */ local multicast domain. */
BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu( BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu(
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer), &BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src, addr,
vmac_src, addr,
npdu, npdu_len); npdu, npdu_len);
bip6_get_broadcast_addr(&bvlc_dest); bip6_get_broadcast_addr(&bvlc_dest);
bip6_send_mpdu(&bvlc_dest, &BVLC6_Buffer[0], BVLC6_Buffer_Len); bip6_send_mpdu(&bvlc_dest, &BVLC6_Buffer[0],
BVLC6_Buffer_Len);
/* In addition, the constructed BVLL Forwarded-NPDU /* In addition, the constructed BVLL Forwarded-NPDU
message shall be unicast to each foreign device in message shall be unicast to each foreign device in
the BBMD's FDT. If the BBMD is unable to transmit the BBMD's FDT. If the BBMD is unable to transmit
@@ -977,7 +925,8 @@ static int handler_bbmd6_for_bbmd(
bbmd6_virtual_address_resolution_handler(addr, pdu, pdu_len); bbmd6_virtual_address_resolution_handler(addr, pdu, pdu_len);
break; break;
case BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK: case BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK:
bbmd6_virtual_address_resolution_ack_handler(addr, pdu, pdu_len); bbmd6_virtual_address_resolution_ack_handler(addr, pdu,
pdu_len);
break; break;
case BVLC6_SECURE_BVLL: case BVLC6_SECURE_BVLL:
break; break;
@@ -1005,10 +954,7 @@ static int handler_bbmd6_for_bbmd(
* *
* @return number of bytes offset into the NPDU for APDU, or 0 if handled * @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/ */
int bvlc6_handler( int bvlc6_handler(BACNET_IP6_ADDRESS *addr, BACNET_ADDRESS *src, uint8_t *npdu,
BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS * src,
uint8_t * npdu,
uint16_t npdu_len) uint16_t npdu_len)
{ {
#if defined(BACDL_BIP6) && BBMD6_ENABLED #if defined(BACDL_BIP6) && BBMD6_ENABLED
@@ -1027,9 +973,7 @@ int bvlc6_handler(
* 0 if no registration request is sent, or * 0 if no registration request is sent, or
* -1 if registration fails. * -1 if registration fails.
*/ */
int bvlc6_register_with_bbmd( int bvlc6_register_with_bbmd(BACNET_IP6_ADDRESS *bbmd_addr, uint32_t vmac_src,
BACNET_IP6_ADDRESS *bbmd_addr,
uint32_t vmac_src,
uint16_t time_to_live_seconds) uint16_t time_to_live_seconds)
{ {
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
@@ -1049,8 +993,7 @@ int bvlc6_register_with_bbmd(
* BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK if registration failed, * BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK if registration failed,
* or one of the other codes (if we are a BBMD). * or one of the other codes (if we are a BBMD).
*/ */
uint16_t bvlc6_get_last_result( uint16_t bvlc6_get_last_result(void)
void)
{ {
return BVLC6_Result_Code; return BVLC6_Result_Code;
} }
@@ -1062,8 +1005,7 @@ uint16_t bvlc6_get_last_result(
* *
* @return A BVLC6_ code, such as BVLC6_ORIGINAL_UNICAST_NPDU. * @return A BVLC6_ code, such as BVLC6_ORIGINAL_UNICAST_NPDU.
*/ */
uint8_t bvlc6_get_function_code( uint8_t bvlc6_get_function_code(void)
void)
{ {
return BVLC6_Function_Code; return BVLC6_Function_Code;
} }
@@ -1095,10 +1037,7 @@ static uint8_t BIP6_MTU_Buffer[MAX_MPDU];
* *
* @return Number of bytes received, or 0 if none or timeout. * @return Number of bytes received, or 0 if none or timeout.
*/ */
uint16_t bip6_receive( uint16_t bip6_receive(BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu,
BACNET_ADDRESS * src,
uint8_t * npdu,
uint16_t max_npdu,
unsigned timeout) unsigned timeout)
{ {
return 0; return 0;
@@ -1115,10 +1054,7 @@ uint16_t bip6_receive(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error. * Otherwise, -1 shall be returned and errno set to indicate the error.
*/ */
int bip6_send_mpdu( int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
BACNET_IP6_ADDRESS *dest,
uint8_t * mtu,
uint16_t mtu_len)
{ {
return 0; return 0;
} }
@@ -1129,8 +1065,7 @@ int bip6_send_mpdu(
* *
* @return The Instance number used in the BACNET_OBJECT_ID for the Device. * @return The Instance number used in the BACNET_OBJECT_ID for the Device.
*/ */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(void)
void)
{ {
return Device_ID; return Device_ID;
} }
@@ -1140,8 +1075,7 @@ uint32_t Device_Object_Instance_Number(
* *
* @return BACnet/IP address * @return BACnet/IP address
*/ */
bool bip6_get_addr( bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
return bvlc6_address_copy(addr, &BIP6_Addr); return bvlc6_address_copy(addr, &BIP6_Addr);
} }
@@ -1151,14 +1085,12 @@ bool bip6_get_addr(
* *
* @return BACnet/IP address * @return BACnet/IP address
*/ */
bool bip6_get_broadcast_addr( bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
BACNET_IP6_ADDRESS *addr)
{ {
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr); return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
} }
static void test_BBMD_Result( static void test_BBMD_Result(Test *pTest)
Test * pTest)
{ {
int result = 0; int result = 0;
uint32_t vmac_src = 0x1234; uint32_t vmac_src = 0x1234;
@@ -1168,8 +1100,7 @@ static void test_BBMD_Result(
BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK, BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK,
BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK, BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK,
BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK, BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK,
BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK};
};
uint16_t test_result_code = 0; uint16_t test_result_code = 0;
uint8_t test_function_code = 0; uint8_t test_function_code = 0;
BACNET_IP6_ADDRESS addr; BACNET_IP6_ADDRESS addr;
@@ -1178,14 +1109,13 @@ static void test_BBMD_Result(
uint8_t mtu[MAX_MPDU] = {0}; uint8_t mtu[MAX_MPDU] = {0};
uint16_t mtu_len = 0; uint16_t mtu_len = 0;
bvlc6_address_set(&addr, bvlc6_address_set(&addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID); BIP6_MULTICAST_GROUP_ID);
addr.port = 0xBAC0; addr.port = 0xBAC0;
bvlc6_vmac_address_set(&src, vmac_src); bvlc6_vmac_address_set(&src, vmac_src);
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
mtu_len = bvlc6_encode_result(&mtu[0], sizeof(mtu), mtu_len =
vmac_src, result_code[i]); bvlc6_encode_result(&mtu[0], sizeof(mtu), vmac_src, result_code[i]);
result = handler_bbmd6_for_non_bbmd(&addr, &src, &mtu[0], mtu_len); result = handler_bbmd6_for_non_bbmd(&addr, &src, &mtu[0], mtu_len);
/* validate that the result is handled (0) */ /* validate that the result is handled (0) */
ct_test(pTest, result == 0); ct_test(pTest, result == 0);
@@ -1196,8 +1126,7 @@ static void test_BBMD_Result(
} }
} }
static void test_BBMD6( static void test_BBMD6(Test *pTest)
Test * pTest)
{ {
bool rc; bool rc;
@@ -1207,8 +1136,7 @@ static void test_BBMD6(
} }
#ifdef TEST_BBMD6 #ifdef TEST_BBMD6
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
@@ -1224,5 +1152,3 @@ int main(
} }
#endif #endif
#endif #endif
+18 -23
View File
@@ -59,9 +59,7 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_ccov_notification( void handler_ccov_notification(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
{ {
@@ -81,31 +79,29 @@ void handler_ccov_notification(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CCOV: Received Notification!\n"); fprintf(stderr, "CCOV: Received Notification!\n");
#endif #endif
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n"); fprintf(stderr, "CCOV: Segmented message. Sending Abort!\n");
#endif #endif
goto CCOV_ABORT; goto CCOV_ABORT;
} }
/* decode the service request only */ /* decode the service request only */
len = len = cov_notify_decode_service_request(service_request, service_len,
cov_notify_decode_service_request(service_request, service_len,
&cov_data); &cov_data);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len > 0) { if (len > 0) {
fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier); fprintf(stderr, "CCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
fprintf(stderr, "%s %u ", fprintf(
stderr, "%s %u ",
bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
cov_data.monitoredObjectIdentifier.instance); cov_data.monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
@@ -114,9 +110,9 @@ void handler_ccov_notification(
while (pProperty_value) { while (pProperty_value) {
fprintf(stderr, "CCOV: "); fprintf(stderr, "CCOV: ");
if (pProperty_value->propertyIdentifier < 512) { if (pProperty_value->propertyIdentifier < 512) {
fprintf(stderr, "%s ", fprintf(
bactext_property_name stderr, "%s ",
(pProperty_value->propertyIdentifier)); bactext_property_name(pProperty_value->propertyIdentifier));
} else { } else {
fprintf(stderr, "proprietary %u ", fprintf(stderr, "proprietary %u ",
pProperty_value->propertyIdentifier); pProperty_value->propertyIdentifier);
@@ -131,25 +127,24 @@ void handler_ccov_notification(
#endif #endif
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "CCOV: Bad Encoding. Sending Abort!\n");
#endif #endif
goto CCOV_ABORT; goto CCOV_ABORT;
} else { } else {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_COV_NOTIFICATION); SERVICE_CONFIRMED_COV_NOTIFICATION);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CCOV: Sending Simple Ack!\n"); fprintf(stderr, "CCOV: Sending Simple Ack!\n");
#endif #endif
} }
CCOV_ABORT: CCOV_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
+77 -112
View File
@@ -92,8 +92,7 @@ static BACNET_COV_ADDRESS COV_Addresses[MAX_COV_ADDRESSES];
* *
* @return true if valid address, false if not valid or not found * @return true if valid address, false if not valid or not found
*/ */
static BACNET_ADDRESS *cov_address_get( static BACNET_ADDRESS *cov_address_get(int index)
int index)
{ {
BACNET_ADDRESS *cov_dest = NULL; BACNET_ADDRESS *cov_dest = NULL;
@@ -110,8 +109,7 @@ static BACNET_ADDRESS *cov_address_get(
* Removes the address from the list of COV addresses, if it is not * Removes the address from the list of COV addresses, if it is not
* used by other COV subscriptions * used by other COV subscriptions
*/ */
static void cov_address_remove_unused( static void cov_address_remove_unused(void)
void)
{ {
unsigned index = 0; unsigned index = 0;
unsigned cov_index = 0; unsigned cov_index = 0;
@@ -141,8 +139,7 @@ static void cov_address_remove_unused(
* *
* @return index number 0..N, or -1 if unable to add * @return index number 0..N, or -1 if unable to add
*/ */
static int cov_address_add( static int cov_address_add(BACNET_ADDRESS *dest)
BACNET_ADDRESS * dest)
{ {
int index = -1; int index = -1;
unsigned i = 0; unsigned i = 0;
@@ -207,9 +204,7 @@ TimeRemaining [3] Unsigned,
COVIncrement [4] REAL OPTIONAL COVIncrement [4] REAL OPTIONAL
*/ */
static int cov_encode_subscription( static int cov_encode_subscription(uint8_t *apdu, int max_apdu,
uint8_t * apdu,
int max_apdu,
BACNET_COV_SUBSCRIPTION *cov_subscription) BACNET_COV_SUBSCRIPTION *cov_subscription)
{ {
int len = 0; int len = 0;
@@ -217,7 +212,6 @@ static int cov_encode_subscription(
BACNET_OCTET_STRING octet_string; BACNET_OCTET_STRING octet_string;
BACNET_ADDRESS *dest = NULL; BACNET_ADDRESS *dest = NULL;
/* FIXME: unused parameter */ /* FIXME: unused parameter */
max_apdu = max_apdu; max_apdu = max_apdu;
if (!cov_subscription) { if (!cov_subscription) {
@@ -256,9 +250,8 @@ static int cov_encode_subscription(
len = encode_closing_tag(&apdu[apdu_len], 0); len = encode_closing_tag(&apdu[apdu_len], 0);
apdu_len += len; apdu_len += len;
/* processIdentifier [1] Unsigned32 */ /* processIdentifier [1] Unsigned32 */
len = len = encode_context_unsigned(
encode_context_unsigned(&apdu[apdu_len], 1, &apdu[apdu_len], 1, cov_subscription->subscriberProcessIdentifier);
cov_subscription->subscriberProcessIdentifier);
apdu_len += len; apdu_len += len;
/* Recipient [0] BACnetRecipientProcess - closing */ /* Recipient [0] BACnetRecipientProcess - closing */
len = encode_closing_tag(&apdu[apdu_len], 0); len = encode_closing_tag(&apdu[apdu_len], 0);
@@ -267,9 +260,8 @@ static int cov_encode_subscription(
len = encode_opening_tag(&apdu[apdu_len], 1); len = encode_opening_tag(&apdu[apdu_len], 1);
apdu_len += len; apdu_len += len;
/* objectIdentifier [0] */ /* objectIdentifier [0] */
len = len = encode_context_object_id(
encode_context_object_id(&apdu[apdu_len], 0, &apdu[apdu_len], 0, cov_subscription->monitoredObjectIdentifier.type,
cov_subscription->monitoredObjectIdentifier.type,
cov_subscription->monitoredObjectIdentifier.instance); cov_subscription->monitoredObjectIdentifier.instance);
apdu_len += len; apdu_len += len;
/* propertyIdentifier [1] */ /* propertyIdentifier [1] */
@@ -280,14 +272,12 @@ static int cov_encode_subscription(
len = encode_closing_tag(&apdu[apdu_len], 1); len = encode_closing_tag(&apdu[apdu_len], 1);
apdu_len += len; apdu_len += len;
/* IssueConfirmedNotifications [2] BOOLEAN, */ /* IssueConfirmedNotifications [2] BOOLEAN, */
len = len = encode_context_boolean(
encode_context_boolean(&apdu[apdu_len], 2, &apdu[apdu_len], 2, cov_subscription->flag.issueConfirmedNotifications);
cov_subscription->flag.issueConfirmedNotifications);
apdu_len += len; apdu_len += len;
/* TimeRemaining [3] Unsigned, */ /* TimeRemaining [3] Unsigned, */
len = len =
encode_context_unsigned(&apdu[apdu_len], 3, encode_context_unsigned(&apdu[apdu_len], 3, cov_subscription->lifetime);
cov_subscription->lifetime);
apdu_len += len; apdu_len += len;
return apdu_len; return apdu_len;
@@ -295,18 +285,16 @@ static int cov_encode_subscription(
/** Handle a request to list all the COV subscriptions. /** Handle a request to list all the COV subscriptions.
* @ingroup DSCOV * @ingroup DSCOV
* Invoked by a request to read the Device object's PROP_ACTIVE_COV_SUBSCRIPTIONS. * Invoked by a request to read the Device object's
* Loops through the list of COV Subscriptions, and, for each valid one, * PROP_ACTIVE_COV_SUBSCRIPTIONS. Loops through the list of COV Subscriptions,
* adds its description to the APDU. * and, for each valid one, adds its description to the APDU.
* @note This function needs some work to better handle buffer overruns. * @note This function needs some work to better handle buffer overruns.
* @param apdu [out] Buffer in which the APDU contents are built. * @param apdu [out] Buffer in which the APDU contents are built.
* @param max_apdu [in] Max length of the APDU buffer. * @param max_apdu [in] Max length of the APDU buffer.
* @return How many bytes were encoded in the buffer, or -2 if the response * @return How many bytes were encoded in the buffer, or -2 if the response
* would not fit within the buffer. * would not fit within the buffer.
*/ */
int handler_cov_encode_subscriptions( int handler_cov_encode_subscriptions(uint8_t *apdu, int max_apdu)
uint8_t * apdu,
int max_apdu)
{ {
int len = 0; int len = 0;
int apdu_len = 0; int apdu_len = 0;
@@ -315,9 +303,9 @@ int handler_cov_encode_subscriptions(
if (apdu) { if (apdu) {
for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) { for (index = 0; index < MAX_COV_SUBCRIPTIONS; index++) {
if (COV_Subscriptions[index].flag.valid) { if (COV_Subscriptions[index].flag.valid) {
len = len = cov_encode_subscription(&apdu[apdu_len],
cov_encode_subscription(&apdu[apdu_len], max_apdu - apdu_len,
max_apdu - apdu_len, &COV_Subscriptions[index]); &COV_Subscriptions[index]);
apdu_len += len; apdu_len += len;
/* TODO: too late here to notice that we overran the buffer */ /* TODO: too late here to notice that we overran the buffer */
if (apdu_len > max_apdu) { if (apdu_len > max_apdu) {
@@ -333,8 +321,7 @@ int handler_cov_encode_subscriptions(
/** Handler to initialize the COV list, clearing and disabling each entry. /** Handler to initialize the COV list, clearing and disabling each entry.
* @ingroup DSCOV * @ingroup DSCOV
*/ */
void handler_cov_init( void handler_cov_init(void)
void)
{ {
unsigned index = 0; unsigned index = 0;
@@ -355,8 +342,7 @@ void handler_cov_init(
} }
} }
static bool cov_list_subscribe( static bool cov_list_subscribe(BACNET_ADDRESS *src,
BACNET_ADDRESS * src,
BACNET_SUBSCRIBE_COV_DATA *cov_data, BACNET_SUBSCRIBE_COV_DATA *cov_data,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
@@ -386,7 +372,8 @@ static bool cov_list_subscribe(
(COV_Subscriptions[index].monitoredObjectIdentifier.instance == (COV_Subscriptions[index].monitoredObjectIdentifier.instance ==
cov_data->monitoredObjectIdentifier.instance) && cov_data->monitoredObjectIdentifier.instance) &&
(COV_Subscriptions[index].subscriberProcessIdentifier == (COV_Subscriptions[index].subscriberProcessIdentifier ==
cov_data->subscriberProcessIdentifier) && address_match) { cov_data->subscriberProcessIdentifier) &&
address_match) {
existing_entry = true; existing_entry = true;
if (cov_data->cancellationRequest) { if (cov_data->cancellationRequest) {
COV_Subscriptions[index].flag.valid = false; COV_Subscriptions[index].flag.valid = false;
@@ -447,8 +434,7 @@ static bool cov_list_subscribe(
return found; return found;
} }
static bool cov_send_request( static bool cov_send_request(BACNET_COV_SUBSCRIPTION *cov_subscription,
BACNET_COV_SUBSCRIPTION * cov_subscription,
BACNET_PROPERTY_VALUE *value_list) BACNET_PROPERTY_VALUE *value_list)
{ {
int len = 0; int len = 0;
@@ -479,8 +465,7 @@ static bool cov_send_request(
} }
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data); &npdu_data);
/* load the COV data structure for outgoing message */ /* load the COV data structure for outgoing message */
cov_data.subscriberProcessIdentifier = cov_data.subscriberProcessIdentifier =
@@ -497,25 +482,26 @@ static bool cov_send_request(
invoke_id = tsm_next_free_invokeID(); invoke_id = tsm_next_free_invokeID();
if (invoke_id) { if (invoke_id) {
cov_subscription->invokeID = invoke_id; cov_subscription->invokeID = invoke_id;
len = len = ccov_notify_encode_apdu(
ccov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, &cov_data); sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id,
&cov_data);
} else { } else {
goto COV_FAILED; goto COV_FAILED;
} }
} else { } else {
len = len = ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
ucov_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len,
sizeof(Handler_Transmit_Buffer) - pdu_len, &cov_data); &cov_data);
} }
pdu_len += len; pdu_len += len;
if (cov_subscription->flag.issueConfirmedNotifications) { if (cov_subscription->flag.issueConfirmedNotifications) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, &npdu_data, tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, &npdu_data,
&Handler_Transmit_Buffer[0], (uint16_t) pdu_len); &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
} }
bytes_sent = bytes_sent = datalink_send_pdu(dest, &npdu_data,
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
if (bytes_sent > 0) { if (bytes_sent > 0) {
status = true; status = true;
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -528,8 +514,7 @@ static bool cov_send_request(
return status; return status;
} }
static void cov_lifetime_expiration_handler( static void cov_lifetime_expiration_handler(unsigned index,
unsigned index,
uint32_t elapsed_seconds, uint32_t elapsed_seconds,
uint32_t lifetime_seconds) uint32_t lifetime_seconds)
{ {
@@ -549,9 +534,10 @@ static void cov_lifetime_expiration_handler(
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "COVtimer: PID=%u ", fprintf(stderr, "COVtimer: PID=%u ",
COV_Subscriptions[index].subscriberProcessIdentifier); COV_Subscriptions[index].subscriberProcessIdentifier);
fprintf(stderr, "%s %u ", fprintf(
bactext_object_type_name(COV_Subscriptions[index]. stderr, "%s %u ",
monitoredObjectIdentifier.type), bactext_object_type_name(
COV_Subscriptions[index].monitoredObjectIdentifier.type),
COV_Subscriptions[index].monitoredObjectIdentifier.instance); COV_Subscriptions[index].monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", fprintf(stderr, "time remaining=%u seconds ",
COV_Subscriptions[index].lifetime); COV_Subscriptions[index].lifetime);
@@ -591,8 +577,7 @@ static void cov_lifetime_expiration_handler(
* *
* @param elapsed_seconds [in] How many seconds have elapsed since last called. * @param elapsed_seconds [in] How many seconds have elapsed since last called.
*/ */
void handler_cov_timer_seconds( void handler_cov_timer_seconds(uint32_t elapsed_seconds)
uint32_t elapsed_seconds)
{ {
unsigned index = 0; unsigned index = 0;
uint32_t lifetime_seconds = 0; uint32_t lifetime_seconds = 0;
@@ -612,8 +597,7 @@ void handler_cov_timer_seconds(
} }
} }
bool handler_cov_fsm( bool handler_cov_fsm(void)
void)
{ {
static int index = 0; static int index = 0;
BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE; BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
@@ -638,11 +622,10 @@ bool handler_cov_fsm(
case COV_STATE_MARK: case COV_STATE_MARK:
/* mark any subscriptions where the value has changed */ /* mark any subscriptions where the value has changed */
if (COV_Subscriptions[index].flag.valid) { if (COV_Subscriptions[index].flag.valid) {
object_type = (BACNET_OBJECT_TYPE) object_type = (BACNET_OBJECT_TYPE)COV_Subscriptions[index]
COV_Subscriptions[index].monitoredObjectIdentifier.type; .monitoredObjectIdentifier.type;
object_instance = object_instance =
COV_Subscriptions[index]. COV_Subscriptions[index].monitoredObjectIdentifier.instance;
monitoredObjectIdentifier.instance;
status = Device_COV(object_type, object_instance); status = Device_COV(object_type, object_instance);
if (status) { if (status) {
COV_Subscriptions[index].flag.send_requested = true; COV_Subscriptions[index].flag.send_requested = true;
@@ -661,11 +644,10 @@ bool handler_cov_fsm(
/* clear the COV flag after checking all subscriptions */ /* clear the COV flag after checking all subscriptions */
if ((COV_Subscriptions[index].flag.valid) && if ((COV_Subscriptions[index].flag.valid) &&
(COV_Subscriptions[index].flag.send_requested)) { (COV_Subscriptions[index].flag.send_requested)) {
object_type = (BACNET_OBJECT_TYPE) object_type = (BACNET_OBJECT_TYPE)COV_Subscriptions[index]
COV_Subscriptions[index].monitoredObjectIdentifier.type; .monitoredObjectIdentifier.type;
object_instance = object_instance =
COV_Subscriptions[index]. COV_Subscriptions[index].monitoredObjectIdentifier.instance;
monitoredObjectIdentifier.instance;
Device_COV_Clear(object_type, object_instance); Device_COV_Clear(object_type, object_instance);
} }
index++; index++;
@@ -681,9 +663,8 @@ bool handler_cov_fsm(
(COV_Subscriptions[index].invokeID)) { (COV_Subscriptions[index].invokeID)) {
if (tsm_invoke_id_free(COV_Subscriptions[index].invokeID)) { if (tsm_invoke_id_free(COV_Subscriptions[index].invokeID)) {
COV_Subscriptions[index].invokeID = 0; COV_Subscriptions[index].invokeID = 0;
} else } else if (tsm_invoke_id_failed(
if (tsm_invoke_id_failed(COV_Subscriptions COV_Subscriptions[index].invokeID)) {
[index].invokeID)) {
tsm_free_invoke_id(COV_Subscriptions[index].invokeID); tsm_free_invoke_id(COV_Subscriptions[index].invokeID);
COV_Subscriptions[index].invokeID = 0; COV_Subscriptions[index].invokeID = 0;
} }
@@ -710,23 +691,20 @@ bool handler_cov_fsm(
} }
} }
if (send) { if (send) {
object_type = (BACNET_OBJECT_TYPE) object_type = (BACNET_OBJECT_TYPE)COV_Subscriptions[index]
COV_Subscriptions[index]. .monitoredObjectIdentifier.type;
monitoredObjectIdentifier.type; object_instance = COV_Subscriptions[index]
object_instance = .monitoredObjectIdentifier.instance;
COV_Subscriptions[index].
monitoredObjectIdentifier.instance;
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "COVtask: Sending...\n"); fprintf(stderr, "COVtask: Sending...\n");
#endif #endif
/* configure the linked list for the two properties */ /* configure the linked list for the two properties */
bacapp_property_value_list_init(&value_list[0], bacapp_property_value_list_init(&value_list[0],
MAX_COV_PROPERTIES); MAX_COV_PROPERTIES);
status = Device_Encode_Value_List(object_type, status = Device_Encode_Value_List(
object_instance, &value_list[0]); object_type, object_instance, &value_list[0]);
if (status) { if (status) {
status = status = cov_send_request(&COV_Subscriptions[index],
cov_send_request(&COV_Subscriptions[index],
&value_list[0]); &value_list[0]);
} }
if (status) { if (status) {
@@ -748,14 +726,12 @@ bool handler_cov_fsm(
return (cov_task_state == COV_STATE_IDLE); return (cov_task_state == COV_STATE_IDLE);
} }
void handler_cov_task( void handler_cov_task(void)
void)
{ {
handler_cov_fsm(); handler_cov_fsm();
} }
static bool cov_subscribe( static bool cov_subscribe(BACNET_ADDRESS *src,
BACNET_ADDRESS * src,
BACNET_SUBSCRIBE_COV_DATA *cov_data, BACNET_SUBSCRIBE_COV_DATA *cov_data,
BACNET_ERROR_CLASS *error_class, BACNET_ERROR_CLASS *error_class,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
@@ -764,15 +740,13 @@ static bool cov_subscribe(
BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE; BACNET_OBJECT_TYPE object_type = MAX_BACNET_OBJECT_TYPE;
uint32_t object_instance = 0; uint32_t object_instance = 0;
object_type = object_type = (BACNET_OBJECT_TYPE)cov_data->monitoredObjectIdentifier.type;
(BACNET_OBJECT_TYPE) cov_data->monitoredObjectIdentifier.type;
object_instance = cov_data->monitoredObjectIdentifier.instance; object_instance = cov_data->monitoredObjectIdentifier.instance;
status = Device_Valid_Object_Id(object_type, object_instance); status = Device_Valid_Object_Id(object_type, object_instance);
if (status) { if (status) {
status = Device_Value_List_Supported(object_type); status = Device_Value_List_Supported(object_type);
if (status) { if (status) {
status = status = cov_list_subscribe(src, cov_data, error_class, error_code);
cov_list_subscribe(src, cov_data, error_class, error_code);
} else { } else {
*error_class = ERROR_CLASS_OBJECT; *error_class = ERROR_CLASS_OBJECT;
*error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED; *error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
@@ -802,9 +776,7 @@ static bool cov_subscribe(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_cov_subscribe( void handler_cov_subscribe(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
{ {
@@ -824,8 +796,7 @@ void handler_cov_subscribe(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
@@ -836,8 +807,7 @@ void handler_cov_subscribe(
error = true; error = true;
goto COV_ABORT; goto COV_ABORT;
} }
len = len = cov_subscribe_decode_service_request(service_request, service_len,
cov_subscribe_decode_service_request(service_request, service_len,
&cov_data); &cov_data);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len <= 0) if (len <= 0)
@@ -849,13 +819,12 @@ void handler_cov_subscribe(
} }
cov_data.error_class = ERROR_CLASS_OBJECT; cov_data.error_class = ERROR_CLASS_OBJECT;
cov_data.error_code = ERROR_CODE_UNKNOWN_OBJECT; cov_data.error_code = ERROR_CODE_UNKNOWN_OBJECT;
success = success = cov_subscribe(src, &cov_data, &cov_data.error_class,
cov_subscribe(src, &cov_data, &cov_data.error_class,
&cov_data.error_code); &cov_data.error_code);
if (success) { if (success) {
apdu_len = apdu_len = encode_simple_ack(&Handler_Transmit_Buffer[npdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_SUBSCRIBE_COV); SERVICE_CONFIRMED_SUBSCRIBE_COV);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Simple Ack!\n"); fprintf(stderr, "SubscribeCOV: Sending Simple Ack!\n");
#endif #endif
@@ -869,25 +838,23 @@ void handler_cov_subscribe(
COV_ABORT: COV_ABORT:
if (error) { if (error) {
if (len == BACNET_STATUS_ABORT) { if (len == BACNET_STATUS_ABORT) {
apdu_len = apdu_len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
abort_convert_error_code(cov_data.error_code), true); abort_convert_error_code(cov_data.error_code), true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Abort!\n"); fprintf(stderr, "SubscribeCOV: Sending Abort!\n");
#endif #endif
} else if (len == BACNET_STATUS_ERROR) { } else if (len == BACNET_STATUS_ERROR) {
apdu_len = apdu_len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_SUBSCRIBE_COV, SERVICE_CONFIRMED_SUBSCRIBE_COV, cov_data.error_class,
cov_data.error_class, cov_data.error_code); cov_data.error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Error!\n"); fprintf(stderr, "SubscribeCOV: Sending Error!\n");
#endif #endif
} else if (len == BACNET_STATUS_REJECT) { } else if (len == BACNET_STATUS_REJECT) {
apdu_len = apdu_len = reject_encode_apdu(
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
reject_convert_error_code(cov_data.error_code)); reject_convert_error_code(cov_data.error_code));
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "SubscribeCOV: Sending Reject!\n"); fprintf(stderr, "SubscribeCOV: Sending Reject!\n");
@@ -895,8 +862,7 @@ void handler_cov_subscribe(
} }
} }
pdu_len = npdu_len + apdu_len; pdu_len = npdu_len + apdu_len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -905,6 +871,5 @@ void handler_cov_subscribe(
#endif #endif
} }
return; return;
} }
+27 -34
View File
@@ -47,8 +47,7 @@ static char My_Password[32] = "filister";
/** Sets (non-volatile hold) the password to be used for DCC requests. /** Sets (non-volatile hold) the password to be used for DCC requests.
* @param new_password [in] The new DCC password, of up to 31 characters. * @param new_password [in] The new DCC password, of up to 31 characters.
*/ */
void handler_dcc_password_set( void handler_dcc_password_set(char *new_password)
char *new_password)
{ {
size_t i = 0; /* loop counter */ size_t i = 0; /* loop counter */
@@ -95,9 +94,7 @@ char *handler_dcc_password(void)
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_device_communication_control( void handler_device_communication_control(
uint8_t * service_request, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
{ {
uint16_t timeDuration = 0; uint16_t timeDuration = 0;
@@ -111,17 +108,15 @@ void handler_device_communication_control(
/* encode the NPDU portion of the reply packet */ /* encode the NPDU portion of the reply packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "DeviceCommunicationControl!\n"); fprintf(stderr, "DeviceCommunicationControl!\n");
#endif #endif
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DeviceCommunicationControl: " "DeviceCommunicationControl: "
@@ -130,21 +125,21 @@ void handler_device_communication_control(
goto DCC_ABORT; goto DCC_ABORT;
} }
/* decode the service request only */ /* decode the service request only */
len = len = dcc_decode_service_request(service_request, service_len,
dcc_decode_service_request(service_request, service_len, &timeDuration, &timeDuration, &state, &password);
&state, &password);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len > 0) if (len > 0)
fprintf(stderr, fprintf(stderr,
"DeviceCommunicationControl: " "timeout=%u state=%u password=%s\n", "DeviceCommunicationControl: "
"timeout=%u state=%u password=%s\n",
(unsigned)timeDuration, (unsigned)state, (unsigned)timeDuration, (unsigned)state,
characterstring_value(&password)); characterstring_value(&password));
#endif #endif
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len < 0) { if (len < 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DeviceCommunicationControl: " "DeviceCommunicationControl: "
@@ -153,9 +148,9 @@ void handler_device_communication_control(
goto DCC_ABORT; goto DCC_ABORT;
} }
if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) { if (state >= MAX_BACNET_COMMUNICATION_ENABLE_DISABLE) {
len = len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); REJECT_REASON_UNDEFINED_ENUMERATION);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DeviceCommunicationControl: " "DeviceCommunicationControl: "
@@ -164,28 +159,26 @@ void handler_device_communication_control(
} else { } else {
#if BAC_ROUTING #if BAC_ROUTING
/* Check to see if the current Device supports this service. */ /* Check to see if the current Device supports this service. */
len = len = Routed_Device_Service_Approval(
Routed_Device_Service_Approval SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, (int)state,
(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, (int) state,
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id);
if (len > 0) if (len > 0)
goto DCC_ABORT; goto DCC_ABORT;
#endif #endif
if (characterstring_ansi_same(&password, My_Password)) { if (characterstring_ansi_same(&password, My_Password)) {
len = len = encode_simple_ack(
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id,
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL); SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DeviceCommunicationControl: " "Sending Simple Ack!\n"); "DeviceCommunicationControl: "
"Sending Simple Ack!\n");
#endif #endif
dcc_set_status_duration(state, timeDuration); dcc_set_status_duration(state, timeDuration);
} else { } else {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id,
SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL, SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
ERROR_CLASS_SECURITY, ERROR_CODE_PASSWORD_FAILURE); ERROR_CLASS_SECURITY, ERROR_CODE_PASSWORD_FAILURE);
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -197,13 +190,13 @@ void handler_device_communication_control(
} }
DCC_ABORT: DCC_ABORT:
pdu_len += len; pdu_len += len;
len = len = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (len <= 0) { if (len <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"DeviceCommunicationControl: " "Failed to send PDU (%s)!\n", "DeviceCommunicationControl: "
"Failed to send PDU (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
} }
+3 -7
View File
@@ -46,7 +46,6 @@
#include "handlers.h" #include "handlers.h"
#include "get_alarm_sum.h" #include "get_alarm_sum.h"
/** Example function to handle a GetAlarmSummary ACK. /** Example function to handle a GetAlarmSummary ACK.
* *
* @param service_request [in] The contents of the service request. * @param service_request [in] The contents of the service request.
@@ -56,9 +55,7 @@
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void get_alarm_summary_ack_handler( void get_alarm_summary_ack_handler(
uint8_t * service_request, uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA* service_data)
{ {
uint16_t apdu_len = 0; uint16_t apdu_len = 0;
@@ -66,9 +63,8 @@ void get_alarm_summary_ack_handler(
BACNET_GET_ALARM_SUMMARY_DATA data; BACNET_GET_ALARM_SUMMARY_DATA data;
while (service_len - len) { while (service_len - len) {
apdu_len = apdu_len = get_alarm_summary_ack_decode_apdu_data(
get_alarm_summary_ack_decode_apdu_data(&service_request[len], &service_request[len], service_len - len, &data);
service_len - len, &data);
len += apdu_len; len += apdu_len;
+18 -33
View File
@@ -41,8 +41,7 @@
static get_alarm_summary_function Get_Alarm_Summary[MAX_BACNET_OBJECT_TYPE]; static get_alarm_summary_function Get_Alarm_Summary[MAX_BACNET_OBJECT_TYPE];
void handler_get_alarm_summary_set( void handler_get_alarm_summary_set(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
get_alarm_summary_function pFunction) get_alarm_summary_function pFunction)
{ {
if (object_type < MAX_BACNET_OBJECT_TYPE) { if (object_type < MAX_BACNET_OBJECT_TYPE) {
@@ -50,9 +49,7 @@ void handler_get_alarm_summary_set(
} }
} }
void handler_get_alarm_summary( void handler_get_alarm_summary(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -68,41 +65,33 @@ void handler_get_alarm_summary(
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
BACNET_GET_ALARM_SUMMARY_DATA getalarm_data; BACNET_GET_ALARM_SUMMARY_DATA getalarm_data;
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
apdu_len = apdu_len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr, "GetAlarmSummary: Segmented message. Sending Abort!\n");
"GetAlarmSummary: Segmented message. Sending Abort!\n");
#endif #endif
goto GET_ALARM_SUMMARY_ABORT; goto GET_ALARM_SUMMARY_ABORT;
} }
/* init header */ /* init header */
apdu_len = apdu_len = get_alarm_summary_ack_encode_apdu_init(
get_alarm_summary_ack_encode_apdu_init(&Handler_Transmit_Buffer &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id);
[pdu_len], service_data->invoke_id);
for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) { for (i = 0; i < MAX_BACNET_OBJECT_TYPE; i++) {
if (Get_Alarm_Summary[i]) { if (Get_Alarm_Summary[i]) {
for (j = 0; j < 0xffff; j++) { for (j = 0; j < 0xffff; j++) {
alarm_value = Get_Alarm_Summary[i](j, &getalarm_data); alarm_value = Get_Alarm_Summary[i](j, &getalarm_data);
if (alarm_value > 0) { if (alarm_value > 0) {
len = len = get_alarm_summary_ack_encode_apdu_data(
get_alarm_summary_ack_encode_apdu_data &Handler_Transmit_Buffer[pdu_len + apdu_len],
(&Handler_Transmit_Buffer[pdu_len + apdu_len],
service_data->max_resp - apdu_len, &getalarm_data); service_data->max_resp - apdu_len, &getalarm_data);
if (len <= 0) { if (len <= 0) {
error = true; error = true;
@@ -116,7 +105,6 @@ void handler_get_alarm_summary(
} }
} }
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending response!\n"); fprintf(stderr, "GetAlarmSummary: Sending response!\n");
#endif #endif
@@ -125,30 +113,27 @@ void handler_get_alarm_summary(
if (error) { if (error) {
if (len == BACNET_STATUS_ABORT) { if (len == BACNET_STATUS_ABORT) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is Abort */
apdu_len = apdu_len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"GetAlarmSummary: Reply too big to fit into APDU!\n"); "GetAlarmSummary: Reply too big to fit into APDU!\n");
#endif #endif
} else { } else {
apdu_len = apdu_len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_GET_ALARM_SUMMARY, SERVICE_CONFIRMED_GET_ALARM_SUMMARY, ERROR_CLASS_PROPERTY,
ERROR_CLASS_PROPERTY, ERROR_CODE_OTHER); ERROR_CODE_OTHER);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "GetAlarmSummary: Sending Error!\n"); fprintf(stderr, "GetAlarmSummary: Sending Error!\n");
#endif #endif
} }
} }
GET_ALARM_SUMMARY_ABORT: GET_ALARM_SUMMARY_ABORT:
pdu_len += apdu_len; pdu_len += apdu_len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
+36 -49
View File
@@ -43,11 +43,9 @@
static get_event_info_function Get_Event_Info[MAX_BACNET_OBJECT_TYPE]; static get_event_info_function Get_Event_Info[MAX_BACNET_OBJECT_TYPE];
/** print eventState /** print eventState
*/ */
void ge_ack_print_data( void ge_ack_print_data(BACNET_GET_EVENT_INFORMATION_DATA* data,
BACNET_GET_EVENT_INFORMATION_DATA * data,
uint32_t device_id) uint32_t device_id)
{ {
BACNET_GET_EVENT_INFORMATION_DATA* act_data = data; BACNET_GET_EVENT_INFORMATION_DATA* act_data = data;
@@ -56,20 +54,16 @@ void ge_ack_print_data(
printf("--------------- ------- --------------- ---------------\n"); printf("--------------- ------- --------------- ---------------\n");
int count = 0; int count = 0;
while (act_data) { while (act_data) {
printf("%u\t\t%u\t%u\t\t%s\n", printf(
device_id, "%u\t\t%u\t%u\t\t%s\n", device_id, act_data->objectIdentifier.type,
act_data->objectIdentifier.type, act_data->objectIdentifier.instance, state_strs[data->eventState]);
act_data->objectIdentifier.instance,
state_strs[data->eventState]
);
act_data = act_data->next; act_data = act_data->next;
count++; count++;
} }
printf("\n%u\t Total\n", count); printf("\n%u\t Total\n", count);
} }
void handler_get_event_information_set( void handler_get_event_information_set(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
get_event_info_function pFunction) get_event_info_function pFunction)
{ {
if (object_type < MAX_BACNET_OBJECT_TYPE) { if (object_type < MAX_BACNET_OBJECT_TYPE) {
@@ -77,10 +71,8 @@ void handler_get_event_information_set(
} }
} }
void handler_get_event_information( void handler_get_event_information(uint8_t* service_request,
uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS* src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
int len = 0; int len = 0;
@@ -104,38 +96,35 @@ void handler_get_event_information(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"GetEventInformation: " "Segmented message. Sending Abort!\n"); "GetEventInformation: "
"Segmented message. Sending Abort!\n");
#endif #endif
goto GET_EVENT_ABORT; goto GET_EVENT_ABORT;
} }
len = len = getevent_decode_service_request(service_request, service_len,
getevent_decode_service_request(service_request, service_len,
&object_id); &object_id);
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr, "GetEventInformation: Bad Encoding. Sending Abort!\n");
"GetEventInformation: Bad Encoding. Sending Abort!\n");
#endif #endif
goto GET_EVENT_ABORT; goto GET_EVENT_ABORT;
} }
len = len = getevent_ack_encode_apdu_init(
getevent_ack_encode_apdu_init(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, service_data->invoke_id); sizeof(Handler_Transmit_Buffer) - pdu_len, service_data->invoke_id);
if (len <= 0) { if (len <= 0) {
error = true; error = true;
@@ -148,7 +137,8 @@ void handler_get_event_information(
for (j = 0; j < 0xffff; j++) { for (j = 0; j < 0xffff; j++) {
valid_event = Get_Event_Info[i](j, &getevent_data); valid_event = Get_Event_Info[i](j, &getevent_data);
if (valid_event > 0) { if (valid_event > 0) {
/* encode GetEvent_data only when type of object_id has max value */ /* encode GetEvent_data only when type of object_id has max
* value */
if (object_id.type != MAX_BACNET_OBJECT_TYPE) { if (object_id.type != MAX_BACNET_OBJECT_TYPE) {
if ((object_id.type == if ((object_id.type ==
getevent_data.objectIdentifier.type) && getevent_data.objectIdentifier.type) &&
@@ -162,9 +152,9 @@ void handler_get_event_information(
} }
getevent_data.next = NULL; getevent_data.next = NULL;
len = len = getevent_ack_encode_apdu_data(
getevent_ack_encode_apdu_data(&Handler_Transmit_Buffer &Handler_Transmit_Buffer[pdu_len],
[pdu_len], sizeof(Handler_Transmit_Buffer) - pdu_len, sizeof(Handler_Transmit_Buffer) - pdu_len,
&getevent_data); &getevent_data);
if (len <= 0) { if (len <= 0) {
error = true; error = true;
@@ -195,8 +185,8 @@ void handler_get_event_information(
} }
} }
} }
len = len = getevent_ack_encode_apdu_end(
getevent_ack_encode_apdu_end(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, more_events); sizeof(Handler_Transmit_Buffer) - pdu_len, more_events);
if (len <= 0) { if (len <= 0) {
error = true; error = true;
@@ -207,25 +197,23 @@ void handler_get_event_information(
#endif #endif
GET_EVENT_ERROR: GET_EVENT_ERROR:
if (error) { if (error) {
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (len == -2) { if (len == -2) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is Abort */
len = len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"GetEventInformation: " "Reply too big to fit into APDU!\n"); "GetEventInformation: "
"Reply too big to fit into APDU!\n");
#endif #endif
} else { } else {
len = len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, SERVICE_CONFIRMED_READ_PROPERTY, error_class, error_code);
error_class, error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "GetEventInformation: Sending Error!\n"); fprintf(stderr, "GetEventInformation: Sending Error!\n");
#endif #endif
@@ -233,8 +221,7 @@ void handler_get_event_information(
} }
GET_EVENT_ABORT: GET_EVENT_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
+3 -6
View File
@@ -59,9 +59,7 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_ACK_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_ACK_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void get_event_ack_handler( void get_event_ack_handler(uint8_t *service_request, uint16_t service_len,
uint8_t *service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
@@ -77,9 +75,8 @@ void get_event_ack_handler(
get_event_data[i - 1].next = &get_event_data[i]; get_event_data[i - 1].next = &get_event_data[i];
} }
apdu_len = apdu_len = getevent_ack_decode_service_request(
getevent_ack_decode_service_request(&service_request[0], &service_request[0], service_len, &get_event_data[0], &more_events);
service_len, &get_event_data[0], &more_events);
if (apdu_len > 0) { if (apdu_len > 0) {
/* FIXME: Add code to process get_event_data */ /* FIXME: Add code to process get_event_data */
+4 -10
View File
@@ -42,9 +42,7 @@
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source. * @param src [in] The BACNET_ADDRESS of the message's source.
*/ */
void handler_i_am_add( void handler_i_am_add(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
@@ -54,8 +52,7 @@ void handler_i_am_add(
uint16_t vendor_id = 0; uint16_t vendor_id = 0;
(void)service_len; (void)service_len;
len = len = iam_decode_service_request(service_request, &device_id, &max_apdu,
iam_decode_service_request(service_request, &device_id, &max_apdu,
&segmentation, &vendor_id); &segmentation, &vendor_id);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Received I-Am Request"); fprintf(stderr, "Received I-Am Request");
@@ -84,9 +81,7 @@ void handler_i_am_add(
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source. * @param src [in] The BACNET_ADDRESS of the message's source.
*/ */
void handler_i_am_bind( void handler_i_am_bind(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
@@ -96,8 +91,7 @@ void handler_i_am_bind(
uint16_t vendor_id = 0; uint16_t vendor_id = 0;
(void)service_len; (void)service_len;
len = len = iam_decode_service_request(service_request, &device_id, &max_apdu,
iam_decode_service_request(service_request, &device_id, &max_apdu,
&segmentation, &vendor_id); &segmentation, &vendor_id);
if (len > 0) { if (len > 0) {
/* only add address if requested to bind */ /* only add address if requested to bind */
+1 -3
View File
@@ -41,9 +41,7 @@
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source. * @param src [in] The BACNET_ADDRESS of the message's source.
*/ */
void handler_i_have( void handler_i_have(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
+20 -20
View File
@@ -40,9 +40,7 @@
/** @file h_lso.c Handles BACnet Life Safey Operation messages. */ /** @file h_lso.c Handles BACnet Life Safey Operation messages. */
void handler_lso( void handler_lso(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -56,15 +54,13 @@ void handler_lso(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "LSO: Segmented message. Sending Abort!\n"); fprintf(stderr, "LSO: Segmented message. Sending Abort!\n");
#endif #endif
@@ -78,9 +74,9 @@ void handler_lso(
#endif #endif
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "LSO: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "LSO: Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -92,26 +88,30 @@ void handler_lso(
*/ */
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"Life Safety Operation: Received operation %d from process id %lu for object %lu\n", "Life Safety Operation: Received operation %d from process id %lu "
"for object %lu\n",
data.operation, (unsigned long)data.processId, data.operation, (unsigned long)data.processId,
(unsigned long)data.targetObject.instance); (unsigned long)data.targetObject.instance);
#endif #endif
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION); SERVICE_CONFIRMED_LIFE_SAFETY_OPERATION);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Life Safety Operation: " "Sending Simple Ack!\n"); fprintf(stderr,
"Life Safety Operation: "
"Sending Simple Ack!\n");
#endif #endif
LSO_ABORT: LSO_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Life Safety Operation: " "Failed to send PDU (%s)!\n", fprintf(stderr,
"Life Safety Operation: "
"Failed to send PDU (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
+1 -2
View File
@@ -63,8 +63,7 @@
* @param pdu [in] Buffer containing the NPDU and APDU of the received packet. * @param pdu [in] Buffer containing the NPDU and APDU of the received packet.
* @param pdu_len [in] The size of the received message in the pdu[] buffer. * @param pdu_len [in] The size of the received message in the pdu[] buffer.
*/ */
void npdu_handler( void npdu_handler(BACNET_ADDRESS* src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t* pdu, /* PDU data */ uint8_t* pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* length PDU */ { /* length PDU */
+39 -61
View File
@@ -52,8 +52,7 @@ DATABLOCK MyData[MYMAXBLOCK];
uint8_t IOBufferPT[MAX_APDU]; /* Buffer for building response in */ uint8_t IOBufferPT[MAX_APDU]; /* Buffer for building response in */
static void ProcessPT( static void ProcessPT(BACNET_PRIVATE_TRANSFER_DATA *data)
BACNET_PRIVATE_TRANSFER_DATA * data)
{ {
int iLen; /* Index to current location in data */ int iLen; /* Index to current location in data */
char cBlockNumber; char cBlockNumber;
@@ -66,8 +65,7 @@ static void ProcessPT(
iLen = 0; iLen = 0;
/* Decode the block number */ /* Decode the block number */
tag_len = tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen],
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type); &tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
@@ -77,8 +75,7 @@ static void ProcessPT(
return; return;
} }
iLen += iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type,
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&ulTemp); &ulTemp);
cBlockNumber = (char)ulTemp; cBlockNumber = (char)ulTemp;
if (cBlockNumber < MY_MAX_BLOCK) { if (cBlockNumber < MY_MAX_BLOCK) {
@@ -101,20 +98,16 @@ static void ProcessPT(
iLen += iLen +=
encode_application_unsigned(&IOBufferPT[iLen], cBlockNumber); encode_application_unsigned(&IOBufferPT[iLen], cBlockNumber);
/* And Then the block contents */ /* And Then the block contents */
iLen += encode_application_unsigned(
&IOBufferPT[iLen], MyData[(int8_t)cBlockNumber].cMyByte1);
iLen += encode_application_unsigned(
&IOBufferPT[iLen], MyData[(int8_t)cBlockNumber].cMyByte2);
iLen += encode_application_real(
&IOBufferPT[iLen], MyData[(int8_t)cBlockNumber].fMyReal);
characterstring_init_ansi(
&bsTemp, (char *)MyData[(int8_t)cBlockNumber].sMyString);
iLen += iLen +=
encode_application_unsigned(&IOBufferPT[iLen], encode_application_character_string(&IOBufferPT[iLen], &bsTemp);
MyData[(int8_t) cBlockNumber].cMyByte1);
iLen +=
encode_application_unsigned(&IOBufferPT[iLen],
MyData[(int8_t) cBlockNumber].cMyByte2);
iLen +=
encode_application_real(&IOBufferPT[iLen],
MyData[(int8_t) cBlockNumber].fMyReal);
characterstring_init_ansi(&bsTemp,
(char *) MyData[(int8_t) cBlockNumber].sMyString);
iLen +=
encode_application_character_string(&IOBufferPT[iLen],
&bsTemp);
} else { } else {
/* Write operation */ /* Write operation */
/* Write block consists of the block number /* Write block consists of the block number
@@ -124,47 +117,40 @@ static void ProcessPT(
response which is 0 for success and response which is 0 for success and
a non 0 error code otherwise. */ a non 0 error code otherwise. */
tag_len = tag_len = decode_tag_number_and_value(
decode_tag_number_and_value(&data->serviceParameters[iLen], &data->serviceParameters[iLen], &tag_number, &len_value_type);
&tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
data->serviceParametersLen = 0; data->serviceParametersLen = 0;
return; return;
} }
iLen += iLen += decode_unsigned(&data->serviceParameters[iLen],
decode_unsigned(&data->serviceParameters[iLen], len_value_type, len_value_type, &ulTemp);
&ulTemp);
MyData[(int8_t)cBlockNumber].cMyByte1 = (char)ulTemp; MyData[(int8_t)cBlockNumber].cMyByte1 = (char)ulTemp;
tag_len = tag_len = decode_tag_number_and_value(
decode_tag_number_and_value(&data->serviceParameters[iLen], &data->serviceParameters[iLen], &tag_number, &len_value_type);
&tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
data->serviceParametersLen = 0; data->serviceParametersLen = 0;
return; return;
} }
iLen += iLen += decode_unsigned(&data->serviceParameters[iLen],
decode_unsigned(&data->serviceParameters[iLen], len_value_type, len_value_type, &ulTemp);
&ulTemp);
MyData[(int8_t)cBlockNumber].cMyByte2 = (char)ulTemp; MyData[(int8_t)cBlockNumber].cMyByte2 = (char)ulTemp;
tag_len = tag_len = decode_tag_number_and_value(
decode_tag_number_and_value(&data->serviceParameters[iLen], &data->serviceParameters[iLen], &tag_number, &len_value_type);
&tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_REAL) { if (tag_number != BACNET_APPLICATION_TAG_REAL) {
data->serviceParametersLen = 0; data->serviceParametersLen = 0;
return; return;
} }
iLen += iLen += decode_real(&data->serviceParameters[iLen],
decode_real(&data->serviceParameters[iLen],
&MyData[(int8_t)cBlockNumber].fMyReal); &MyData[(int8_t)cBlockNumber].fMyReal);
tag_len = tag_len = decode_tag_number_and_value(
decode_tag_number_and_value(&data->serviceParameters[iLen], &data->serviceParameters[iLen], &tag_number, &len_value_type);
&tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) { if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) {
data->serviceParametersLen = 0; data->serviceParametersLen = 0;
@@ -198,10 +184,7 @@ static void ProcessPT(
* *
*/ */
void handler_conf_private_trans(uint8_t *service_request, uint16_t service_len,
void handler_conf_private_trans(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
{ {
@@ -230,28 +213,25 @@ void handler_conf_private_trans(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n"); fprintf(stderr, "CPT: Segmented Message. Sending Abort!\n");
#endif #endif
goto CPT_ABORT; goto CPT_ABORT;
} }
len = len = ptransfer_decode_service_request(service_request, service_len, &data);
ptransfer_decode_service_request(service_request, service_len, &data);
/* bad decoding - send an abort */ /* bad decoding - send an abort */
if (len < 0) { if (len < 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "CPT: Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -278,8 +258,7 @@ void handler_conf_private_trans(
fprintf(stderr, "CPT: Error servicing request!\n"); fprintf(stderr, "CPT: Error servicing request!\n");
#endif #endif
} }
len = len = ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
ptransfer_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
} else { /* Not our vendor ID or bad service parameter */ } else { /* Not our vendor ID or bad service parameter */
@@ -292,14 +271,13 @@ void handler_conf_private_trans(
} }
if (error) { if (error) {
len = len = ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
ptransfer_error_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, error_class,
service_data->invoke_id, error_class, error_code, &data); error_code, &data);
} }
CPT_ABORT: CPT_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
+23 -36
View File
@@ -45,11 +45,10 @@
/** @file h_pt_a.c Handles Confirmed Private Transfer Acknowledgment. */ /** @file h_pt_a.c Handles Confirmed Private Transfer Acknowledgment. */
extern uint8_t IOBufferPT[300]; /* Somewhere to build the encoded result block for Private Transfers */ extern uint8_t IOBufferPT[300]; /* Somewhere to build the encoded result block
for Private Transfers */
static void DecodeBlock( static void DecodeBlock(char cBlockNum, uint8_t *pData)
char cBlockNum,
uint8_t * pData)
{ {
int iLen; int iLen;
uint32_t ulTemp; uint32_t ulTemp;
@@ -65,8 +64,7 @@ static void DecodeBlock(
return; return;
tag_len = tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number, decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
&len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
return; return;
@@ -75,8 +73,7 @@ static void DecodeBlock(
Response.cMyByte1 = (char)ulTemp; Response.cMyByte1 = (char)ulTemp;
tag_len = tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number, decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
&len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT)
return; return;
@@ -85,8 +82,7 @@ static void DecodeBlock(
Response.cMyByte2 = (char)ulTemp; Response.cMyByte2 = (char)ulTemp;
tag_len = tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number, decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
&len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_REAL) if (tag_number != BACNET_APPLICATION_TAG_REAL)
return; return;
@@ -94,8 +90,7 @@ static void DecodeBlock(
iLen += decode_real(&pData[iLen], &Response.fMyReal); iLen += decode_real(&pData[iLen], &Response.fMyReal);
tag_len = tag_len =
decode_tag_number_and_value(&pData[iLen], &tag_number, decode_tag_number_and_value(&pData[iLen], &tag_number, &len_value_type);
&len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING) if (tag_number != BACNET_APPLICATION_TAG_CHARACTER_STRING)
return; return;
@@ -113,8 +108,7 @@ static void DecodeBlock(
printf(" String : %s\n\n", Response.sMyString); printf(" String : %s\n\n", Response.sMyString);
} }
static void ProcessPTA( static void ProcessPTA(BACNET_PRIVATE_TRANSFER_DATA *data)
BACNET_PRIVATE_TRANSFER_DATA * data)
{ {
int iLen; /* Index to current location in data */ int iLen; /* Index to current location in data */
uint32_t uiErrorCode; uint32_t uiErrorCode;
@@ -128,8 +122,7 @@ static void ProcessPTA(
/* Error code is returned for read and write operations */ /* Error code is returned for read and write operations */
tag_len = tag_len = decode_tag_number_and_value(&data->serviceParameters[iLen],
decode_tag_number_and_value(&data->serviceParameters[iLen],
&tag_number, &len_value_type); &tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
@@ -138,18 +131,18 @@ static void ProcessPTA(
#endif #endif
return; return;
} }
iLen += iLen += decode_unsigned(&data->serviceParameters[iLen], len_value_type,
decode_unsigned(&data->serviceParameters[iLen], len_value_type,
&uiErrorCode); &uiErrorCode);
if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be full block of data or error */ if (data->serviceNumber == MY_SVC_READ) { /* Read I/O block so should be
/* Decode the error type and if necessary block number and then fetch the info */ full block of data or error */
/* Decode the error type and if necessary block number and then fetch
* the info */
if (uiErrorCode == MY_ERR_OK) { if (uiErrorCode == MY_ERR_OK) {
/* Block Number */ /* Block Number */
tag_len = tag_len = decode_tag_number_and_value(
decode_tag_number_and_value(&data->serviceParameters[iLen], &data->serviceParameters[iLen], &tag_number, &len_value_type);
&tag_number, &len_value_type);
iLen += tag_len; iLen += tag_len;
if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (tag_number != BACNET_APPLICATION_TAG_UNSIGNED_INT) {
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -158,14 +151,12 @@ static void ProcessPTA(
return; return;
} }
iLen += iLen += decode_unsigned(&data->serviceParameters[iLen],
decode_unsigned(&data->serviceParameters[iLen], len_value_type, len_value_type, &ulTemp);
&ulTemp);
cBlockNumber = (char)ulTemp; cBlockNumber = (char)ulTemp;
DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]); DecodeBlock(cBlockNumber, &data->serviceParameters[iLen]);
} else { /* Read error */ } else { /* Read error */
printf printf("Private Transfer read operation returned error code: %lu\n",
("Private Transfer read operation returned error code: %lu\n",
(unsigned long)uiErrorCode); (unsigned long)uiErrorCode);
return; return;
} }
@@ -175,8 +166,6 @@ static void ProcessPTA(
} }
} }
/* /*
* This is called when we receive a private transfer packet ack. * This is called when we receive a private transfer packet ack.
* We parse the response which the remote application generated * We parse the response which the remote application generated
@@ -184,9 +173,7 @@ static void ProcessPTA(
*/ */
void handler_conf_private_trans_ack( void handler_conf_private_trans_ack(
uint8_t * service_request, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
BACNET_PRIVATE_TRANSFER_DATA data; BACNET_PRIVATE_TRANSFER_DATA data;
@@ -204,13 +191,13 @@ void handler_conf_private_trans_ack(
len = 0; len = 0;
#if PRINT_ENABLED #if PRINT_ENABLED
printf("Received Confirmed Private Transfer Ack!\n"); printf("Received Confirmed Private Transfer Ack!\n");
#endif #endif
len = ptransfer_decode_service_request(service_request, service_len, &data); /* Same decode for ack as for service request! */ len = ptransfer_decode_service_request(
service_request, service_len,
&data); /* Same decode for ack as for service request! */
if (len < 0) { if (len < 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
printf("cpta: Bad Encoding!\n"); printf("cpta: Bad Encoding!\n");
+20 -28
View File
@@ -63,9 +63,7 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_reinitialize_device( void handler_reinitialize_device(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -78,17 +76,15 @@ void handler_reinitialize_device(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "ReinitializeDevice!\n"); fprintf(stderr, "ReinitializeDevice!\n");
#endif #endif
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"ReinitializeDevice: Sending Abort - segmented message.\n"); "ReinitializeDevice: Sending Abort - segmented message.\n");
@@ -96,9 +92,8 @@ void handler_reinitialize_device(
goto RD_ABORT; goto RD_ABORT;
} }
/* decode the service request only */ /* decode the service request only */
len = len = rd_decode_service_request(service_request, service_len,
rd_decode_service_request(service_request, service_len, &rd_data.state, &rd_data.state, &rd_data.password);
&rd_data.password);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len > 0) { if (len > 0) {
fprintf(stderr, "ReinitializeDevice: state=%u password=%s\n", fprintf(stderr, "ReinitializeDevice: state=%u password=%s\n",
@@ -110,9 +105,9 @@ void handler_reinitialize_device(
#endif #endif
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len < 0) { if (len < 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"ReinitializeDevice: Sending Abort - could not decode.\n"); "ReinitializeDevice: Sending Abort - could not decode.\n");
@@ -121,9 +116,9 @@ void handler_reinitialize_device(
} }
/* check the data from the request */ /* check the data from the request */
if (rd_data.state >= BACNET_REINIT_MAX) { if (rd_data.state >= BACNET_REINIT_MAX) {
len = len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, REJECT_REASON_UNDEFINED_ENUMERATION); REJECT_REASON_UNDEFINED_ENUMERATION);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"ReinitializeDevice: Sending Reject - undefined enumeration\n"); "ReinitializeDevice: Sending Reject - undefined enumeration\n");
@@ -131,26 +126,24 @@ void handler_reinitialize_device(
} else { } else {
#if BAC_ROUTING #if BAC_ROUTING
/* Check to see if the current Device supports this service. */ /* Check to see if the current Device supports this service. */
len = len = Routed_Device_Service_Approval(
Routed_Device_Service_Approval SERVICE_CONFIRMED_REINITIALIZE_DEVICE, (int)rd_data.state,
(SERVICE_CONFIRMED_REINITIALIZE_DEVICE, (int) rd_data.state,
&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id); &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id);
if (len > 0) if (len > 0)
goto RD_ABORT; goto RD_ABORT;
#endif #endif
if (Device_Reinitialize(&rd_data)) { if (Device_Reinitialize(&rd_data)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, service_data->invoke_id,
SERVICE_CONFIRMED_REINITIALIZE_DEVICE); SERVICE_CONFIRMED_REINITIALIZE_DEVICE);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "ReinitializeDevice: Sending Simple Ack!\n"); fprintf(stderr, "ReinitializeDevice: Sending Simple Ack!\n");
#endif #endif
} else { } else {
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_REINITIALIZE_DEVICE, SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
rd_data.error_class, rd_data.error_code); rd_data.error_class, rd_data.error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "ReinitializeDevice: Sending Error.\n"); fprintf(stderr, "ReinitializeDevice: Sending Error.\n");
@@ -159,8 +152,7 @@ void handler_reinitialize_device(
} }
RD_ABORT: RD_ABORT:
pdu_len += len; pdu_len += len;
len = len = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (len <= 0) { if (len <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
+25 -34
View File
@@ -47,10 +47,8 @@
#include "bvlc.h" #include "bvlc.h"
#endif #endif
/** @file h_routed_npdu.c Handles messages at the NPDU level of the BACnet
/** @file h_routed_npdu.c Handles messages at the NPDU level of the BACnet stack, * stack, including routing and network control messages. */
* including routing and network control messages. */
/** Handler to manage the Network Layer Control Messages received in a packet. /** Handler to manage the Network Layer Control Messages received in a packet.
* This handler is called if the NCPI bit 7 indicates that this packet is a * This handler is called if the NCPI bit 7 indicates that this packet is a
@@ -61,19 +59,17 @@
* @param src [in] The routing source information, if any. * @param src [in] The routing source information, if any.
* If src->net and src->len are 0, there is no * If src->net and src->len are 0, there is no
* routing source information. * routing source information.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers. * @param DNET_list [in] List of our reachable downstream BACnet Network
* Normally just one valid entry; terminated with a -1 value. * numbers. Normally just one valid entry; terminated with a -1 value.
* @param npdu_data [in] Contains a filled-out structure with information * @param npdu_data [in] Contains a filled-out structure with information
* decoded from the NCPI and other NPDU bytes. * decoded from the NCPI and other NPDU
* bytes.
* @param npdu [in] Buffer containing the rest of the NPDU, following the * @param npdu [in] Buffer containing the rest of the NPDU, following the
* bytes that have already been decoded. * bytes that have already been decoded.
* @param npdu_len [in] The length of the remaining NPDU message in npdu[]. * @param npdu_len [in] The length of the remaining NPDU message in npdu[].
*/ */
static void network_control_handler( static void network_control_handler(BACNET_ADDRESS *src, int *DNET_list,
BACNET_ADDRESS * src, BACNET_NPDU_DATA *npdu_data, uint8_t *npdu,
int *DNET_list,
BACNET_NPDU_DATA * npdu_data,
uint8_t * npdu,
uint16_t npdu_len) uint16_t npdu_len)
{ {
uint16_t npdu_offset = 0; uint16_t npdu_offset = 0;
@@ -109,8 +105,8 @@ static void network_control_handler(
* later for congestion control - then it could matter. * later for congestion control - then it could matter.
*/ */
debug_printf("%s for Networks: ", debug_printf("%s for Networks: ",
bactext_network_layer_msg_name bactext_network_layer_msg_name(
(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK)); NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK));
while (npdu_len >= 2) { while (npdu_len >= 2) {
len = decode_unsigned16(&npdu[npdu_offset], &dnet); len = decode_unsigned16(&npdu[npdu_offset], &dnet);
debug_printf("%hu", dnet); debug_printf("%hu", dnet);
@@ -129,8 +125,8 @@ static void network_control_handler(
if (npdu_len >= 3) { if (npdu_len >= 3) {
decode_unsigned16(&npdu[1], &dnet); decode_unsigned16(&npdu[1], &dnet);
debug_printf("Received %s for Network: ", debug_printf("Received %s for Network: ",
bactext_network_layer_msg_name bactext_network_layer_msg_name(
(NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK)); NETWORK_MESSAGE_I_COULD_BE_ROUTER_TO_NETWORK));
debug_printf("%hu, Reason code: %d \n", dnet, npdu[0]); debug_printf("%hu, Reason code: %d \n", dnet, npdu[0]);
} }
break; break;
@@ -168,8 +164,8 @@ static void network_control_handler(
break; break;
default: default:
/* An unrecognized message is bad; send an error response. */ /* An unrecognized message is bad; send an error response. */
Send_Reject_Message_To_Network(src, Send_Reject_Message_To_Network(
NETWORK_REJECT_UNKNOWN_MESSAGE_TYPE, DNET_list[0]); src, NETWORK_REJECT_UNKNOWN_MESSAGE_TYPE, DNET_list[0]);
/* Sending our DNET doesn't make a lot of sense, does it? */ /* Sending our DNET doesn't make a lot of sense, does it? */
break; break;
} }
@@ -186,16 +182,13 @@ static void network_control_handler(
* *
* @param src [in] The BACNET_ADDRESS of the message's source. * @param src [in] The BACNET_ADDRESS of the message's source.
* @param dest [in] The BACNET_ADDRESS of the message's destination. * @param dest [in] The BACNET_ADDRESS of the message's destination.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers. * @param DNET_list [in] List of our reachable downstream BACnet Network
* Normally just one valid entry; terminated with a -1 value. * numbers. Normally just one valid entry; terminated with a -1 value.
* @param apdu [in] The apdu portion of the request, to be processed. * @param apdu [in] The apdu portion of the request, to be processed.
* @param apdu_len [in] The total (remaining) length of the apdu. * @param apdu_len [in] The total (remaining) length of the apdu.
*/ */
static void routed_apdu_handler( static void routed_apdu_handler(BACNET_ADDRESS *src, BACNET_ADDRESS *dest,
BACNET_ADDRESS * src, int *DNET_list, uint8_t *apdu,
BACNET_ADDRESS * dest,
int *DNET_list,
uint8_t * apdu,
uint16_t apdu_len) uint16_t apdu_len)
{ {
int cursor = 0; /* Starting hint */ int cursor = 0; /* Starting hint */
@@ -260,15 +253,12 @@ static void routed_apdu_handler(
* think this project's code has any use for the src info * think this project's code has any use for the src info
* on return from this handler, since the response has * on return from this handler, since the response has
* already been sent via the apdu_handler. * already been sent via the apdu_handler.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers. * @param DNET_list [in] List of our reachable downstream BACnet Network
* Normally just one valid entry; terminated with a -1 value. * numbers. Normally just one valid entry; terminated with a -1 value.
* @param pdu [in] Buffer containing the NPDU and APDU of the received packet. * @param pdu [in] Buffer containing the NPDU and APDU of the received packet.
* @param pdu_len [in] The size of the received message in the pdu[] buffer. * @param pdu_len [in] The size of the received message in the pdu[] buffer.
*/ */
void routing_npdu_handler( void routing_npdu_handler(BACNET_ADDRESS *src, int *DNET_list, uint8_t *pdu,
BACNET_ADDRESS * src,
int *DNET_list,
uint8_t * pdu,
uint16_t pdu_len) uint16_t pdu_len)
{ {
int apdu_offset = 0; int apdu_offset = 0;
@@ -283,7 +273,8 @@ void routing_npdu_handler(
} else if (npdu_data.network_layer_message) { } else if (npdu_data.network_layer_message) {
if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) { if ((dest.net == 0) || (dest.net == BACNET_BROADCAST_NETWORK)) {
network_control_handler(src, DNET_list, &npdu_data, network_control_handler(src, DNET_list, &npdu_data,
&pdu[apdu_offset], (uint16_t) (pdu_len - apdu_offset)); &pdu[apdu_offset],
(uint16_t)(pdu_len - apdu_offset));
} else { } else {
/* The DNET is set, but we don't support downstream routers, /* The DNET is set, but we don't support downstream routers,
* so we just silently drop this network layer message, * so we just silently drop this network layer message,
@@ -297,8 +288,8 @@ void routing_npdu_handler(
} }
} else { } else {
/* Should we send NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK? */ /* Should we send NETWORK_MESSAGE_REJECT_MESSAGE_TO_NETWORK? */
debug_printf debug_printf(
("NPDU: Unsupported BACnet Protocol Version=%u. Discarded!\n", "NPDU: Unsupported BACnet Protocol Version=%u. Discarded!\n",
(unsigned)pdu[0]); (unsigned)pdu[0]);
} }
+14 -23
View File
@@ -44,7 +44,6 @@
/** @file h_rp.c Handles Read Property requests. */ /** @file h_rp.c Handles Read Property requests. */
/** Handler for a ReadProperty Service request. /** Handler for a ReadProperty Service request.
* @ingroup DSRP * @ingroup DSRP
* This handler will be invoked by apdu_handler() if it has been enabled * This handler will be invoked by apdu_handler() if it has been enabled
@@ -64,9 +63,7 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_read_property( void handler_read_property(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -85,8 +82,7 @@ void handler_read_property(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
@@ -116,8 +112,7 @@ void handler_read_property(
rpdata.object_instance = Device_Object_Instance_Number(); rpdata.object_instance = Device_Object_Instance_Number();
} }
apdu_len = apdu_len = rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
rp_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id, &rpdata); service_data->invoke_id, &rpdata);
/* configure our storage */ /* configure our storage */
rpdata.application_data = &Handler_Transmit_Buffer[npdu_len + apdu_len]; rpdata.application_data = &Handler_Transmit_Buffer[npdu_len + apdu_len];
@@ -126,9 +121,8 @@ void handler_read_property(
len = Device_Read_Property(&rpdata); len = Device_Read_Property(&rpdata);
if (len >= 0) { if (len >= 0) {
apdu_len += len; apdu_len += len;
len = len = rp_ack_encode_apdu_object_property_end(
rp_ack_encode_apdu_object_property_end(&Handler_Transmit_Buffer &Handler_Transmit_Buffer[npdu_len + apdu_len]);
[npdu_len + apdu_len]);
apdu_len += len; apdu_len += len;
if (apdu_len > service_data->max_resp) { if (apdu_len > service_data->max_resp) {
/* too big for the sender - send an abort /* too big for the sender - send an abort
@@ -163,25 +157,23 @@ void handler_read_property(
RP_FAILURE: RP_FAILURE:
if (error) { if (error) {
if (len == BACNET_STATUS_ABORT) { if (len == BACNET_STATUS_ABORT) {
apdu_len = apdu_len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
abort_convert_error_code(rpdata.error_code), true); abort_convert_error_code(rpdata.error_code), true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RP: Sending Abort!\n"); fprintf(stderr, "RP: Sending Abort!\n");
#endif #endif
} else if (len == BACNET_STATUS_ERROR) { } else if (len == BACNET_STATUS_ERROR) {
apdu_len = apdu_len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROPERTY, SERVICE_CONFIRMED_READ_PROPERTY, rpdata.error_class,
rpdata.error_class, rpdata.error_code); rpdata.error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RP: Sending Error!\n"); fprintf(stderr, "RP: Sending Error!\n");
#endif #endif
} else if (len == BACNET_STATUS_REJECT) { } else if (len == BACNET_STATUS_REJECT) {
apdu_len = apdu_len = reject_encode_apdu(
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
reject_convert_error_code(rpdata.error_code)); reject_convert_error_code(rpdata.error_code));
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RP: Sending Reject!\n"); fprintf(stderr, "RP: Sending Reject!\n");
@@ -190,8 +182,7 @@ void handler_read_property(
} }
pdu_len = npdu_len + apdu_len; pdu_len = npdu_len + apdu_len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
+9 -16
View File
@@ -46,8 +46,7 @@
/** For debugging... /** For debugging...
* @param [in] data portion of the ACK * @param [in] data portion of the ACK
*/ */
void rp_ack_print_data( void rp_ack_print_data(BACNET_READ_PROPERTY_DATA *data)
BACNET_READ_PROPERTY_DATA * data)
{ {
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
@@ -63,9 +62,8 @@ void rp_ack_print_data(
/* FIXME: what if application_data_len is bigger than 255? */ /* FIXME: what if application_data_len is bigger than 255? */
/* value? need to loop until all of the len is gone... */ /* value? need to loop until all of the len is gone... */
for (;;) { for (;;) {
len = len = bacapp_decode_application_data(
bacapp_decode_application_data(application_data, application_data, (uint8_t)application_data_len, &value);
(uint8_t) application_data_len, &value);
if (first_value && (len < application_data_len)) { if (first_value && (len < application_data_len)) {
first_value = false; first_value = false;
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -102,7 +100,6 @@ void rp_ack_print_data(
} }
} }
/** Handler for a ReadProperty ACK. /** Handler for a ReadProperty ACK.
* @ingroup DSRP * @ingroup DSRP
* Doesn't actually do anything, except, for debugging, to * Doesn't actually do anything, except, for debugging, to
@@ -114,9 +111,7 @@ void rp_ack_print_data(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_read_property_ack( void handler_read_property_ack(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
@@ -148,9 +143,7 @@ void handler_read_property_ack(
* or -1 on decoding error. * or -1 on decoding error.
*/ */
int rp_ack_fully_decode_service_request( int rp_ack_fully_decode_service_request(
uint8_t * apdu, uint8_t *apdu, int apdu_len, BACNET_READ_ACCESS_DATA *read_access_data)
int apdu_len,
BACNET_READ_ACCESS_DATA * read_access_data)
{ {
int decoded_len = 0; /* return value */ int decoded_len = 0; /* return value */
BACNET_READ_PROPERTY_DATA rp1data; BACNET_READ_PROPERTY_DATA rp1data;
@@ -174,7 +167,8 @@ int rp_ack_fully_decode_service_request(
} }
rp1_property->propertyIdentifier = rp1data.object_property; rp1_property->propertyIdentifier = rp1data.object_property;
rp1_property->propertyArrayIndex = rp1data.array_index; rp1_property->propertyArrayIndex = rp1data.array_index;
/* Is there no Error case possible here, as there is when decoding RPM? */ /* Is there no Error case possible here, as there is when decoding RPM?
*/
/* rp1_property->error.error_class = ?? */ /* rp1_property->error.error_class = ?? */
/* rp_ack_decode_service_request() processing already removed the /* rp_ack_decode_service_request() processing already removed the
* Opening and Closing '3' Tags. * Opening and Closing '3' Tags.
@@ -187,9 +181,8 @@ int rp_ack_fully_decode_service_request(
old_value = value; old_value = value;
while (value && vdata && (vlen > 0)) { while (value && vdata && (vlen > 0)) {
if (IS_CONTEXT_SPECIFIC(*vdata)) { if (IS_CONTEXT_SPECIFIC(*vdata)) {
len = len = bacapp_decode_context_data(
bacapp_decode_context_data(vdata, vlen, value, vdata, vlen, value, rp1_property->propertyIdentifier);
rp1_property->propertyIdentifier);
} else { } else {
len = bacapp_decode_application_data(vdata, vlen, value); len = bacapp_decode_application_data(vdata, vlen, value);
} }
+48 -70
View File
@@ -50,8 +50,7 @@ static uint8_t Temp_Buf[MAX_APDU] = { 0 };
static BACNET_PROPERTY_ID RPM_Object_Property( static BACNET_PROPERTY_ID RPM_Object_Property(
struct special_property_list_t *pPropertyList, struct special_property_list_t *pPropertyList,
BACNET_PROPERTY_ID special_property, BACNET_PROPERTY_ID special_property, unsigned index)
unsigned index)
{ {
int property = -1; /* return value */ int property = -1; /* return value */
unsigned required, optional, proprietary; unsigned required, optional, proprietary;
@@ -89,8 +88,7 @@ static unsigned RPM_Object_Property_Count(
unsigned count = 0; /* return value */ unsigned count = 0; /* return value */
if (special_property == PROP_ALL) { if (special_property == PROP_ALL) {
count = count = pPropertyList->Required.count + pPropertyList->Optional.count +
pPropertyList->Required.count + pPropertyList->Optional.count +
pPropertyList->Proprietary.count; pPropertyList->Proprietary.count;
} else if (special_property == PROP_REQUIRED) { } else if (special_property == PROP_REQUIRED) {
count = pPropertyList->Required.count; count = pPropertyList->Required.count;
@@ -103,20 +101,16 @@ static unsigned RPM_Object_Property_Count(
/** Encode the RPM property returning the length of the encoding, /** Encode the RPM property returning the length of the encoding,
or 0 if there is no room to fit the encoding. */ or 0 if there is no room to fit the encoding. */
static int RPM_Encode_Property( static int RPM_Encode_Property(uint8_t *apdu, uint16_t offset,
uint8_t * apdu, uint16_t max_apdu, BACNET_RPM_DATA *rpmdata)
uint16_t offset,
uint16_t max_apdu,
BACNET_RPM_DATA * rpmdata)
{ {
int len = 0; int len = 0;
size_t copy_len = 0; size_t copy_len = 0;
int apdu_len = 0; int apdu_len = 0;
BACNET_READ_PROPERTY_DATA rpdata; BACNET_READ_PROPERTY_DATA rpdata;
len = len = rpm_ack_encode_apdu_object_property(
rpm_ack_encode_apdu_object_property(&Temp_Buf[0], &Temp_Buf[0], rpmdata->object_property, rpmdata->array_index);
rpmdata->object_property, rpmdata->array_index);
copy_len = memcopy(&apdu[0], &Temp_Buf[0], offset, len, max_apdu); copy_len = memcopy(&apdu[0], &Temp_Buf[0], offset, len, max_apdu);
if (copy_len == 0) { if (copy_len == 0) {
rpmdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; rpmdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -140,9 +134,8 @@ static int RPM_Encode_Property(
return len; /* Ie, Abort */ return len; /* Ie, Abort */
} }
/* error was returned - encode that for the response */ /* error was returned - encode that for the response */
len = len = rpm_ack_encode_apdu_object_property_error(
rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0], &Temp_Buf[0], rpdata.error_class, rpdata.error_code);
rpdata.error_class, rpdata.error_code);
copy_len = copy_len =
memcopy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len, max_apdu); memcopy(&apdu[0], &Temp_Buf[0], offset + apdu_len, len, max_apdu);
@@ -152,9 +145,8 @@ static int RPM_Encode_Property(
} }
} 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 */ /* enough room to fit the property value and tags */
len = len = rpm_ack_encode_apdu_object_property_value(
rpm_ack_encode_apdu_object_property_value(&apdu[offset + apdu_len], &apdu[offset + apdu_len], &Temp_Buf[0], len);
&Temp_Buf[0], len);
} else { } else {
/* not enough room - abort! */ /* not enough room - abort! */
rpmdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; rpmdata->error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -175,8 +167,8 @@ static int RPM_Encode_Property(
* - if decoding fails * - if decoding fails
* - if the response would be too large * - if the response would be too large
* - the result from each included read request, if it succeeds * - the result from each included read request, if it succeeds
* - an Error if processing fails for all, or individual errors if only some fail, * - an Error if processing fails for all, or individual errors if only some
* or there isn't enough room in the APDU to fit the data. * fail, or there isn't enough room in the APDU to fit the data.
* *
* @param service_request [in] The contents of the service request. * @param service_request [in] The contents of the service request.
* @param service_len [in] The length of the service_request. * @param service_len [in] The length of the service_request.
@@ -184,10 +176,8 @@ static int RPM_Encode_Property(
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_read_property_multiple( void handler_read_property_multiple(uint8_t *service_request,
uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS *src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA *service_data) BACNET_CONFIRMED_SERVICE_DATA *service_data)
{ {
int len = 0; int len = 0;
@@ -203,12 +193,12 @@ void handler_read_property_multiple(
int error = 0; int error = 0;
/* jps_debug - see if we are utilizing all the buffer */ /* 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 */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
rpmdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; rpmdata.error_code = ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -220,13 +210,11 @@ void handler_read_property_multiple(
} }
/* decode apdu request & encode apdu reply /* decode apdu request & encode apdu reply
encode complex ack, invoke id, service choice */ encode complex ack, invoke id, service choice */
apdu_len = apdu_len = rpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
rpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id); service_data->invoke_id);
for (;;) { for (;;) {
/* Start by looking for an object ID */ /* Start by looking for an object ID */
len = len = rpm_decode_object_id(&service_request[decode_len],
rpm_decode_object_id(&service_request[decode_len],
service_len - decode_len, &rpmdata); service_len - decode_len, &rpmdata);
if (len >= 0) { if (len >= 0) {
/* Got one so skip to next stage */ /* Got one so skip to next stage */
@@ -248,9 +236,8 @@ void handler_read_property_multiple(
/* Stick this object id into the reply - if it will fit */ /* Stick this object id into the reply - if it will fit */
len = rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], &rpmdata); len = rpm_ack_encode_apdu_object_begin(&Temp_Buf[0], &rpmdata);
copy_len = copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0],
memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], apdu_len, apdu_len, len, MAX_APDU);
len, MAX_APDU);
if (copy_len == 0) { if (copy_len == 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RPM: Response too big!\r\n"); fprintf(stderr, "RPM: Response too big!\r\n");
@@ -288,11 +275,10 @@ void handler_read_property_multiple(
if (rpmdata.array_index != BACNET_ARRAY_ALL) { if (rpmdata.array_index != BACNET_ARRAY_ALL) {
/* No array index options for this special property. /* No array index options for this special property.
Encode error for this object property response */ Encode error for this object property response */
len = len = rpm_ack_encode_apdu_object_property(
rpm_ack_encode_apdu_object_property(&Temp_Buf[0], &Temp_Buf[0], rpmdata.object_property,
rpmdata.object_property, rpmdata.array_index); rpmdata.array_index);
copy_len = copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len],
memcopy(&Handler_Transmit_Buffer[npdu_len],
&Temp_Buf[0], apdu_len, len, MAX_APDU); &Temp_Buf[0], apdu_len, len, MAX_APDU);
if (copy_len == 0) { if (copy_len == 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -305,12 +291,10 @@ void handler_read_property_multiple(
goto RPM_FAILURE; goto RPM_FAILURE;
} }
apdu_len += len; apdu_len += len;
len = len = rpm_ack_encode_apdu_object_property_error(
rpm_ack_encode_apdu_object_property_error(&Temp_Buf[0], &Temp_Buf[0], ERROR_CLASS_PROPERTY,
ERROR_CLASS_PROPERTY,
ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY); ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY);
copy_len = copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len],
memcopy(&Handler_Transmit_Buffer[npdu_len],
&Temp_Buf[0], apdu_len, len, MAX_APDU); &Temp_Buf[0], apdu_len, len, MAX_APDU);
if (copy_len == 0) { if (copy_len == 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -325,10 +309,10 @@ void handler_read_property_multiple(
} else { } else {
special_object_property = rpmdata.object_property; special_object_property = rpmdata.object_property;
Device_Objects_Property_List(rpmdata.object_type, Device_Objects_Property_List(rpmdata.object_type,
rpmdata.object_instance, &property_list); rpmdata.object_instance,
property_count = &property_list);
RPM_Object_Property_Count(&property_list, property_count = RPM_Object_Property_Count(
special_object_property); &property_list, special_object_property);
if (property_count == 0) { if (property_count == 0) {
/* this only happens with the OPTIONAL property */ /* this only happens with the OPTIONAL property */
/* 135-2016bl-2. Clarify ReadPropertyMultiple /* 135-2016bl-2. Clarify ReadPropertyMultiple
@@ -338,13 +322,11 @@ void handler_read_property_multiple(
for the specified property.*/ for the specified property.*/
} else { } else {
for (index = 0; index < property_count; index++) { for (index = 0; index < property_count; index++) {
rpmdata.object_property = rpmdata.object_property = RPM_Object_Property(
RPM_Object_Property(&property_list, &property_list, special_object_property, index);
special_object_property, index); len = RPM_Encode_Property(
len = &Handler_Transmit_Buffer[npdu_len],
RPM_Encode_Property(&Handler_Transmit_Buffer (uint16_t)apdu_len, MAX_APDU, &rpmdata);
[npdu_len], (uint16_t) apdu_len, MAX_APDU,
&rpmdata);
if (len > 0) { if (len > 0) {
apdu_len += len; apdu_len += len;
} else { } else {
@@ -378,9 +360,8 @@ void handler_read_property_multiple(
/* Reached end of property list so cap the result list */ /* Reached end of property list so cap the result list */
decode_len++; decode_len++;
len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]); len = rpm_ack_encode_apdu_object_end(&Temp_Buf[0]);
copy_len = copy_len = memcopy(&Handler_Transmit_Buffer[npdu_len],
memcopy(&Handler_Transmit_Buffer[npdu_len], &Temp_Buf[0], &Temp_Buf[0], apdu_len, len, MAX_APDU);
apdu_len, len, MAX_APDU);
if (copy_len == 0) { if (copy_len == 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RPM: Too full to encode object end!\r\n"); fprintf(stderr, "RPM: Too full to encode object end!\r\n");
@@ -414,25 +395,23 @@ void handler_read_property_multiple(
RPM_FAILURE: RPM_FAILURE:
if (error) { if (error) {
if (error == BACNET_STATUS_ABORT) { if (error == BACNET_STATUS_ABORT) {
apdu_len = apdu_len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
abort_convert_error_code(rpmdata.error_code), true); abort_convert_error_code(rpmdata.error_code), true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RPM: Sending Abort!\n"); fprintf(stderr, "RPM: Sending Abort!\n");
#endif #endif
} else if (error == BACNET_STATUS_ERROR) { } else if (error == BACNET_STATUS_ERROR) {
apdu_len = apdu_len = bacerror_encode_apdu(
bacerror_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_READ_PROP_MULTIPLE, SERVICE_CONFIRMED_READ_PROP_MULTIPLE, rpmdata.error_class,
rpmdata.error_class, rpmdata.error_code); rpmdata.error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RPM: Sending Error!\n"); fprintf(stderr, "RPM: Sending Error!\n");
#endif #endif
} else if (error == BACNET_STATUS_REJECT) { } else if (error == BACNET_STATUS_REJECT) {
apdu_len = apdu_len = reject_encode_apdu(
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
reject_convert_error_code(rpmdata.error_code)); reject_convert_error_code(rpmdata.error_code));
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RPM: Sending Reject!\n"); fprintf(stderr, "RPM: Sending Reject!\n");
@@ -441,8 +420,7 @@ void handler_read_property_multiple(
} }
pdu_len = apdu_len + npdu_len; pdu_len = apdu_len + npdu_len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
+16 -25
View File
@@ -53,9 +53,7 @@
* where the RPM data is to be stored. * where the RPM data is to be stored.
* @return The number of bytes decoded, or -1 on error * @return The number of bytes decoded, or -1 on error
*/ */
int rpm_ack_decode_service_request( int rpm_ack_decode_service_request(uint8_t *apdu, int apdu_len,
uint8_t * apdu,
int apdu_len,
BACNET_READ_ACCESS_DATA *read_access_data) BACNET_READ_ACCESS_DATA *read_access_data)
{ {
int decoded_len = 0; /* return value */ int decoded_len = 0; /* return value */
@@ -74,8 +72,7 @@ int rpm_ack_decode_service_request(
rpm_object = read_access_data; rpm_object = read_access_data;
old_rpm_object = rpm_object; old_rpm_object = rpm_object;
while (rpm_object && apdu_len) { while (rpm_object && apdu_len) {
len = len = rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type,
rpm_ack_decode_object_id(apdu, apdu_len, &rpm_object->object_type,
&rpm_object->object_instance); &rpm_object->object_instance);
if (len <= 0) { if (len <= 0) {
old_rpm_object->next = NULL; old_rpm_object->next = NULL;
@@ -89,9 +86,8 @@ int rpm_ack_decode_service_request(
rpm_object->listOfProperties = rpm_property; rpm_object->listOfProperties = rpm_property;
old_rpm_property = rpm_property; old_rpm_property = rpm_property;
while (rpm_property && apdu_len) { while (rpm_property && apdu_len) {
len = len = rpm_ack_decode_object_property(
rpm_ack_decode_object_property(apdu, apdu_len, apdu, apdu_len, &rpm_property->propertyIdentifier,
&rpm_property->propertyIdentifier,
&rpm_property->propertyArrayIndex); &rpm_property->propertyArrayIndex);
if (len <= 0) { if (len <= 0) {
old_rpm_property->next = NULL; old_rpm_property->next = NULL;
@@ -117,12 +113,11 @@ int rpm_ack_decode_service_request(
old_value = value; old_value = value;
while (value && (apdu_len > 0)) { while (value && (apdu_len > 0)) {
if (IS_CONTEXT_SPECIFIC(*apdu)) { if (IS_CONTEXT_SPECIFIC(*apdu)) {
len = len = bacapp_decode_context_data(
bacapp_decode_context_data(apdu, apdu_len, value, apdu, apdu_len, value,
rpm_property->propertyIdentifier); rpm_property->propertyIdentifier);
} else { } else {
len = len = bacapp_decode_application_data(apdu, apdu_len,
bacapp_decode_application_data(apdu, apdu_len,
value); value);
} }
/* If len == 0 then it's an empty structure, which is OK. */ /* If len == 0 then it's an empty structure, which is OK. */
@@ -201,8 +196,7 @@ int rpm_ack_decode_service_request(
} }
/* for debugging... */ /* for debugging... */
void rpm_ack_print_data( void rpm_ack_print_data(BACNET_READ_ACCESS_DATA *rpm_data)
BACNET_READ_ACCESS_DATA * rpm_data)
{ {
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_PROPERTY_REFERENCE *listOfProperties; BACNET_PROPERTY_REFERENCE *listOfProperties;
@@ -221,8 +215,8 @@ void rpm_ack_print_data(
#if PRINT_ENABLED #if PRINT_ENABLED
if (listOfProperties->propertyIdentifier < 512) { if (listOfProperties->propertyIdentifier < 512) {
fprintf(stdout, " %s: ", fprintf(stdout, " %s: ",
bactext_property_name(listOfProperties-> bactext_property_name(
propertyIdentifier)); listOfProperties->propertyIdentifier));
} else { } else {
fprintf(stdout, " proprietary %u: ", fprintf(stdout, " proprietary %u: ",
(unsigned)listOfProperties->propertyIdentifier); (unsigned)listOfProperties->propertyIdentifier);
@@ -269,10 +263,10 @@ void rpm_ack_print_data(
#if PRINT_ENABLED #if PRINT_ENABLED
/* AccessError */ /* AccessError */
fprintf(stdout, "BACnet Error: %s: %s\r\n", fprintf(stdout, "BACnet Error: %s: %s\r\n",
bactext_error_class_name((int) listOfProperties-> bactext_error_class_name(
error.error_class), (int)listOfProperties->error.error_class),
bactext_error_code_name((int) listOfProperties-> bactext_error_code_name(
error.error_code)); (int)listOfProperties->error.error_code));
#endif #endif
} }
listOfProperties = listOfProperties->next; listOfProperties = listOfProperties->next;
@@ -295,9 +289,7 @@ void rpm_ack_print_data(
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_read_property_multiple_ack( void handler_read_property_multiple_ack(
uint8_t * service_request, uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
int len = 0; int len = 0;
@@ -313,8 +305,7 @@ void handler_read_property_multiple_ack(
rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA)); rpm_data = calloc(1, sizeof(BACNET_READ_ACCESS_DATA));
if (rpm_data) { if (rpm_data) {
len = len = rpm_ack_decode_service_request(service_request, service_len,
rpm_ack_decode_service_request(service_request, service_len,
rpm_data); rpm_data);
} }
#if 1 #if 1
+37 -33
View File
@@ -45,9 +45,7 @@ static uint8_t Temp_Buf[MAX_APDU] = { 0 };
/* Encodes the property APDU and returns the length, /* Encodes the property APDU and returns the length,
or sets the error, and returns -1 */ or sets the error, and returns -1 */
static int Encode_RR_payload( static int Encode_RR_payload(uint8_t* apdu, BACNET_READ_RANGE_DATA* pRequest)
uint8_t * apdu,
BACNET_READ_RANGE_DATA * pRequest)
{ {
int apdu_len = -1; int apdu_len = -1;
rr_info_function info_fn_ptr = NULL; rr_info_function info_fn_ptr = NULL;
@@ -61,10 +59,15 @@ static int Encode_RR_payload(
info_fn_ptr = Device_Objects_RR_Info(pRequest->object_type); info_fn_ptr = Device_Objects_RR_Info(pRequest->object_type);
if ((info_fn_ptr != NULL) && (info_fn_ptr(pRequest, &PropInfo) != false)) { if ((info_fn_ptr != NULL) && (info_fn_ptr(pRequest, &PropInfo) != false)) {
/* We try and do some of the more generic error checking here to cut down on duplication of effort */ /* We try and do some of the more generic error checking here to cut
* down on duplication of effort */
if ((pRequest->RequestType == RR_BY_POSITION) && (pRequest->Range.RefIndex == 0)) { /* First index is 1 so can't accept 0 */ if ((pRequest->RequestType == RR_BY_POSITION) &&
pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */ (pRequest->Range.RefIndex ==
0)) { /* First index is 1 so can't accept 0 */
pRequest->error_code =
ERROR_CODE_OTHER; /* I couldn't see anything more appropriate
so... */
} else if (((PropInfo.RequestTypes & RR_ARRAY_OF_LISTS) == 0) && } else if (((PropInfo.RequestTypes & RR_ARRAY_OF_LISTS) == 0) &&
(pRequest->array_index != 0) && (pRequest->array_index != 0) &&
(pRequest->array_index != BACNET_ARRAY_ALL)) { (pRequest->array_index != BACNET_ARRAY_ALL)) {
@@ -72,24 +75,30 @@ static int Encode_RR_payload(
pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
} else if ((pRequest->RequestType != RR_READ_ALL) && } else if ((pRequest->RequestType != RR_READ_ALL) &&
((PropInfo.RequestTypes & pRequest->RequestType) == 0)) { ((PropInfo.RequestTypes & pRequest->RequestType) == 0)) {
/* By Time or By Sequence not supported - By Position is always required */ /* By Time or By Sequence not supported - By Position is always
pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */ * required */
} else if ((pRequest->Count == 0) && (pRequest->RequestType != RR_READ_ALL)) { /* Count cannot be zero */ pRequest->error_code =
pRequest->error_code = ERROR_CODE_OTHER; /* I couldn't see anything more appropriate so... */ ERROR_CODE_OTHER; /* I couldn't see anything more appropriate
so... */
} else if ((pRequest->Count == 0) &&
(pRequest->RequestType !=
RR_READ_ALL)) { /* Count cannot be zero */
pRequest->error_code =
ERROR_CODE_OTHER; /* I couldn't see anything more appropriate
so... */
} else if (PropInfo.Handler != NULL) { } else if (PropInfo.Handler != NULL) {
apdu_len = PropInfo.Handler(apdu, pRequest); apdu_len = PropInfo.Handler(apdu, pRequest);
} }
} else { } else {
/* Either we don't support RR for this property yet or it is not a list or array of lists */ /* Either we don't support RR for this property yet or it is not a list
* or array of lists */
pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_A_LIST; pRequest->error_code = ERROR_CODE_PROPERTY_IS_NOT_A_LIST;
} }
return apdu_len; return apdu_len;
} }
void handler_read_range( void handler_read_range(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -106,15 +115,13 @@ void handler_read_range(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
if (service_data->segmented_message) { if (service_data->segmented_message) {
/* we don't support segmentation - send an abort */ /* we don't support segmentation - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RR: Segmented message. Sending Abort!\n"); fprintf(stderr, "RR: Segmented message. Sending Abort!\n");
#endif #endif
@@ -128,9 +135,9 @@ void handler_read_range(
#endif #endif
if (len < 0) { if (len < 0) {
/* bad decoding - send an abort */ /* bad decoding - send an abort */
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "RR: Bad Encoding. Sending Abort!\n");
#endif #endif
@@ -145,8 +152,7 @@ void handler_read_range(
data.application_data = &Temp_Buf[0]; data.application_data = &Temp_Buf[0];
data.application_data_len = len; data.application_data_len = len;
/* FIXME: probably need a length limitation sent with encode */ /* FIXME: probably need a length limitation sent with encode */
len = len = rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
rr_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
service_data->invoke_id, &data); service_data->invoke_id, &data);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RR: Sending Ack!\n"); fprintf(stderr, "RR: Sending Ack!\n");
@@ -156,17 +162,16 @@ void handler_read_range(
if (error) { if (error) {
if (len == -2) { if (len == -2) {
/* BACnet APDU too small to fit data, so proper response is Abort */ /* BACnet APDU too small to fit data, so proper response is Abort */
len = len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id,
ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true); ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RR: Reply too big to fit into APDU!\n"); fprintf(stderr, "RR: Reply too big to fit into APDU!\n");
#endif #endif
} else { } else {
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_READ_RANGE, SERVICE_CONFIRMED_READ_RANGE,
data.error_class, data.error_code); data.error_class, data.error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "RR: Sending Error!\n"); fprintf(stderr, "RR: Sending Error!\n");
@@ -175,8 +180,7 @@ void handler_read_range(
} }
RR_ABORT: RR_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
+4 -8
View File
@@ -43,8 +43,7 @@
/** @file h_rr_a.c Handles Read Range Acknowledgments. */ /** @file h_rr_a.c Handles Read Range Acknowledgments. */
/* for debugging... */ /* for debugging... */
static void PrintReadRangeData( static void PrintReadRangeData(BACNET_READ_RANGE_DATA *data)
BACNET_READ_RANGE_DATA * data)
{ {
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
@@ -60,9 +59,8 @@ static void PrintReadRangeData(
/* FIXME: what if application_data_len is bigger than 255? */ /* FIXME: what if application_data_len is bigger than 255? */
/* value? need to loop until all of the len is gone... */ /* value? need to loop until all of the len is gone... */
for (;;) { for (;;) {
len = len = bacapp_decode_application_data(
bacapp_decode_application_data(application_data, application_data, (uint8_t)application_data_len, &value);
(uint8_t) application_data_len, &value);
if (first_value && (len < application_data_len)) { if (first_value && (len < application_data_len)) {
first_value = false; first_value = false;
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -99,9 +97,7 @@ static void PrintReadRangeData(
} }
} }
void handler_read_range_ack( void handler_read_range_ack(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src, BACNET_ADDRESS *src,
BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data) BACNET_CONFIRMED_SERVICE_ACK_DATA *service_data)
{ {
+13 -31
View File
@@ -49,9 +49,7 @@ static BACNET_DATE_TIME Next_Sync_Time;
#endif #endif
#if PRINT_ENABLED #if PRINT_ENABLED
static void show_bacnet_date_time( static void show_bacnet_date_time(BACNET_DATE *bdate, BACNET_TIME *btime)
BACNET_DATE * bdate,
BACNET_TIME * btime)
{ {
/* show the date received */ /* show the date received */
fprintf(stderr, "%u", (unsigned)bdate->year); fprintf(stderr, "%u", (unsigned)bdate->year);
@@ -66,9 +64,7 @@ static void show_bacnet_date_time(
} }
#endif #endif
void handler_timesync( void handler_timesync(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src) BACNET_ADDRESS *src)
{ {
int len = 0; int len = 0;
@@ -77,8 +73,7 @@ void handler_timesync(
(void)src; (void)src;
(void)service_len; (void)service_len;
len = len = timesync_decode_service_request(service_request, service_len, &bdate,
timesync_decode_service_request(service_request, service_len, &bdate,
&btime); &btime);
if (len > 0) { if (len > 0) {
if (datetime_is_valid(&bdate, &btime)) { if (datetime_is_valid(&bdate, &btime)) {
@@ -96,9 +91,7 @@ void handler_timesync(
return; return;
} }
void handler_timesync_utc( void handler_timesync_utc(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src) BACNET_ADDRESS *src)
{ {
int len = 0; int len = 0;
@@ -107,8 +100,7 @@ void handler_timesync_utc(
(void)src; (void)src;
(void)service_len; (void)service_len;
len = len = timesync_decode_service_request(service_request, service_len, &bdate,
timesync_decode_service_request(service_request, service_len, &bdate,
&btime); &btime);
if (len > 0) { if (len > 0) {
if (datetime_is_valid(&bdate, &btime)) { if (datetime_is_valid(&bdate, &btime)) {
@@ -138,9 +130,7 @@ void handler_timesync_utc(
* @return How many bytes were encoded in the buffer, or * @return How many bytes were encoded in the buffer, or
* BACNET_STATUS_ABORT if the response would not fit within the buffer. * BACNET_STATUS_ABORT if the response would not fit within the buffer.
*/ */
int handler_timesync_encode_recipients( int handler_timesync_encode_recipients(uint8_t *apdu, int max_apdu)
uint8_t * apdu,
int max_apdu)
{ {
return timesync_encode_timesync_recipients(apdu, max_apdu, return timesync_encode_timesync_recipients(apdu, max_apdu,
&Time_Sync_Recipients[0]); &Time_Sync_Recipients[0]);
@@ -148,8 +138,7 @@ int handler_timesync_encode_recipients(
#endif #endif
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
bool handler_timesync_recipient_write( bool handler_timesync_recipient_write(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; bool status = false;
@@ -162,8 +151,7 @@ bool handler_timesync_recipient_write(
#endif #endif
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
static void handler_timesync_send( static void handler_timesync_send(BACNET_DATE_TIME *current_date_time)
BACNET_DATE_TIME * current_date_time)
{ {
unsigned index = 0; unsigned index = 0;
bool status = false; bool status = false;
@@ -171,8 +159,7 @@ static void handler_timesync_send(
for (index = 0; index < MAX_TIME_SYNC_RECIPIENTS; index++) { for (index = 0; index < MAX_TIME_SYNC_RECIPIENTS; index++) {
if (Time_Sync_Recipients[index].tag == 1) { if (Time_Sync_Recipients[index].tag == 1) {
if (status) { if (status) {
Send_TimeSync_Remote( Send_TimeSync_Remote(&Time_Sync_Recipients[index].type.address,
&Time_Sync_Recipients[index].type.address,
&current_date_time->date, &current_date_time->date,
&current_date_time->time); &current_date_time->time);
} }
@@ -182,8 +169,7 @@ static void handler_timesync_send(
#endif #endif
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
static void handler_timesync_update( static void handler_timesync_update(uint32_t device_interval,
uint32_t device_interval,
BACNET_DATE_TIME *current_date_time) BACNET_DATE_TIME *current_date_time)
{ {
uint32_t current_minutes = 0; uint32_t current_minutes = 0;
@@ -242,17 +228,14 @@ static void handler_timesync_update(
#endif #endif
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
bool handler_timesync_recipient_address_set( bool handler_timesync_recipient_address_set(unsigned index,
unsigned index,
BACNET_ADDRESS *address) BACNET_ADDRESS *address)
{ {
bool status = false; bool status = false;
if (address && (index < MAX_TIME_SYNC_RECIPIENTS)) { if (address && (index < MAX_TIME_SYNC_RECIPIENTS)) {
Time_Sync_Recipients[index].tag = 1; Time_Sync_Recipients[index].tag = 1;
bacnet_address_copy( bacnet_address_copy(&Time_Sync_Recipients[index].type.address, address);
&Time_Sync_Recipients[index].type.address,
address);
status = true; status = true;
} }
@@ -261,8 +244,7 @@ bool handler_timesync_recipient_address_set(
#endif #endif
#if defined(BACNET_TIME_MASTER) #if defined(BACNET_TIME_MASTER)
void handler_timesync_task( void handler_timesync_task(BACNET_DATE_TIME *current_date_time)
BACNET_DATE_TIME * current_date_time)
{ {
int compare = 0; int compare = 0;
uint32_t device_interval = 0; uint32_t device_interval = 0;
+7 -9
View File
@@ -57,9 +57,7 @@
* @param service_len [in] The length of the service_request. * @param service_len [in] The length of the service_request.
* @param src [in] BACNET_ADDRESS of the source of the message (unused) * @param src [in] BACNET_ADDRESS of the source of the message (unused)
*/ */
void handler_ucov_notification( void handler_ucov_notification(uint8_t *service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS *src) BACNET_ADDRESS *src)
{ {
BACNET_COV_DATA cov_data; BACNET_COV_DATA cov_data;
@@ -77,14 +75,14 @@ void handler_ucov_notification(
fprintf(stderr, "UCOV: Received Notification!\n"); fprintf(stderr, "UCOV: Received Notification!\n");
#endif #endif
/* decode the service request only */ /* decode the service request only */
len = len = cov_notify_decode_service_request(service_request, service_len,
cov_notify_decode_service_request(service_request, service_len,
&cov_data); &cov_data);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len > 0) { if (len > 0) {
fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier); fprintf(stderr, "UCOV: PID=%u ", cov_data.subscriberProcessIdentifier);
fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier); fprintf(stderr, "instance=%u ", cov_data.initiatingDeviceIdentifier);
fprintf(stderr, "%s %u ", fprintf(
stderr, "%s %u ",
bactext_object_type_name(cov_data.monitoredObjectIdentifier.type), bactext_object_type_name(cov_data.monitoredObjectIdentifier.type),
cov_data.monitoredObjectIdentifier.instance); cov_data.monitoredObjectIdentifier.instance);
fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining); fprintf(stderr, "time remaining=%u seconds ", cov_data.timeRemaining);
@@ -93,9 +91,9 @@ void handler_ucov_notification(
while (pProperty_value) { while (pProperty_value) {
fprintf(stderr, "UCOV: "); fprintf(stderr, "UCOV: ");
if (pProperty_value->propertyIdentifier < 512) { if (pProperty_value->propertyIdentifier < 512) {
fprintf(stderr, "%s ", fprintf(
bactext_property_name stderr, "%s ",
(pProperty_value->propertyIdentifier)); bactext_property_name(pProperty_value->propertyIdentifier));
} else { } else {
fprintf(stderr, "proprietary %u ", fprintf(stderr, "proprietary %u ",
pProperty_value->propertyIdentifier); pProperty_value->propertyIdentifier);
+5 -9
View File
@@ -39,8 +39,7 @@
/** @file h_upt.c Handles Unconfirmed Private Transfer requests. */ /** @file h_upt.c Handles Unconfirmed Private Transfer requests. */
void private_transfer_print_data( void private_transfer_print_data(BACNET_PRIVATE_TRANSFER_DATA *private_data)
BACNET_PRIVATE_TRANSFER_DATA *private_data)
{ {
BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */ BACNET_OBJECT_PROPERTY_VALUE object_value; /* for bacapp printing */
BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */ BACNET_APPLICATION_DATA_VALUE value; /* for decode value data */
@@ -60,9 +59,8 @@ void private_transfer_print_data(
application_data = private_data->serviceParameters; application_data = private_data->serviceParameters;
application_data_len = private_data->serviceParametersLen; application_data_len = private_data->serviceParametersLen;
for (;;) { for (;;) {
len = len = bacapp_decode_application_data(
bacapp_decode_application_data(application_data, application_data, (uint8_t)application_data_len, &value);
(uint8_t) application_data_len, &value);
if (first_value && (len < application_data_len)) { if (first_value && (len < application_data_len)) {
first_value = false; first_value = false;
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -101,8 +99,7 @@ void private_transfer_print_data(
} }
} }
void handler_unconfirmed_private_transfer( void handler_unconfirmed_private_transfer(uint8_t *service_request,
uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS *src) BACNET_ADDRESS *src)
{ {
@@ -112,8 +109,7 @@ void handler_unconfirmed_private_transfer(
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n"); fprintf(stderr, "Received Unconfirmed Private Transfer Request!\n");
#endif #endif
len = len = ptransfer_decode_service_request(service_request, service_len,
ptransfer_decode_service_request(service_request, service_len,
&private_data); &private_data);
if (len >= 0) { if (len >= 0) {
private_transfer_print_data(&private_data); private_transfer_print_data(&private_data);
+18 -22
View File
@@ -42,8 +42,7 @@
* or object ID, if the Device has a match. * or object ID, if the Device has a match.
* @param data [in] The decoded who-has payload from the request. * @param data [in] The decoded who-has payload from the request.
*/ */
static void match_name_or_object( static void match_name_or_object(BACNET_WHO_HAS_DATA* data)
BACNET_WHO_HAS_DATA * data)
{ {
int object_type = 0; int object_type = 0;
uint32_t object_instance = 0; uint32_t object_instance = 0;
@@ -54,8 +53,7 @@ static void match_name_or_object(
note: we should have only 1 of such an object */ note: we should have only 1 of such an object */
if (data->is_object_name) { if (data->is_object_name) {
/* valid name in my device? */ /* valid name in my device? */
found = found = Device_Valid_Object_Name(&data->object.name, &object_type,
Device_Valid_Object_Name(&data->object.name, &object_type,
&object_instance); &object_instance);
if (found) { if (found) {
Send_I_Have(Device_Object_Instance_Number(), Send_I_Have(Device_Object_Instance_Number(),
@@ -64,10 +62,9 @@ static void match_name_or_object(
} }
} else { } else {
/* valid object_name copy in my device? */ /* valid object_name copy in my device? */
found = found = Device_Object_Name_Copy(
Device_Object_Name_Copy((BACNET_OBJECT_TYPE) data-> (BACNET_OBJECT_TYPE)data->object.identifier.type,
object.identifier.type, data->object.identifier.instance, data->object.identifier.instance, &object_name);
&object_name);
if (found) { if (found) {
Send_I_Have(Device_Object_Instance_Number(), Send_I_Have(Device_Object_Instance_Number(),
(BACNET_OBJECT_TYPE)data->object.identifier.type, (BACNET_OBJECT_TYPE)data->object.identifier.type,
@@ -76,7 +73,6 @@ static void match_name_or_object(
} }
} }
/** Handler for Who-Has requests, with broadcast I-Have response. /** Handler for Who-Has requests, with broadcast I-Have response.
* Will respond if the device Object ID matches, and we have * Will respond if the device Object ID matches, and we have
* the Object or Object Name requested. * the Object or Object Name requested.
@@ -86,9 +82,7 @@ static void match_name_or_object(
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source. * @param src [in] The BACNET_ADDRESS of the message's source.
*/ */
void handler_who_has( void handler_who_has(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
@@ -100,8 +94,9 @@ void handler_who_has(
if (len > 0) { if (len > 0) {
if ((data.low_limit == -1) || (data.high_limit == -1)) if ((data.low_limit == -1) || (data.high_limit == -1))
directed_to_me = true; directed_to_me = true;
else if ((Device_Object_Instance_Number() >= (uint32_t) data.low_limit) else if ((Device_Object_Instance_Number() >=
&& (Device_Object_Instance_Number() <= (uint32_t) data.high_limit)) (uint32_t)data.low_limit) &&
(Device_Object_Instance_Number() <= (uint32_t)data.high_limit))
directed_to_me = true; directed_to_me = true;
if (directed_to_me) { if (directed_to_me) {
match_name_or_object(&data); match_name_or_object(&data);
@@ -109,10 +104,12 @@ void handler_who_has(
} }
} }
#ifdef BAC_ROUTING /* was for BAC_ROUTING - delete in 2/2012 if still unused \
#ifdef BAC_ROUTING /* was for BAC_ROUTING - delete in 2/2012 if still unused */ */
/* EKH: I restored this to BAC_ROUTING (from DEPRECATED) because I found that the server demo with the built-in /* EKH: I restored this to BAC_ROUTING (from DEPRECATED) because I found that
virtual Router did not insert the SADRs of the virtual devices on the virtual network without it */ the server demo with the built-in
virtual Router did not insert the SADRs of the virtual devices on the virtual
network without it */
/** Handler for Who-Has requests in the virtual routing setup, /** Handler for Who-Has requests in the virtual routing setup,
* with broadcast I-Have response. * with broadcast I-Have response.
@@ -124,9 +121,7 @@ void handler_who_has(
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source (ignored). * @param src [in] The BACNET_ADDRESS of the message's source (ignored).
*/ */
void handler_who_has_for_routing( void handler_who_has_for_routing(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
@@ -141,7 +136,8 @@ void handler_who_has_for_routing(
if (len > 0) { if (len > 0) {
/* Go through all devices, starting with the root gateway Device */ /* Go through all devices, starting with the root gateway Device */
memset(&bcast_net, 0, sizeof(BACNET_ADDRESS)); memset(&bcast_net, 0, sizeof(BACNET_ADDRESS));
bcast_net.net = BACNET_BROADCAST_NETWORK; /* That's all we have to set */ bcast_net.net =
BACNET_BROADCAST_NETWORK; /* That's all we have to set */
while (Routed_Device_GetNext(&bcast_net, my_list, &cursor)) { while (Routed_Device_GetNext(&bcast_net, my_list, &cursor)) {
dev_instance = Device_Object_Instance_Number(); dev_instance = Device_Object_Instance_Number();
if ((data.low_limit == -1) || (data.high_limit == -1) || if ((data.low_limit == -1) || (data.high_limit == -1) ||
+22 -34
View File
@@ -47,9 +47,7 @@
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source (ignored). * @param src [in] The BACNET_ADDRESS of the message's source (ignored).
*/ */
void handler_who_is( void handler_who_is(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
@@ -57,8 +55,7 @@ void handler_who_is(
int32_t high_limit = 0; int32_t high_limit = 0;
(void)src; (void)src;
len = len = whois_decode_service_request(service_request, service_len, &low_limit,
whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit); &high_limit);
if (len == 0) { if (len == 0) {
Send_I_Am(&Handler_Transmit_Buffer[0]); Send_I_Am(&Handler_Transmit_Buffer[0]);
@@ -73,24 +70,22 @@ void handler_who_is(
return; return;
} }
/** Handler for Who-Is requests, with Unicast I-Am response (per Addendum 135-2004q). /** Handler for Who-Is requests, with Unicast I-Am response (per Addendum
* 135-2004q).
* @ingroup DMDDB * @ingroup DMDDB
* @param service_request [in] The received message to be handled. * @param service_request [in] The received message to be handled.
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source that the * @param src [in] The BACNET_ADDRESS of the message's source that the
* response will be sent back to. * response will be sent back to.
*/ */
void handler_who_is_unicast( void handler_who_is_unicast(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
int len = 0; int len = 0;
int32_t low_limit = 0; int32_t low_limit = 0;
int32_t high_limit = 0; int32_t high_limit = 0;
len = len = whois_decode_service_request(service_request, service_len, &low_limit,
whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit); &high_limit);
/* If no limits, then always respond */ /* If no limits, then always respond */
if (len == 0) { if (len == 0) {
@@ -106,11 +101,12 @@ void handler_who_is_unicast(
return; return;
} }
#ifdef BAC_ROUTING /* was for BAC_ROUTING - delete in 2/2012 if still unused \
#ifdef BAC_ROUTING /* was for BAC_ROUTING - delete in 2/2012 if still unused */ */
/* EKH: I restored this to BAC_ROUTING (from DEPRECATED) because I found that the server demo with the built-in /* EKH: I restored this to BAC_ROUTING (from DEPRECATED) because I found that
virtual Router did not insert the SADRs of the virtual devices on the virtual network without it */ the server demo with the built-in
virtual Router did not insert the SADRs of the virtual devices on the virtual
network without it */
/** Local function to check Who-Is requests against our Device IDs. /** Local function to check Who-Is requests against our Device IDs.
* Will check the gateway (root Device) and all virtual routed * Will check the gateway (root Device) and all virtual routed
@@ -120,12 +116,11 @@ void handler_who_is_unicast(
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source. * @param src [in] The BACNET_ADDRESS of the message's source.
* @param is_unicast [in] True if should send unicast response(s) * @param is_unicast [in] True if should send unicast response(s)
* back to the src, else False if should broadcast response(s). * back to the src, else False if should broadcast
* response(s).
*/ */
static void check_who_is_for_routing( static void check_who_is_for_routing(uint8_t* service_request,
uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS* src,
uint16_t service_len,
BACNET_ADDRESS * src,
bool is_unicast) bool is_unicast)
{ {
int len = 0; int len = 0;
@@ -136,8 +131,7 @@ static void check_who_is_for_routing(
int my_list[2] = {0, -1}; /* Not really used, so dummy values */ int my_list[2] = {0, -1}; /* Not really used, so dummy values */
BACNET_ADDRESS bcast_net; BACNET_ADDRESS bcast_net;
len = len = whois_decode_service_request(service_request, service_len, &low_limit,
whois_decode_service_request(service_request, service_len, &low_limit,
&high_limit); &high_limit);
if (len == BACNET_STATUS_ERROR) { if (len == BACNET_STATUS_ERROR) {
/* Invalid; just leave */ /* Invalid; just leave */
@@ -150,18 +144,16 @@ static void check_who_is_for_routing(
while (Routed_Device_GetNext(&bcast_net, my_list, &cursor)) { while (Routed_Device_GetNext(&bcast_net, my_list, &cursor)) {
dev_instance = Device_Object_Instance_Number(); dev_instance = Device_Object_Instance_Number();
/* If len == 0, no limits and always respond */ /* If len == 0, no limits and always respond */
if ((len == 0) || ((dev_instance >= low_limit) && if ((len == 0) ||
(dev_instance <= high_limit))) { ((dev_instance >= low_limit) && (dev_instance <= high_limit))) {
if (is_unicast) if (is_unicast)
Send_I_Am_Unicast(&Handler_Transmit_Buffer[0], src); Send_I_Am_Unicast(&Handler_Transmit_Buffer[0], src);
else else
Send_I_Am(&Handler_Transmit_Buffer[0]); Send_I_Am(&Handler_Transmit_Buffer[0]);
} }
} }
} }
/** Handler for Who-Is requests in the virtual routing setup, /** Handler for Who-Is requests in the virtual routing setup,
* with broadcast I-Am response(s). * with broadcast I-Am response(s).
* @ingroup DMDDB * @ingroup DMDDB
@@ -173,15 +165,12 @@ static void check_who_is_for_routing(
* @param service_len [in] Length of the service_request message. * @param service_len [in] Length of the service_request message.
* @param src [in] The BACNET_ADDRESS of the message's source (ignored). * @param src [in] The BACNET_ADDRESS of the message's source (ignored).
*/ */
void handler_who_is_bcast_for_routing( void handler_who_is_bcast_for_routing(uint8_t* service_request,
uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS* src)
uint16_t service_len,
BACNET_ADDRESS * src)
{ {
check_who_is_for_routing(service_request, service_len, src, false); check_who_is_for_routing(service_request, service_len, src, false);
} }
/** Handler for Who-Is requests in the virtual routing setup, /** Handler for Who-Is requests in the virtual routing setup,
* with unicast I-Am response(s) returned to the src. * with unicast I-Am response(s) returned to the src.
* Will check the gateway (root Device) and all virtual routed * Will check the gateway (root Device) and all virtual routed
@@ -193,8 +182,7 @@ void handler_who_is_bcast_for_routing(
* @param src [in] The BACNET_ADDRESS of the message's source that the * @param src [in] The BACNET_ADDRESS of the message's source that the
* response will be sent back to. * response will be sent back to.
*/ */
void handler_who_is_unicast_for_routing( void handler_who_is_unicast_for_routing(uint8_t* service_request,
uint8_t * service_request,
uint16_t service_len, uint16_t service_len,
BACNET_ADDRESS* src) BACNET_ADDRESS* src)
{ {
+24 -35
View File
@@ -42,7 +42,6 @@
/** @file h_wp.c Handles Write Property requests. */ /** @file h_wp.c Handles Write Property requests. */
/** Handler for a WriteProperty Service request. /** Handler for a WriteProperty Service request.
* @ingroup DSWP * @ingroup DSWP
* This handler will be invoked by apdu_handler() if it has been enabled * This handler will be invoked by apdu_handler() if it has been enabled
@@ -61,9 +60,7 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_write_property( void handler_write_property(uint8_t* service_request, uint16_t service_len,
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS* src, BACNET_ADDRESS* src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
@@ -77,17 +74,15 @@ void handler_write_property(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WP: Received Request!\n"); fprintf(stderr, "WP: Received Request!\n");
#endif #endif
if (service_data->segmented_message) { if (service_data->segmented_message) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, ABORT_REASON_SEGMENTATION_NOT_SUPPORTED, true);
true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WP: Segmented message. Sending Abort!\n"); fprintf(stderr, "WP: Segmented message. Sending Abort!\n");
#endif #endif
@@ -96,7 +91,8 @@ void handler_write_property(
len = wp_decode_service_request(service_request, service_len, &wp_data); len = wp_decode_service_request(service_request, service_len, &wp_data);
#if PRINT_ENABLED #if PRINT_ENABLED
if (len > 0) if (len > 0)
fprintf(stderr, fprintf(
stderr,
"WP: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n", "WP: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n",
(unsigned long)wp_data.object_type, (unsigned long)wp_data.object_type,
(unsigned long)wp_data.object_instance, (unsigned long)wp_data.object_instance,
@@ -107,25 +103,25 @@ void handler_write_property(
#endif #endif
/* bad decoding or something we didn't understand - send an abort */ /* bad decoding or something we didn't understand - send an abort */
if (len <= 0) { if (len <= 0) {
len = len = abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
abort_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id, ABORT_REASON_OTHER,
service_data->invoke_id, ABORT_REASON_OTHER, true); true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WP: Bad Encoding. Sending Abort!\n"); fprintf(stderr, "WP: Bad Encoding. Sending Abort!\n");
#endif #endif
goto WP_ABORT; goto WP_ABORT;
} }
if (Device_Write_Property(&wp_data)) { if (Device_Write_Property(&wp_data)) {
len = len = encode_simple_ack(&Handler_Transmit_Buffer[pdu_len],
encode_simple_ack(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY); SERVICE_CONFIRMED_WRITE_PROPERTY);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WP: Sending Simple Ack!\n"); fprintf(stderr, "WP: Sending Simple Ack!\n");
#endif #endif
} else { } else {
len = len = bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
bacerror_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, SERVICE_CONFIRMED_WRITE_PROPERTY, SERVICE_CONFIRMED_WRITE_PROPERTY,
wp_data.error_class, wp_data.error_code); wp_data.error_class, wp_data.error_code);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WP: Sending Error!\n"); fprintf(stderr, "WP: Sending Error!\n");
@@ -133,8 +129,7 @@ void handler_write_property(
} }
WP_ABORT: WP_ABORT:
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
@@ -145,18 +140,14 @@ void handler_write_property(
return; return;
} }
/** Perform basic validation of Write Property argument based on /** Perform basic validation of Write Property argument based on
* the assumption that it is a string. Check for correct data type, * the assumption that it is a string. Check for correct data type,
* correct encoding (fixed here as ANSI X34),correct length, and * correct encoding (fixed here as ANSI X34),correct length, and
* finally if it is allowed to be empty. * finally if it is allowed to be empty.
*/ */
bool WPValidateString( bool WPValidateString(BACNET_APPLICATION_DATA_VALUE* pValue, int iMaxLen,
BACNET_APPLICATION_DATA_VALUE * pValue, bool bEmptyAllowed, BACNET_ERROR_CLASS* pErrorClass,
int iMaxLen,
bool bEmptyAllowed,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE* pErrorCode) BACNET_ERROR_CODE* pErrorCode)
{ {
bool bResult; bool bResult;
@@ -172,11 +163,11 @@ bool WPValidateString(
if (characterstring_encoding(&pValue->type.Character_String) == if (characterstring_encoding(&pValue->type.Character_String) ==
CHARACTER_ANSI_X34) { CHARACTER_ANSI_X34) {
if ((bEmptyAllowed == false) && if ((bEmptyAllowed == false) &&
(characterstring_length(&pValue->type.Character_String) == (characterstring_length(&pValue->type.Character_String) == 0)) {
0)) {
*pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE; *pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if ((bEmptyAllowed == false) && } else if ((bEmptyAllowed == false) &&
(!characterstring_printable(&pValue->type.Character_String))) { (!characterstring_printable(
&pValue->type.Character_String))) {
/* assumption: non-empty also means must be "printable" */ /* assumption: non-empty also means must be "printable" */
*pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE; *pErrorCode = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (characterstring_length(&pValue->type.Character_String) > } else if (characterstring_length(&pValue->type.Character_String) >
@@ -198,10 +189,8 @@ bool WPValidateString(
* validation fails. Cuts out reams of repeated code in the object code. * validation fails. Cuts out reams of repeated code in the object code.
*/ */
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE* pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS* pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE* pErrorCode) BACNET_ERROR_CODE* pErrorCode)
{ {
bool bResult; bool bResult;
+25 -29
View File
@@ -44,7 +44,6 @@
/** @file h_wpm.c Handles Write Property Multiple requests. */ /** @file h_wpm.c Handles Write Property Multiple requests. */
/** Handler for a WriteProperty Service request. /** Handler for a WriteProperty Service request.
* @ingroup DSWP * @ingroup DSWP
* This handler will be invoked by apdu_handler() if it has been enabled * This handler will be invoked by apdu_handler() if it has been enabled
@@ -63,9 +62,7 @@
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_write_property_multiple( void handler_write_property_multiple(
uint8_t * service_request, uint8_t* service_request, uint16_t service_len, BACNET_ADDRESS* src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
int len = 0; int len = 0;
@@ -92,8 +89,7 @@ void handler_write_property_multiple(
decode_len = 0; decode_len = 0;
do { do {
/* decode Object Identifier */ /* decode Object Identifier */
len = len = wpm_decode_object_id(&service_request[decode_len],
wpm_decode_object_id(&service_request[decode_len],
service_len - decode_len, &wp_data); service_len - decode_len, &wp_data);
if (len > 0) { if (len > 0) {
uint8_t tag_number = 0; uint8_t tag_number = 0;
@@ -103,16 +99,19 @@ void handler_write_property_multiple(
if (decode_is_opening_tag_number(&service_request[decode_len++], if (decode_is_opening_tag_number(&service_request[decode_len++],
1)) { 1)) {
do { do {
/* decode a 'Property Identifier'; (3) an optional 'Property Array Index' */ /* decode a 'Property Identifier'; (3) an optional 'Property
/* (4) a 'Property Value'; and (5) an optional 'Priority'. */ * Array Index' */
len = /* (4) a 'Property Value'; and (5) an optional 'Priority'.
wpm_decode_object_property(&service_request */
[decode_len], service_len - decode_len, &wp_data); len = wpm_decode_object_property(
&service_request[decode_len], service_len - decode_len,
&wp_data);
if (len > 0) { if (len > 0) {
decode_len += len; decode_len += len;
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"WPM: type=%lu instance=%lu property=%lu priority=%lu index=%ld\n", "WPM: type=%lu instance=%lu property=%lu "
"priority=%lu index=%ld\n",
(unsigned long)wp_data.object_type, (unsigned long)wp_data.object_type,
(unsigned long)wp_data.object_instance, (unsigned long)wp_data.object_instance,
(unsigned long)wp_data.object_property, (unsigned long)wp_data.object_property,
@@ -133,15 +132,17 @@ void handler_write_property_multiple(
} }
/* Closing tag 1 - List of Properties */ /* Closing tag 1 - List of Properties */
if (decode_is_closing_tag_number(&service_request if (decode_is_closing_tag_number(
[decode_len], 1)) { &service_request[decode_len], 1)) {
tag_number = 1; tag_number = 1;
decode_len++; decode_len++;
} else } else
tag_number = 0; /* it was not tag 1, decode next Property Identifier ... */ tag_number = 0; /* it was not tag 1, decode next
Property Identifier ... */
} } while (
while (tag_number != 1); /* end decoding List of Properties for "that" object */ tag_number !=
1); /* end decoding List of Properties for "that" object */
if (error) { if (error) {
goto WPM_ABORT; goto WPM_ABORT;
@@ -160,16 +161,14 @@ void handler_write_property_multiple(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
apdu_len = 0; apdu_len = 0;
/* handle any errors */ /* handle any errors */
if (error) { if (error) {
if (len == BACNET_STATUS_ABORT) { if (len == BACNET_STATUS_ABORT) {
apdu_len = apdu_len = abort_encode_apdu(
abort_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
abort_convert_error_code(wp_data.error_code), true); abort_convert_error_code(wp_data.error_code), true);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WPM: Sending Abort!\n"); fprintf(stderr, "WPM: Sending Abort!\n");
@@ -182,17 +181,15 @@ void handler_write_property_multiple(
fprintf(stderr, "WPM: Sending Error!\n"); fprintf(stderr, "WPM: Sending Error!\n");
#endif #endif
} else if (len == BACNET_STATUS_REJECT) { } else if (len == BACNET_STATUS_REJECT) {
apdu_len = apdu_len = reject_encode_apdu(
reject_encode_apdu(&Handler_Transmit_Buffer[npdu_len], &Handler_Transmit_Buffer[npdu_len], service_data->invoke_id,
service_data->invoke_id,
reject_convert_error_code(wp_data.error_code)); reject_convert_error_code(wp_data.error_code));
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WPM: Sending Reject!\n"); fprintf(stderr, "WPM: Sending Reject!\n");
#endif #endif
} }
} else { } else {
apdu_len = apdu_len = wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
wpm_ack_encode_apdu_init(&Handler_Transmit_Buffer[npdu_len],
service_data->invoke_id); service_data->invoke_id);
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "WPM: Sending Ack!\n"); fprintf(stderr, "WPM: Sending Ack!\n");
@@ -200,8 +197,7 @@ void handler_write_property_multiple(
} }
pdu_len = npdu_len + apdu_len; pdu_len = npdu_len + apdu_len;
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
+7 -11
View File
@@ -49,10 +49,8 @@
* @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information * @param service_data [in] The BACNET_CONFIRMED_SERVICE_DATA information
* decoded from the APDU header of this message. * decoded from the APDU header of this message.
*/ */
void handler_unrecognized_service( void handler_unrecognized_service(uint8_t* service_request,
uint8_t * service_request, uint16_t service_len, BACNET_ADDRESS* src,
uint16_t service_len,
BACNET_ADDRESS * src,
BACNET_CONFIRMED_SERVICE_DATA* service_data) BACNET_CONFIRMED_SERVICE_DATA* service_data)
{ {
int len = 0; int len = 0;
@@ -67,17 +65,15 @@ void handler_unrecognized_service(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], src, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
reject_encode_apdu(&Handler_Transmit_Buffer[pdu_len], service_data->invoke_id,
service_data->invoke_id, REJECT_REASON_UNRECOGNIZED_SERVICE); REJECT_REASON_UNRECOGNIZED_SERVICE);
pdu_len += len; pdu_len += len;
/* send the data */ /* send the data */
bytes_sent = bytes_sent = datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(src, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
if (bytes_sent > 0) { if (bytes_sent > 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
+11 -21
View File
@@ -44,36 +44,31 @@
/* list of devices */ /* list of devices */
static OS_Keylist Device_List = NULL; static OS_Keylist Device_List = NULL;
void objects_init( void objects_init(void)
void)
{ {
if (!Device_List) if (!Device_List)
Device_List = Keylist_Create(); Device_List = Keylist_Create();
} }
int objects_device_count( int objects_device_count(void)
void)
{ {
objects_init(); objects_init();
return Keylist_Count(Device_List); return Keylist_Count(Device_List);
} }
OBJECT_DEVICE_T *objects_device_data( OBJECT_DEVICE_T *objects_device_data(int index)
int index)
{ {
objects_init(); objects_init();
return Keylist_Data_Index(Device_List, index); return Keylist_Data_Index(Device_List, index);
} }
OBJECT_DEVICE_T *objects_device_by_instance( OBJECT_DEVICE_T *objects_device_by_instance(uint32_t device_instance)
uint32_t device_instance)
{ {
objects_init(); objects_init();
return Keylist_Data(Device_List, device_instance); return Keylist_Data(Device_List, device_instance);
} }
OBJECT_DEVICE_T *objects_device_new( OBJECT_DEVICE_T *objects_device_new(uint32_t device_instance)
uint32_t device_instance)
{ {
OBJECT_DEVICE_T *pDevice = NULL; OBJECT_DEVICE_T *pDevice = NULL;
KEY key = device_instance; KEY key = device_instance;
@@ -102,8 +97,7 @@ OBJECT_DEVICE_T *objects_device_new(
return pDevice; return pDevice;
} }
OBJECT_DEVICE_T *objects_device_delete( OBJECT_DEVICE_T *objects_device_delete(int index)
int index)
{ {
OBJECT_DEVICE_T *pDevice = NULL; OBJECT_DEVICE_T *pDevice = NULL;
BACNET_OBJECT_ID *pObject; BACNET_OBJECT_ID *pObject;
@@ -137,9 +131,7 @@ OBJECT_DEVICE_T *objects_device_delete(
#include "ctest.h" #include "ctest.h"
/* test the object creation and deletion */ /* test the object creation and deletion */
void testBACnetObjectsCompare( void testBACnetObjectsCompare(Test *pTest, OBJECT_DEVICE_T *pDevice,
Test * pTest,
OBJECT_DEVICE_T * pDevice,
uint32_t device_id) uint32_t device_id)
{ {
ct_test(pTest, pDevice != NULL); ct_test(pTest, pDevice != NULL);
@@ -151,8 +143,7 @@ void testBACnetObjectsCompare(
} }
} }
void testBACnetObjects( void testBACnetObjects(Test *pTest)
Test * pTest)
{ {
uint32_t device_id = 0; uint32_t device_id = 0;
unsigned test_point = 0; unsigned test_point = 0;
@@ -175,8 +166,8 @@ void testBACnetObjects(
for (test_point = 0; test_point < max_test_points; test_point++) { for (test_point = 0; test_point < max_test_points; test_point++) {
device_id = test_point * (BACNET_MAX_INSTANCE / max_test_points); device_id = test_point * (BACNET_MAX_INSTANCE / max_test_points);
pDevice = objects_device_data(test_point); pDevice = objects_device_data(test_point);
testBACnetObjectsCompare(pTest, pDevice, Keylist_Key(Device_List, testBACnetObjectsCompare(pTest, pDevice,
test_point)); Keylist_Key(Device_List, test_point));
} }
for (test_point = 0; test_point < max_test_points; test_point++) { for (test_point = 0; test_point < max_test_points; test_point++) {
pDevice = objects_device_delete(0); pDevice = objects_device_delete(0);
@@ -184,8 +175,7 @@ void testBACnetObjects(
} }
#ifdef TEST_OBJECT_LIST #ifdef TEST_OBJECT_LIST
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+7 -16
View File
@@ -43,7 +43,6 @@
#include "handlers.h" #include "handlers.h"
#include "client.h" #include "client.h"
/** Encodes an Abort message /** Encodes an Abort message
* @param buffer The buffer to build the message for sending. * @param buffer The buffer to build the message for sending.
* @param dest - Destination address to send the message * @param dest - Destination address to send the message
@@ -55,14 +54,9 @@
* *
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int abort_encode_pdu( int abort_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src,
uint8_t * buffer, BACNET_NPDU_DATA *npdu_data, uint8_t invoke_id,
BACNET_ADDRESS * dest, BACNET_ABORT_REASON reason, bool server)
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data,
uint8_t invoke_id,
BACNET_ABORT_REASON reason,
bool server)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
@@ -87,11 +81,8 @@ int abort_encode_pdu(
* *
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int Send_Abort_To_Network( int Send_Abort_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest,
uint8_t * buffer, uint8_t invoke_id, BACNET_ABORT_REASON reason,
BACNET_ADDRESS *dest,
uint8_t invoke_id,
BACNET_ABORT_REASON reason,
bool server) bool server)
{ {
int pdu_len = 0; int pdu_len = 0;
@@ -100,8 +91,8 @@ int Send_Abort_To_Network(
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
datalink_get_my_address(&src); datalink_get_my_address(&src);
pdu_len = abort_encode_pdu(buffer, dest, &src, &npdu_data, pdu_len = abort_encode_pdu(buffer, dest, &src, &npdu_data, invoke_id,
invoke_id, reason, server); reason, server);
bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len); bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len);
return bytes_sent; return bytes_sent;
+10 -14
View File
@@ -48,9 +48,7 @@
/* returns the invoke ID for confirmed request, or zero on failure */ /* returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Alarm_Acknowledgement(uint32_t device_id,
uint8_t Send_Alarm_Acknowledgement(
uint32_t device_id,
BACNET_ALARM_ACK_DATA* data) BACNET_ALARM_ACK_DATA* data)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -75,12 +73,10 @@ uint8_t Send_Alarm_Acknowledgement(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data); len = alarm_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
len = invoke_id, data);
alarm_ack_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
note: if there is a bottleneck router in between note: if there is a bottleneck router in between
@@ -88,11 +84,11 @@ uint8_t Send_Alarm_Acknowledgement(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Alarm Ack Request (%s)!\n", fprintf(stderr, "Failed to Send Alarm Ack Request (%s)!\n",
+10 -15
View File
@@ -45,9 +45,7 @@
/** @file s_arfs.c Send part of an Atomic Read File Stream. */ /** @file s_arfs.c Send part of an Atomic Read File Stream. */
uint8_t Send_Atomic_Read_File_Stream( uint8_t Send_Atomic_Read_File_Stream(uint32_t device_id, uint32_t file_instance,
uint32_t device_id,
uint32_t file_instance,
int fileStartPosition, int fileStartPosition,
unsigned requestedOctetCount) unsigned requestedOctetCount)
{ {
@@ -81,11 +79,9 @@ uint8_t Send_Atomic_Read_File_Stream(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data); len = arf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
len =
arf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&data); &data);
pdu_len += len; pdu_len += len;
/* will the APDU fit the target device? /* will the APDU fit the target device?
@@ -94,15 +90,14 @@ uint8_t Send_Atomic_Read_File_Stream(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr, "Failed to Send AtomicReadFile Request (%s)!\n",
"Failed to Send AtomicReadFile Request (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
} else { } else {
+11 -13
View File
@@ -45,8 +45,7 @@
/** @file s_awfs.c Send part of an Atomic Write File Stream request. */ /** @file s_awfs.c Send part of an Atomic Write File Stream request. */
uint8_t Send_Atomic_Write_File_Stream( uint8_t Send_Atomic_Write_File_Stream(uint32_t device_id,
uint32_t device_id,
uint32_t file_instance, uint32_t file_instance,
int fileStartPosition, int fileStartPosition,
BACNET_OCTET_STRING* fileData) BACNET_OCTET_STRING* fileData)
@@ -82,12 +81,10 @@ uint8_t Send_Atomic_Write_File_Stream(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
&my_address, &npdu_data); &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
awf_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
&data); &data);
pdu_len += len; pdu_len += len;
/* will the APDU fit the target device? /* will the APDU fit the target device?
@@ -96,12 +93,11 @@ uint8_t Send_Atomic_Write_File_Stream(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len <= max_apdu) { if ((unsigned)pdu_len <= max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len); (uint16_t)pdu_len);
bytes_sent = bytes_sent = datalink_send_pdu(
datalink_send_pdu(&dest, &npdu_data, &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
&Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
@@ -112,7 +108,8 @@ uint8_t Send_Atomic_Write_File_Stream(
tsm_free_invoke_id(invoke_id); tsm_free_invoke_id(invoke_id);
invoke_id = 0; invoke_id = 0;
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(
stderr,
"Failed to Send AtomicWriteFile Request " "Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds destination maximum APDU [%u])!\n", "(payload [%d] exceeds destination maximum APDU [%u])!\n",
pdu_len, max_apdu); pdu_len, max_apdu);
@@ -124,7 +121,8 @@ uint8_t Send_Atomic_Write_File_Stream(
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"Failed to Send AtomicWriteFile Request " "Failed to Send AtomicWriteFile Request "
"(payload [%d] exceeds octet string capacity)!\n", pdu_len); "(payload [%d] exceeds octet string capacity)!\n",
pdu_len);
#endif #endif
} }
} }
+11 -13
View File
@@ -47,8 +47,7 @@
* @return invoke id of outgoing message, or 0 if communication is disabled, * @return invoke id of outgoing message, or 0 if communication is disabled,
* or no tsm slot is available. * or no tsm slot is available.
*/ */
uint8_t Send_CEvent_Notify( uint8_t Send_CEvent_Notify(uint32_t device_id,
uint32_t device_id,
BACNET_EVENT_NOTIFICATION_DATA* data) BACNET_EVENT_NOTIFICATION_DATA* data)
{ {
int len = 0; int len = 0;
@@ -73,12 +72,10 @@ uint8_t Send_CEvent_Notify(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
cevent_notify_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
invoke_id, data); invoke_id, data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
@@ -87,14 +84,15 @@ uint8_t Send_CEvent_Notify(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
fprintf(stderr, fprintf(
stderr,
"Failed to Send ConfirmedEventNotification Request (%s)!\n", "Failed to Send ConfirmedEventNotification Request (%s)!\n",
strerror(errno)); strerror(errno));
} }
+19 -25
View File
@@ -42,7 +42,8 @@
#include "txbuf.h" #include "txbuf.h"
#include "client.h" #include "client.h"
/** @file s_cov.c Send a Change of Value (COV) update or a Subscribe COV request. */ /** @file s_cov.c Send a Change of Value (COV) update or a Subscribe COV
* request. */
/** Encodes an Unconfirmed COV Notification. /** Encodes an Unconfirmed COV Notification.
* @ingroup DSCOV * @ingroup DSCOV
@@ -54,11 +55,8 @@
* @param cov_data [in] The COV update information to be encoded. * @param cov_data [in] The COV update information to be encoded.
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int ucov_notify_encode_pdu( int ucov_notify_encode_pdu(uint8_t* buffer, unsigned buffer_len,
uint8_t * buffer, BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data,
unsigned buffer_len,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data,
BACNET_COV_DATA* cov_data) BACNET_COV_DATA* cov_data)
{ {
int len = 0; int len = 0;
@@ -73,8 +71,8 @@ int ucov_notify_encode_pdu(
pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data); pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = ucov_notify_encode_apdu(&buffer[pdu_len], len = ucov_notify_encode_apdu(&buffer[pdu_len], buffer_len - pdu_len,
buffer_len - pdu_len, cov_data); cov_data);
if (len) { if (len) {
pdu_len += len; pdu_len += len;
} else { } else {
@@ -92,9 +90,7 @@ int ucov_notify_encode_pdu(
* @param cov_data [in] The COV update information to be encoded. * @param cov_data [in] The COV update information to be encoded.
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int Send_UCOV_Notify( int Send_UCOV_Notify(uint8_t* buffer, unsigned buffer_len,
uint8_t * buffer,
unsigned buffer_len,
BACNET_COV_DATA* cov_data) BACNET_COV_DATA* cov_data)
{ {
int pdu_len = 0; int pdu_len = 0;
@@ -102,8 +98,8 @@ int Send_UCOV_Notify(
int bytes_sent = 0; int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
pdu_len = ucov_notify_encode_pdu(buffer, buffer_len, &dest, &npdu_data, pdu_len =
cov_data); ucov_notify_encode_pdu(buffer, buffer_len, &dest, &npdu_data, cov_data);
bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len); bytes_sent = datalink_send_pdu(&dest, &npdu_data, &buffer[0], pdu_len);
return bytes_sent; return bytes_sent;
@@ -117,8 +113,7 @@ int Send_UCOV_Notify(
* @return invoke id of outgoing message, or 0 if communication is disabled or * @return invoke id of outgoing message, or 0 if communication is disabled or
* no slot is available from the tsm for sending. * no slot is available from the tsm for sending.
*/ */
uint8_t Send_COV_Subscribe( uint8_t Send_COV_Subscribe(uint32_t device_id,
uint32_t device_id,
BACNET_SUBSCRIBE_COV_DATA* cov_data) BACNET_SUBSCRIBE_COV_DATA* cov_data)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -143,12 +138,11 @@ uint8_t Send_COV_Subscribe(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = cov_subscribe_encode_apdu(
cov_subscribe_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &Handler_Transmit_Buffer[pdu_len],
sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, cov_data); sizeof(Handler_Transmit_Buffer) - pdu_len, invoke_id, cov_data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
@@ -157,11 +151,11 @@ uint8_t Send_COV_Subscribe(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Failed to Send SubscribeCOV Request (%s)!\n", fprintf(stderr, "Failed to Send SubscribeCOV Request (%s)!\n",
+14 -16
View File
@@ -56,10 +56,8 @@
*/ */
uint8_t Send_Device_Communication_Control_Request( uint8_t Send_Device_Communication_Control_Request(
uint32_t device_id, uint32_t device_id, uint16_t timeDuration, /* 0=optional */
uint16_t timeDuration, /* 0=optional */ BACNET_COMMUNICATION_ENABLE_DISABLE state, char *password)
BACNET_COMMUNICATION_ENABLE_DISABLE state,
char *password)
{ /* NULL=optional */ { /* NULL=optional */
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
@@ -85,14 +83,13 @@ uint8_t Send_Device_Communication_Control_Request(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
characterstring_init_ansi(&password_string, password); characterstring_init_ansi(&password_string, password);
len = len = dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
dcc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, timeDuration, state,
timeDuration, state, password ? &password_string : NULL); password ? &password_string : NULL);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
note: if there is a bottleneck router in between note: if there is a bottleneck router in between
@@ -100,14 +97,15 @@ uint8_t Send_Device_Communication_Control_Request(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(
stderr,
"Failed to Send DeviceCommunicationControl Request (%s)!\n", "Failed to Send DeviceCommunicationControl Request (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
+8 -16
View File
@@ -42,7 +42,6 @@
#include "handlers.h" #include "handlers.h"
#include "client.h" #include "client.h"
/** Encodes an Error message /** Encodes an Error message
* @param buffer The buffer to build the message for sending. * @param buffer The buffer to build the message for sending.
* @param dest - Destination address to send the message * @param dest - Destination address to send the message
@@ -54,12 +53,8 @@
* *
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int error_encode_pdu( int error_encode_pdu(uint8_t *buffer, BACNET_ADDRESS *dest, BACNET_ADDRESS *src,
uint8_t * buffer, BACNET_NPDU_DATA *npdu_data, uint8_t invoke_id,
BACNET_ADDRESS * dest,
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data,
uint8_t invoke_id,
BACNET_CONFIRMED_SERVICE service, BACNET_CONFIRMED_SERVICE service,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
@@ -72,8 +67,8 @@ int error_encode_pdu(
pdu_len = npdu_encode_pdu(&buffer[0], dest, src, npdu_data); pdu_len = npdu_encode_pdu(&buffer[0], dest, src, npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = bacerror_encode_apdu(&buffer[pdu_len], invoke_id, len = bacerror_encode_apdu(&buffer[pdu_len], invoke_id, service,
service, error_class, error_code); error_class, error_code);
pdu_len += len; pdu_len += len;
return pdu_len; return pdu_len;
@@ -88,11 +83,8 @@ int error_encode_pdu(
* *
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int Send_Error_To_Network( int Send_Error_To_Network(uint8_t *buffer, BACNET_ADDRESS *dest,
uint8_t * buffer, uint8_t invoke_id, BACNET_CONFIRMED_SERVICE service,
BACNET_ADDRESS *dest,
uint8_t invoke_id,
BACNET_CONFIRMED_SERVICE service,
BACNET_ERROR_CLASS error_class, BACNET_ERROR_CLASS error_class,
BACNET_ERROR_CODE error_code) BACNET_ERROR_CODE error_code)
{ {
@@ -102,8 +94,8 @@ int Send_Error_To_Network(
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
datalink_get_my_address(&src); datalink_get_my_address(&src);
pdu_len = error_encode_pdu(buffer, dest, &src, &npdu_data, pdu_len = error_encode_pdu(buffer, dest, &src, &npdu_data, invoke_id,
invoke_id, service, error_class, error_code); service, error_class, error_code);
bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len); bytes_sent = datalink_send_pdu(dest, &npdu_data, &buffer[0], pdu_len);
return bytes_sent; return bytes_sent;
+8 -13
View File
@@ -52,9 +52,7 @@
#include "client.h" #include "client.h"
#include "get_alarm_sum.h" #include "get_alarm_sum.h"
uint8_t Send_Get_Alarm_Summary_Address( uint8_t Send_Get_Alarm_Summary_Address(BACNET_ADDRESS *dest, uint16_t max_apdu)
BACNET_ADDRESS *dest,
uint16_t max_apdu)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
@@ -72,8 +70,7 @@ uint8_t Send_Get_Alarm_Summary_Address(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
&my_address, &npdu_data); &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = get_alarm_summary_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = get_alarm_summary_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
@@ -81,14 +78,14 @@ uint8_t Send_Get_Alarm_Summary_Address(
pdu_len += len; pdu_len += len;
if ((uint16_t)pdu_len < max_apdu) { if ((uint16_t)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len); (uint16_t)pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
bytes_sent = bytes_sent =
#endif #endif
datalink_send_pdu(dest, &npdu_data, datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
&Handler_Transmit_Buffer[0], pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
@@ -109,8 +106,7 @@ uint8_t Send_Get_Alarm_Summary_Address(
return invoke_id; return invoke_id;
} }
uint8_t Send_Get_Alarm_Summary( uint8_t Send_Get_Alarm_Summary(uint32_t device_id)
uint32_t device_id)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
unsigned max_apdu = 0; unsigned max_apdu = 0;
@@ -120,8 +116,7 @@ uint8_t Send_Get_Alarm_Summary(
/* is the device bound? */ /* is the device bound? */
status = address_get_by_device(device_id, &max_apdu, &dest); status = address_get_by_device(device_id, &max_apdu, &dest);
if (status) { if (status) {
invoke_id = Send_Get_Alarm_Summary_Address( invoke_id = Send_Get_Alarm_Summary_Address(&dest, max_apdu);
&dest, max_apdu);
} }
return invoke_id; return invoke_id;
+12 -13
View File
@@ -55,8 +55,7 @@
#include "getevent.h" #include "getevent.h"
uint8_t Send_Get_Event_Information_Address( uint8_t Send_Get_Event_Information_Address(
BACNET_ADDRESS *dest, BACNET_ADDRESS *dest, uint16_t max_apdu,
uint16_t max_apdu,
BACNET_OBJECT_ID *lastReceivedObjectIdentifier) BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
{ {
int len = 0; int len = 0;
@@ -74,25 +73,26 @@ uint8_t Send_Get_Event_Information_Address(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, true, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
&my_address, &npdu_data); &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
invoke_id, lastReceivedObjectIdentifier); lastReceivedObjectIdentifier);
pdu_len += len; pdu_len += len;
if ((uint16_t)pdu_len < max_apdu) { if ((uint16_t)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0],
(uint16_t)pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
bytes_sent = bytes_sent =
#endif #endif
datalink_send_pdu(dest, &npdu_data, datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0],
&Handler_Transmit_Buffer[0], pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Get Event Information Request (%s)!\n", fprintf(stderr,
"Failed to Send Get Event Information Request (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
} else { } else {
@@ -110,8 +110,7 @@ uint8_t Send_Get_Event_Information_Address(
} }
uint8_t Send_Get_Event_Information( uint8_t Send_Get_Event_Information(
uint32_t device_id, uint32_t device_id, BACNET_OBJECT_ID *lastReceivedObjectIdentifier)
BACNET_OBJECT_ID * lastReceivedObjectIdentifier)
{ {
BACNET_ADDRESS dest = {0}; BACNET_ADDRESS dest = {0};
unsigned max_apdu = 0; unsigned max_apdu = 0;
+9 -12
View File
@@ -46,12 +46,11 @@
/** @file s_getevent.c Send a GetEventInformation request. */ /** @file s_getevent.c Send a GetEventInformation request. */
/** Send a GetEventInformation request to a remote network for a specific device, a range, /** Send a GetEventInformation request to a remote network for a specific
* or any device. * device, a range, or any device.
* @param target_address [in] BACnet address of target or broadcast * @param target_address [in] BACnet address of target or broadcast
*/ */
uint8_t Send_GetEvent( uint8_t Send_GetEvent(BACNET_ADDRESS* target_address,
BACNET_ADDRESS * target_address,
BACNET_OBJECT_ID* lastReceivedObjectIdentifier) BACNET_OBJECT_ID* lastReceivedObjectIdentifier)
{ {
int len = 0; int len = 0;
@@ -65,22 +64,21 @@ uint8_t Send_GetEvent(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
&my_address, &npdu_data); &my_address, &npdu_data);
invoke_id = tsm_next_free_invokeID(); invoke_id = tsm_next_free_invokeID();
if (invoke_id) { if (invoke_id) {
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
getevent_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, lastReceivedObjectIdentifier); lastReceivedObjectIdentifier);
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(target_address, &npdu_data,
datalink_send_pdu(target_address, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len); &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send GetEventInformation Request (%s)!\n", fprintf(stderr,
"Failed to Send GetEventInformation Request (%s)!\n",
strerror(errno)); strerror(errno));
#endif #endif
} else { } else {
@@ -108,4 +106,3 @@ uint8_t Send_GetEvent_Global( void )
return Send_GetEvent(&dest, NULL); return Send_GetEvent(&dest, NULL);
} }
+18 -34
View File
@@ -51,11 +51,8 @@
* @param segmentation [in] #BACNET_SEGMENTATION enumeration * @param segmentation [in] #BACNET_SEGMENTATION enumeration
* @param vendor_id [in] BACnet vendor ID 0-65535 * @param vendor_id [in] BACnet vendor ID 0-65535
*/ */
void Send_I_Am_To_Network( void Send_I_Am_To_Network(BACNET_ADDRESS* target_address, uint32_t device_id,
BACNET_ADDRESS * target_address, unsigned int max_apdu, int segmentation,
uint32_t device_id,
unsigned int max_apdu,
int segmentation,
uint16_t vendor_id) uint16_t vendor_id)
{ {
int len = 0; int len = 0;
@@ -68,25 +65,20 @@ void Send_I_Am_To_Network(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
&my_address, &npdu_data); &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = iam_encode_apdu(&Handler_Transmit_Buffer[pdu_len], device_id,
iam_encode_apdu(&Handler_Transmit_Buffer[pdu_len], max_apdu, segmentation, vendor_id);
device_id, max_apdu, segmentation, vendor_id);
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(target_address, &npdu_data,
datalink_send_pdu(target_address, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len); &Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Failed to Send I-Am Request (%s)!\n", fprintf(stderr, "Failed to Send I-Am Request (%s)!\n", strerror(errno));
strerror(errno));
#endif #endif
} }
} }
/** Encode an I Am message to be broadcast. /** Encode an I Am message to be broadcast.
@@ -95,9 +87,7 @@ void Send_I_Am_To_Network(
* @param npdu_data [out] The NPDU structure describing the message. * @param npdu_data [out] The NPDU structure describing the message.
* @return The length of the message in buffer[]. * @return The length of the message in buffer[].
*/ */
int iam_encode_pdu( int iam_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* dest,
uint8_t * buffer,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA* npdu_data) BACNET_NPDU_DATA* npdu_data)
{ {
int len = 0; int len = 0;
@@ -111,9 +101,9 @@ int iam_encode_pdu(
pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data); pdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(),
iam_encode_apdu(&buffer[pdu_len], Device_Object_Instance_Number(), MAX_APDU, SEGMENTATION_NONE,
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); Device_Vendor_Identifier());
pdu_len += len; pdu_len += len;
return pdu_len; return pdu_len;
@@ -124,8 +114,7 @@ int iam_encode_pdu(
* *
* @param buffer [in] The buffer to use for building and sending the message. * @param buffer [in] The buffer to use for building and sending the message.
*/ */
void Send_I_Am( void Send_I_Am(uint8_t* buffer)
uint8_t * buffer)
{ {
int pdu_len = 0; int pdu_len = 0;
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -165,11 +154,8 @@ void Send_I_Am(
* @param npdu_data [out] The NPDU structure describing the message. * @param npdu_data [out] The NPDU structure describing the message.
* @return The length of the message in buffer[]. * @return The length of the message in buffer[].
*/ */
int iam_unicast_encode_pdu( int iam_unicast_encode_pdu(uint8_t* buffer, BACNET_ADDRESS* src,
uint8_t * buffer, BACNET_ADDRESS* dest, BACNET_NPDU_DATA* npdu_data)
BACNET_ADDRESS * src,
BACNET_ADDRESS * dest,
BACNET_NPDU_DATA * npdu_data)
{ {
int npdu_len = 0; int npdu_len = 0;
int apdu_len = 0; int apdu_len = 0;
@@ -184,9 +170,9 @@ int iam_unicast_encode_pdu(
npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(npdu_data, false, MESSAGE_PRIORITY_NORMAL);
npdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data); npdu_len = npdu_encode_pdu(&buffer[0], dest, &my_address, npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
apdu_len = apdu_len = iam_encode_apdu(&buffer[npdu_len],
iam_encode_apdu(&buffer[npdu_len], Device_Object_Instance_Number(), Device_Object_Instance_Number(), MAX_APDU,
MAX_APDU, SEGMENTATION_NONE, Device_Vendor_Identifier()); SEGMENTATION_NONE, Device_Vendor_Identifier());
pdu_len = npdu_len + apdu_len; pdu_len = npdu_len + apdu_len;
return pdu_len; return pdu_len;
@@ -203,9 +189,7 @@ int iam_unicast_encode_pdu(
* @param buffer [in] The buffer to use for building and sending the message. * @param buffer [in] The buffer to use for building and sending the message.
* @param src [in] The source address information from service handler. * @param src [in] The source address information from service handler.
*/ */
void Send_I_Am_Unicast( void Send_I_Am_Unicast(uint8_t* buffer, BACNET_ADDRESS* src)
uint8_t * buffer,
BACNET_ADDRESS * src)
{ {
int pdu_len = 0; int pdu_len = 0;
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
+6 -12
View File
@@ -53,11 +53,8 @@
* @param object_instance [in] The Object ID that I Have. * @param object_instance [in] The Object ID that I Have.
* @param object_name [in] The Name of the Object I Have. * @param object_name [in] The Name of the Object I Have.
*/ */
void Send_I_Have( void Send_I_Have(uint32_t device_id, BACNET_OBJECT_TYPE object_type,
uint32_t device_id, uint32_t object_instance, BACNET_CHARACTER_STRING* object_name)
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
@@ -75,8 +72,7 @@ void Send_I_Have(
datalink_get_broadcast_address(&dest); datalink_get_broadcast_address(&dest);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
@@ -88,13 +84,11 @@ void Send_I_Have(
len = ihave_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); len = ihave_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
pdu_len += len; pdu_len += len;
/* send the data */ /* send the data */
bytes_sent = bytes_sent = datalink_send_pdu(&dest, &npdu_data,
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n", fprintf(stderr, "Failed to Send I-Have Reply (%s)!\n", strerror(errno));
strerror(errno));
#endif #endif
} }
} }
+9 -13
View File
@@ -48,9 +48,7 @@
/* returns the invoke ID for confirmed request, or zero on failure */ /* returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Life_Safety_Operation_Data(uint32_t device_id,
uint8_t Send_Life_Safety_Operation_Data(
uint32_t device_id,
BACNET_LSO_DATA* data) BACNET_LSO_DATA* data)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -75,12 +73,10 @@ uint8_t Send_Life_Safety_Operation_Data(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
len = len =
lso_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, lso_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, data);
data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
note: if there is a bottleneck router in between note: if there is a bottleneck router in between
@@ -88,11 +84,11 @@ uint8_t Send_Life_Safety_Operation_Data(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Life Safe Op Request (%s)!\n", fprintf(stderr, "Failed to Send Life Safe Op Request (%s)!\n",
+26 -31
View File
@@ -48,19 +48,13 @@
/** @file s_ptransfer.c Send a Private Transfer request. */ /** @file s_ptransfer.c Send a Private Transfer request. */
/* This function is exported. Hence this unnecessary prototype. */ /* This function is exported. Hence this unnecessary prototype. */
uint8_t Send_Private_Transfer_Request( uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id,
uint32_t device_id,
uint16_t vendor_id,
uint32_t service_number, uint32_t service_number,
char block_number, char block_number, DATABLOCK *block);
DATABLOCK * block);
uint8_t Send_Private_Transfer_Request( uint8_t Send_Private_Transfer_Request(uint32_t device_id, uint16_t vendor_id,
uint32_t device_id,
uint16_t vendor_id,
uint32_t service_number, uint32_t service_number,
char block_number, char block_number, DATABLOCK *block)
DATABLOCK * block)
{ /* NULL=optional */ { /* NULL=optional */
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
@@ -71,7 +65,8 @@ uint8_t Send_Private_Transfer_Request(
int pdu_len = 0; int pdu_len = 0;
int bytes_sent = 0; int bytes_sent = 0;
BACNET_NPDU_DATA npdu_data; BACNET_NPDU_DATA npdu_data;
static uint8_t pt_req_buffer[300]; /* Somewhere to build the request packet */ static uint8_t
pt_req_buffer[300]; /* Somewhere to build the request packet */
BACNET_PRIVATE_TRANSFER_DATA pt_block; BACNET_PRIVATE_TRANSFER_DATA pt_block;
BACNET_CHARACTER_STRING bsTemp; BACNET_CHARACTER_STRING bsTemp;
@@ -88,34 +83,34 @@ uint8_t Send_Private_Transfer_Request(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
pt_block.vendorID = vendor_id; pt_block.vendorID = vendor_id;
pt_block.serviceNumber = service_number; pt_block.serviceNumber = service_number;
if (service_number == MY_SVC_READ) { if (service_number == MY_SVC_READ) {
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number we want to retrieve */ len += encode_application_unsigned(
&pt_req_buffer[len],
block_number); /* The block number we want to retrieve */
} else { } else {
len += encode_application_unsigned(&pt_req_buffer[len], block_number); /* The block number */ len += encode_application_unsigned(
len += encode_application_unsigned(&pt_req_buffer[len], block->cMyByte1); /* And Then the block contents */ &pt_req_buffer[len], block_number); /* The block number */
len += len += encode_application_unsigned(
encode_application_unsigned(&pt_req_buffer[len], &pt_req_buffer[len],
block->cMyByte1); /* And Then the block contents */
len += encode_application_unsigned(&pt_req_buffer[len],
block->cMyByte2); block->cMyByte2);
len += len += encode_application_real(&pt_req_buffer[len], block->fMyReal);
encode_application_real(&pt_req_buffer[len], block->fMyReal);
characterstring_init_ansi(&bsTemp, (char *)block->sMyString); characterstring_init_ansi(&bsTemp, (char *)block->sMyString);
len += len += encode_application_character_string(&pt_req_buffer[len],
encode_application_character_string(&pt_req_buffer[len],
&bsTemp); &bsTemp);
} }
pt_block.serviceParameters = &pt_req_buffer[0]; pt_block.serviceParameters = &pt_req_buffer[0];
pt_block.serviceParametersLen = len; pt_block.serviceParametersLen = len;
len = len = ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len],
ptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, invoke_id, &pt_block);
&pt_block);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
@@ -125,11 +120,11 @@ uint8_t Send_Private_Transfer_Request(
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
+12 -14
View File
@@ -49,12 +49,12 @@
* @ingroup DMRD * @ingroup DMRD
* *
* @param device_id [in] The index to the device address in our address cache. * @param device_id [in] The index to the device address in our address cache.
* @param state [in] Specifies the desired state of the device after reinitialization. * @param state [in] Specifies the desired state of the device after
* reinitialization.
* @param password [in] Optional password, up to 20 chars. * @param password [in] Optional password, up to 20 chars.
* @return The invokeID of the transmitted message, or 0 on failure. * @return The invokeID of the transmitted message, or 0 on failure.
*/ */
uint8_t Send_Reinitialize_Device_Request( uint8_t Send_Reinitialize_Device_Request(uint32_t device_id,
uint32_t device_id,
BACNET_REINITIALIZED_STATE state, BACNET_REINITIALIZED_STATE state,
char *password) char *password)
{ {
@@ -82,14 +82,12 @@ uint8_t Send_Reinitialize_Device_Request(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
characterstring_init_ansi(&password_string, password); characterstring_init_ansi(&password_string, password);
len = len = rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
rd_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, state, state, password ? &password_string : NULL);
password ? &password_string : NULL);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
note: if there is a bottleneck router in between note: if there is a bottleneck router in between
@@ -97,11 +95,11 @@ uint8_t Send_Reinitialize_Device_Request(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
+11 -13
View File
@@ -47,8 +47,7 @@
/** @file s_readrange.c Send a ReadRange request. */ /** @file s_readrange.c Send a ReadRange request. */
/* returns invoke id of 0 if device is not bound or no tsm available */ /* returns invoke id of 0 if device is not bound or no tsm available */
uint8_t Send_ReadRange_Request( uint8_t Send_ReadRange_Request(uint32_t device_id, /* destination device */
uint32_t device_id, /* destination device */
BACNET_READ_RANGE_DATA* read_access_data) BACNET_READ_RANGE_DATA* read_access_data)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -74,13 +73,11 @@ uint8_t Send_ReadRange_Request(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
rr_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id,
read_access_data); read_access_data);
if (len <= 0) { if (len <= 0) {
return 0; return 0;
@@ -93,11 +90,11 @@ uint8_t Send_ReadRange_Request(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send ReadRange Request (%s)!\n", fprintf(stderr, "Failed to Send ReadRange Request (%s)!\n",
@@ -108,7 +105,8 @@ uint8_t Send_ReadRange_Request(
invoke_id = 0; invoke_id = 0;
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
"Failed to Send ReadRange Request (exceeds destination maximum APDU)!\n"); "Failed to Send ReadRange Request (exceeds destination "
"maximum APDU)!\n");
#endif #endif
} }
} }
+19 -36
View File
@@ -43,7 +43,8 @@
#include "client.h" #include "client.h"
#include "debug.h" #include "debug.h"
/** @file s_router.c Methods to send various BACnet Router Network Layer Messages. */ /** @file s_router.c Methods to send various BACnet Router Network Layer
* Messages. */
/** Initialize an npdu_data structure with given parameters and good defaults, /** Initialize an npdu_data structure with given parameters and good defaults,
* and add the Network Layer Message fields. * and add the Network Layer Message fields.
@@ -52,7 +53,8 @@
* APDU instead of a Network Layer Message. * APDU instead of a Network Layer Message.
* *
* @param npdu_data [out] Returns a filled-out structure with information * @param npdu_data [out] Returns a filled-out structure with information
* provided by the other arguments and good defaults. * provided by the other arguments and
* good defaults.
* @param network_message_type [in] The type of Network Layer Message. * @param network_message_type [in] The type of Network Layer Message.
* @param data_expecting_reply [in] True if message should have a reply. * @param data_expecting_reply [in] True if message should have a reply.
* @param priority [in] One of the 4 priorities defined in section 6.2.2, * @param priority [in] One of the 4 priorities defined in section 6.2.2,
@@ -60,8 +62,7 @@
*/ */
static void npdu_encode_npdu_network( static void npdu_encode_npdu_network(
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_NETWORK_MESSAGE_TYPE network_message_type, bool data_expecting_reply,
bool data_expecting_reply,
BACNET_MESSAGE_PRIORITY priority) BACNET_MESSAGE_PRIORITY priority)
{ {
if (npdu_data) { if (npdu_data) {
@@ -75,7 +76,6 @@ static void npdu_encode_npdu_network(
} }
} }
/** Function to encode and send any supported Network Layer Message. /** Function to encode and send any supported Network Layer Message.
* The payload for the message is encoded from information in the iArgs[] array. * The payload for the message is encoded from information in the iArgs[] array.
* The contents of iArgs are are, per message type: * The contents of iArgs are are, per message type:
@@ -97,10 +97,8 @@ static void npdu_encode_npdu_network(
* the type of message. * the type of message.
* @return Number of bytes sent, or <=0 if no message was sent. * @return Number of bytes sent, or <=0 if no message was sent.
*/ */
int Send_Network_Layer_Message( int Send_Network_Layer_Message(BACNET_NETWORK_MESSAGE_TYPE network_message_type,
BACNET_NETWORK_MESSAGE_TYPE network_message_type, BACNET_ADDRESS *dst, int *iArgs)
BACNET_ADDRESS * dst,
int *iArgs)
{ {
int len = 0; int len = 0;
int pdu_len = 0; int pdu_len = 0;
@@ -134,8 +132,7 @@ int Send_Network_Layer_Message(
switch (network_message_type) { switch (network_message_type) {
case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK: case NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK:
if (*pVal >= 0) { if (*pVal >= 0) {
len = len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal); (uint16_t)*pVal);
pdu_len += len; pdu_len += len;
} }
@@ -146,8 +143,7 @@ int Send_Network_Layer_Message(
case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK: case NETWORK_MESSAGE_ROUTER_BUSY_TO_NETWORK:
case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK: case NETWORK_MESSAGE_ROUTER_AVAILABLE_TO_NETWORK:
while (*pVal >= 0) { while (*pVal >= 0) {
len = len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal); (uint16_t)*pVal);
pdu_len += len; pdu_len += len;
pVal++; pVal++;
@@ -158,8 +154,7 @@ int Send_Network_Layer_Message(
/* Encode the Reason byte, then the DNET */ /* Encode the Reason byte, then the DNET */
Handler_Transmit_Buffer[pdu_len++] = (uint8_t)*pVal; Handler_Transmit_Buffer[pdu_len++] = (uint8_t)*pVal;
pVal++; pVal++;
len = len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal); (uint16_t)*pVal);
pdu_len += len; pdu_len += len;
break; break;
@@ -182,8 +177,7 @@ int Send_Network_Layer_Message(
* and have no PortInfo. * and have no PortInfo.
*/ */
while (*pVal >= 0) { while (*pVal >= 0) {
len = len = encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
encode_unsigned16(&Handler_Transmit_Buffer[pdu_len],
(uint16_t)*pVal); (uint16_t)*pVal);
pdu_len += len; pdu_len += len;
Handler_Transmit_Buffer[pdu_len++] = portID++; Handler_Transmit_Buffer[pdu_len++] = portID++;
@@ -204,14 +198,14 @@ int Send_Network_Layer_Message(
if (dst != NULL) if (dst != NULL)
debug_printf("Sending %s message to BACnet network %u \n", debug_printf("Sending %s message to BACnet network %u \n",
bactext_network_layer_msg_name(network_message_type), dst->net); bactext_network_layer_msg_name(network_message_type),
dst->net);
else else
debug_printf("Sending %s message to local BACnet network \n", debug_printf("Sending %s message to local BACnet network \n",
bactext_network_layer_msg_name(network_message_type)); bactext_network_layer_msg_name(network_message_type));
/* Now send the message */ /* Now send the message */
bytes_sent = bytes_sent = datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
datalink_send_pdu(dst, &npdu_data, &Handler_Transmit_Buffer[0],
pdu_len); pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
@@ -224,7 +218,6 @@ int Send_Network_Layer_Message(
return bytes_sent; return bytes_sent;
} }
/** Finds a specific router, or all reachable BACnet networks. /** Finds a specific router, or all reachable BACnet networks.
* The response(s) will come in I-am-router-to-network message(s). * The response(s) will come in I-am-router-to-network message(s).
* @ingroup NMRC * @ingroup NMRC
@@ -236,9 +229,7 @@ int Send_Network_Layer_Message(
* will be sent and the receiving router(s) will send * will be sent and the receiving router(s) will send
* their full list of reachable BACnet networks. * their full list of reachable BACnet networks.
*/ */
void Send_Who_Is_Router_To_Network( void Send_Who_Is_Router_To_Network(BACNET_ADDRESS *dst, int dnet)
BACNET_ADDRESS * dst,
int dnet)
{ {
Send_Network_Layer_Message(NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, dst, Send_Network_Layer_Message(NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, dst,
&dnet); &dnet);
@@ -253,8 +244,7 @@ void Send_Who_Is_Router_To_Network(
* @param DNET_list [in] List of BACnet network numbers for which I am a router, * @param DNET_list [in] List of BACnet network numbers for which I am a router,
* terminated with -1 * terminated with -1
*/ */
void Send_I_Am_Router_To_Network( void Send_I_Am_Router_To_Network(const int DNET_list[])
const int DNET_list[])
{ {
/* Use a NULL dst here since we want a broadcast MAC address. */ /* Use a NULL dst here since we want a broadcast MAC address. */
Send_Network_Layer_Message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, NULL, Send_Network_Layer_Message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, NULL,
@@ -271,9 +261,7 @@ void Send_I_Am_Router_To_Network(
* @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes. * @param reject_reason [in] One of the BACNET_NETWORK_REJECT_REASONS codes.
* @param dnet [in] Which BACnet network orginated the message. * @param dnet [in] Which BACnet network orginated the message.
*/ */
void Send_Reject_Message_To_Network( void Send_Reject_Message_To_Network(BACNET_ADDRESS *dst, uint8_t reject_reason,
BACNET_ADDRESS * dst,
uint8_t reject_reason,
int dnet) int dnet)
{ {
int iArgs[2]; int iArgs[2];
@@ -284,7 +272,6 @@ void Send_Reject_Message_To_Network(
debug_printf(" Reject Reason=%d, DNET=%u\n", reject_reason, dnet); debug_printf(" Reject Reason=%d, DNET=%u\n", reject_reason, dnet);
} }
/** Send an Initialize Routing Table message, built from an optional DNET[] /** Send an Initialize Routing Table message, built from an optional DNET[]
* array. * array.
* There are two cases here: * There are two cases here:
@@ -301,16 +288,13 @@ void Send_Reject_Message_To_Network(
* terminated with -1. Will be just -1 when we are * terminated with -1. Will be just -1 when we are
* requesting a routing table. * requesting a routing table.
*/ */
void Send_Initialize_Routing_Table( void Send_Initialize_Routing_Table(BACNET_ADDRESS *dst, const int DNET_list[])
BACNET_ADDRESS * dst,
const int DNET_list[])
{ {
/* Use a NULL dst here since we want a broadcast MAC address. */ /* Use a NULL dst here since we want a broadcast MAC address. */
Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE, dst, Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE, dst,
(int *)DNET_list); (int *)DNET_list);
} }
/** Sends our Routing Table, built from our DNET[] array, as an ACK. /** Sends our Routing Table, built from our DNET[] array, as an ACK.
* There are two cases here: * There are two cases here:
* 1) We are responding to a NETWORK_MESSAGE_INIT_RT_TABLE requesting our table. * 1) We are responding to a NETWORK_MESSAGE_INIT_RT_TABLE requesting our table.
@@ -328,8 +312,7 @@ void Send_Initialize_Routing_Table(
* terminated with -1. May be just -1 when no table * terminated with -1. May be just -1 when no table
* should be sent. * should be sent.
*/ */
void Send_Initialize_Routing_Table_Ack( void Send_Initialize_Routing_Table_Ack(BACNET_ADDRESS *dst,
BACNET_ADDRESS * dst,
const int DNET_list[]) const int DNET_list[])
{ {
Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK, dst, Send_Network_Layer_Message(NETWORK_MESSAGE_INIT_RT_TABLE_ACK, dst,
+21 -21
View File
@@ -52,15 +52,16 @@
* @param max_apdu [in] * @param max_apdu [in]
* @param object_type [in] Type of the object whose property is to be read. * @param object_type [in] Type of the object whose property is to be read.
* @param object_instance [in] Instance # of the object to be read. * @param object_instance [in] Instance # of the object to be read.
* @param object_property [in] Property to be read, but not ALL, REQUIRED, or OPTIONAL. * @param object_property [in] Property to be read, but not ALL, REQUIRED, or
* OPTIONAL.
* @param array_index [in] Optional: if the Property is an array, * @param array_index [in] Optional: if the Property is an array,
* - 0 for the array size * - 0 for the array size
* - 1 to n for individual array members * - 1 to n for individual array members
* - BACNET_ARRAY_ALL (~0) for the full array to be read. * - BACNET_ARRAY_ALL (~0) for the full array to be read.
* @return invoke id of outgoing message, or 0 if device is not bound or no tsm available * @return invoke id of outgoing message, or 0 if device is not bound or no tsm
* available
*/ */
uint8_t Send_Read_Property_Request_Address( uint8_t Send_Read_Property_Request_Address(BACNET_ADDRESS* dest,
BACNET_ADDRESS * dest,
uint16_t max_apdu, uint16_t max_apdu,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
@@ -87,17 +88,15 @@ uint8_t Send_Read_Property_Request_Address(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
data.object_type = object_type; data.object_type = object_type;
data.object_instance = object_instance; data.object_instance = object_instance;
data.object_property = object_property; data.object_property = object_property;
data.array_index = array_index; data.array_index = array_index;
len = len =
rp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, rp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data);
&data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
note: if there is a bottleneck router in between note: if there is a bottleneck router in between
@@ -105,11 +104,11 @@ uint8_t Send_Read_Property_Request_Address(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((uint16_t)pdu_len < max_apdu) { if ((uint16_t)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Failed to Send ReadProperty Request (%s)!\n", fprintf(stderr, "Failed to Send ReadProperty Request (%s)!\n",
@@ -136,15 +135,16 @@ uint8_t Send_Read_Property_Request_Address(
* @param device_id [in] ID of the destination device * @param device_id [in] ID of the destination device
* @param object_type [in] Type of the object whose property is to be read. * @param object_type [in] Type of the object whose property is to be read.
* @param object_instance [in] Instance # of the object to be read. * @param object_instance [in] Instance # of the object to be read.
* @param object_property [in] Property to be read, but not ALL, REQUIRED, or OPTIONAL. * @param object_property [in] Property to be read, but not ALL, REQUIRED, or
* OPTIONAL.
* @param array_index [in] Optional: if the Property is an array, * @param array_index [in] Optional: if the Property is an array,
* - 0 for the array size * - 0 for the array size
* - 1 to n for individual array members * - 1 to n for individual array members
* - BACNET_ARRAY_ALL (~0) for the full array to be read. * - BACNET_ARRAY_ALL (~0) for the full array to be read.
* @return invoke id of outgoing message, or 0 if device is not bound or no tsm available * @return invoke id of outgoing message, or 0 if device is not bound or no tsm
* available
*/ */
uint8_t Send_Read_Property_Request( uint8_t Send_Read_Property_Request(uint32_t device_id, /* destination device */
uint32_t device_id, /* destination device */
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID object_property, BACNET_PROPERTY_ID object_property,
@@ -158,9 +158,9 @@ uint8_t Send_Read_Property_Request(
/* is the device bound? */ /* is the device bound? */
status = address_get_by_device(device_id, &max_apdu, &dest); status = address_get_by_device(device_id, &max_apdu, &dest);
if (status) { if (status) {
invoke_id = invoke_id = Send_Read_Property_Request_Address(
Send_Read_Property_Request_Address(&dest, max_apdu, object_type, &dest, max_apdu, object_type, object_instance, object_property,
object_instance, object_property, array_index); array_index);
} }
return invoke_id; return invoke_id;
+7 -10
View File
@@ -53,12 +53,11 @@
* @param device_id [in] ID of the destination device * @param device_id [in] ID of the destination device
* @param read_access_data [in] Ptr to structure with the linked list of * @param read_access_data [in] Ptr to structure with the linked list of
* properties to be read. * properties to be read.
* @return invoke id of outgoing message, or 0 if device is not bound or no tsm available * @return invoke id of outgoing message, or 0 if device is not bound or no tsm
* available
*/ */
uint8_t Send_Read_Property_Multiple_Request( uint8_t Send_Read_Property_Multiple_Request(
uint8_t * pdu, uint8_t* pdu, size_t max_pdu, uint32_t device_id, /* destination device */
size_t max_pdu,
uint32_t device_id, /* destination device */
BACNET_READ_ACCESS_DATA* read_access_data) BACNET_READ_ACCESS_DATA* read_access_data)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -85,8 +84,7 @@ uint8_t Send_Read_Property_Multiple_Request(
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(&pdu[0], &dest, &my_address, &npdu_data); pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
rpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
read_access_data); read_access_data);
if (len <= 0) { if (len <= 0) {
return 0; return 0;
@@ -98,10 +96,9 @@ uint8_t Send_Read_Property_Multiple_Request(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &pdu[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &pdu[0], (uint16_t)pdu_len);
bytes_sent = bytes_sent = datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
+13 -27
View File
@@ -52,9 +52,7 @@
* @param bdate - #BACNET_DATE * @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME * @param btime - #BACNET_TIME
*/ */
void Send_TimeSync_Remote( void Send_TimeSync_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate,
BACNET_ADDRESS * dest,
BACNET_DATE * bdate,
BACNET_TIME* btime) BACNET_TIME* btime)
{ {
int len = 0; int len = 0;
@@ -69,17 +67,14 @@ void Send_TimeSync_Remote(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
timesync_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate, btime);
pdu_len += len; pdu_len += len;
/* send it out the datalink */ /* send it out the datalink */
bytes_sent = bytes_sent = datalink_send_pdu(dest, &npdu_data,
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Time-Synchronization Request (%s)!\n", fprintf(stderr, "Failed to Send Time-Synchronization Request (%s)!\n",
@@ -93,9 +88,7 @@ void Send_TimeSync_Remote(
* @param bdate - #BACNET_DATE * @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME * @param btime - #BACNET_TIME
*/ */
void Send_TimeSync( void Send_TimeSync(BACNET_DATE* bdate, BACNET_TIME* btime)
BACNET_DATE * bdate,
BACNET_TIME * btime)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -110,9 +103,7 @@ void Send_TimeSync(
* @param bdate - #BACNET_DATE * @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME * @param btime - #BACNET_TIME
*/ */
void Send_TimeSyncUTC_Remote( void Send_TimeSyncUTC_Remote(BACNET_ADDRESS* dest, BACNET_DATE* bdate,
BACNET_ADDRESS * dest,
BACNET_DATE * bdate,
BACNET_TIME* btime) BACNET_TIME* btime)
{ {
int len = 0; int len = 0;
@@ -127,17 +118,14 @@ void Send_TimeSyncUTC_Remote(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], bdate,
timesync_utc_encode_apdu(&Handler_Transmit_Buffer[pdu_len], btime);
bdate, btime);
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(dest, &npdu_data,
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, fprintf(stderr,
@@ -152,9 +140,7 @@ void Send_TimeSyncUTC_Remote(
* @param bdate - #BACNET_DATE * @param bdate - #BACNET_DATE
* @param btime - #BACNET_TIME * @param btime - #BACNET_TIME
*/ */
void Send_TimeSyncUTC( void Send_TimeSyncUTC(BACNET_DATE* bdate, BACNET_TIME* btime)
BACNET_DATE * bdate,
BACNET_TIME * btime)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
+1 -3
View File
@@ -40,9 +40,7 @@
* @param dest [in] The destination address information (may be a broadcast). * @param dest [in] The destination address information (may be a broadcast).
* @return Size of the message sent (bytes), or a negative value on error. * @return Size of the message sent (bytes), or a negative value on error.
*/ */
int Send_UEvent_Notify( int Send_UEvent_Notify(uint8_t* buffer, BACNET_EVENT_NOTIFICATION_DATA* data,
uint8_t * buffer,
BACNET_EVENT_NOTIFICATION_DATA * data,
BACNET_ADDRESS* dest) BACNET_ADDRESS* dest)
{ {
int len = 0; int len = 0;
+5 -9
View File
@@ -45,8 +45,7 @@
/** @file s_upt.c Send an Unconfirmed Private Transfer request. */ /** @file s_upt.c Send an Unconfirmed Private Transfer request. */
int Send_UnconfirmedPrivateTransfer( int Send_UnconfirmedPrivateTransfer(BACNET_ADDRESS* dest,
BACNET_ADDRESS * dest,
BACNET_PRIVATE_TRANSFER_DATA* private_data) BACNET_PRIVATE_TRANSFER_DATA* private_data)
{ {
int len = 0; int len = 0;
@@ -61,18 +60,15 @@ int Send_UnconfirmedPrivateTransfer(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], dest, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len =
uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], uptransfer_encode_apdu(&Handler_Transmit_Buffer[pdu_len], private_data);
private_data);
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(dest, &npdu_data,
datalink_send_pdu(dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, fprintf(stderr,
+16 -24
View File
@@ -47,17 +47,15 @@
/** Send a Who-Has request for a device which has a named Object. /** Send a Who-Has request for a device which has a named Object.
* @ingroup DMDOB * @ingroup DMDOB
* If low_limit and high_limit both are -1, then the device ID range is unlimited. * If low_limit and high_limit both are -1, then the device ID range is
* If low_limit and high_limit have the same non-negative value, then only * unlimited. If low_limit and high_limit have the same non-negative value, then
* that device will respond. * only that device will respond. Otherwise, low_limit must be less than
* Otherwise, low_limit must be less than high_limit for a range. * high_limit for a range.
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
* @param object_name [in] The Name of the desired Object. * @param object_name [in] The Name of the desired Object.
*/ */
void Send_WhoHas_Name( void Send_WhoHas_Name(int32_t low_limit, int32_t high_limit,
int32_t low_limit,
int32_t high_limit,
const char *object_name) const char *object_name)
{ {
int len = 0; int len = 0;
@@ -76,8 +74,7 @@ void Send_WhoHas_Name(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
@@ -88,9 +85,8 @@ void Send_WhoHas_Name(
len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
pdu_len += len; pdu_len += len;
/* send the data */ /* send the data */
bytes_sent = bytes_sent = datalink_send_pdu(&dest, &npdu_data,
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n", fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n",
@@ -100,18 +96,16 @@ void Send_WhoHas_Name(
/** Send a Who-Has request for a device which has a specific Object type and ID. /** Send a Who-Has request for a device which has a specific Object type and ID.
* @ingroup DMDOB * @ingroup DMDOB
* If low_limit and high_limit both are -1, then the device ID range is unlimited. * If low_limit and high_limit both are -1, then the device ID range is
* If low_limit and high_limit have the same non-negative value, then only * unlimited. If low_limit and high_limit have the same non-negative value, then
* that device will respond. * only that device will respond. Otherwise, low_limit must be less than
* Otherwise, low_limit must be less than high_limit for a range. * high_limit for a range.
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
* @param object_type [in] The BACNET_OBJECT_TYPE of the desired Object. * @param object_type [in] The BACNET_OBJECT_TYPE of the desired Object.
* @param object_instance [in] The ID of the desired Object. * @param object_instance [in] The ID of the desired Object.
*/ */
void Send_WhoHas_Object( void Send_WhoHas_Object(int32_t low_limit, int32_t high_limit,
int32_t low_limit,
int32_t high_limit,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance) uint32_t object_instance)
{ {
@@ -131,8 +125,7 @@ void Send_WhoHas_Object(
datalink_get_my_address(&my_address); datalink_get_my_address(&my_address);
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address,
&npdu_data); &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
@@ -143,9 +136,8 @@ void Send_WhoHas_Object(
data.object.identifier.instance = object_instance; data.object.identifier.instance = object_instance;
len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data); len = whohas_encode_apdu(&Handler_Transmit_Buffer[pdu_len], &data);
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(&dest, &npdu_data,
datalink_send_pdu(&dest, &npdu_data, &Handler_Transmit_Buffer[0], &Handler_Transmit_Buffer[0], pdu_len);
pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n", fprintf(stderr, "Failed to Send Who-Has Request (%s)!\n",
+10 -23
View File
@@ -56,9 +56,7 @@
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/ */
void Send_WhoIs_To_Network( void Send_WhoIs_To_Network(BACNET_ADDRESS* target_address, int32_t low_limit,
BACNET_ADDRESS * target_address,
int32_t low_limit,
int32_t high_limit) int32_t high_limit)
{ {
int len = 0; int len = 0;
@@ -71,16 +69,13 @@ void Send_WhoIs_To_Network(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL); npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
pdu_len = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], target_address,
&my_address, &npdu_data); &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len], low_limit,
whois_encode_apdu(&Handler_Transmit_Buffer[pdu_len], low_limit,
high_limit); high_limit);
pdu_len += len; pdu_len += len;
bytes_sent = bytes_sent = datalink_send_pdu(target_address, &npdu_data,
datalink_send_pdu(target_address, &npdu_data,
&Handler_Transmit_Buffer[0], pdu_len); &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
@@ -97,9 +92,7 @@ void Send_WhoIs_To_Network(
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/ */
void Send_WhoIs_Global( void Send_WhoIs_Global(int32_t low_limit, int32_t high_limit)
int32_t low_limit,
int32_t high_limit)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -120,9 +113,7 @@ void Send_WhoIs_Global(
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/ */
void Send_WhoIs_Local( void Send_WhoIs_Local(int32_t low_limit, int32_t high_limit)
int32_t low_limit,
int32_t high_limit)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
char temp[6]; char temp[6];
@@ -138,7 +129,8 @@ void Send_WhoIs_Local(
/* I added this to make it a local broadcast */ /* I added this to make it a local broadcast */
dest.net = 0; dest.net = 0;
/* Not sure why this happens but values are backwards so they need to be reversed */ /* Not sure why this happens but values are backwards so they need to be
* reversed */
temp[0] = dest.mac[3]; temp[0] = dest.mac[3];
temp[1] = dest.mac[2]; temp[1] = dest.mac[2];
@@ -147,7 +139,6 @@ void Send_WhoIs_Local(
temp[4] = dest.mac[5]; temp[4] = dest.mac[5];
temp[5] = dest.mac[4]; temp[5] = dest.mac[4];
for (loop = 0; loop < 6; loop++) { for (loop = 0; loop < 6; loop++) {
dest.mac[loop] = temp[loop]; dest.mac[loop] = temp[loop];
} }
@@ -166,9 +157,7 @@ void Send_WhoIs_Local(
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/ */
void Send_WhoIs_Remote( void Send_WhoIs_Remote(BACNET_ADDRESS* target_address, int32_t low_limit,
BACNET_ADDRESS * target_address,
int32_t low_limit,
int32_t high_limit) int32_t high_limit)
{ {
if (!dcc_communication_enabled()) if (!dcc_communication_enabled())
@@ -189,9 +178,7 @@ void Send_WhoIs_Remote(
* @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1 * @param low_limit [in] Device Instance Low Range, 0 - 4,194,303 or -1
* @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1 * @param high_limit [in] Device Instance High Range, 0 - 4,194,303 or -1
*/ */
void Send_WhoIs( void Send_WhoIs(int32_t low_limit, int32_t high_limit)
int32_t low_limit,
int32_t high_limit)
{ {
Send_WhoIs_Global(low_limit, high_limit); Send_WhoIs_Global(low_limit, high_limit);
} }
+20 -26
View File
@@ -46,15 +46,13 @@
/** @file s_wp.c Send a Write Property request. */ /** @file s_wp.c Send a Write Property request. */
/** returns the invoke ID for confirmed request, or zero on failure */ /** returns the invoke ID for confirmed request, or zero on failure */
uint8_t Send_Write_Property_Request_Data( uint8_t Send_Write_Property_Request_Data(uint32_t device_id,
uint32_t device_id,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID object_property, BACNET_PROPERTY_ID object_property,
uint8_t* application_data, uint8_t* application_data,
int application_data_len, int application_data_len,
uint8_t priority, uint8_t priority, uint32_t array_index)
uint32_t array_index)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
BACNET_ADDRESS my_address; BACNET_ADDRESS my_address;
@@ -79,9 +77,8 @@ uint8_t Send_Write_Property_Request_Data(
/* encode the NPDU portion of the packet */ /* encode the NPDU portion of the packet */
datalink_get_my_address(&my_address); 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 = pdu_len = npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest,
npdu_encode_pdu(&Handler_Transmit_Buffer[0], &dest, &my_address, &my_address, &npdu_data);
&npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
data.object_type = object_type; data.object_type = object_type;
data.object_instance = object_instance; data.object_instance = object_instance;
@@ -92,8 +89,7 @@ uint8_t Send_Write_Property_Request_Data(
application_data_len); application_data_len);
data.priority = priority; data.priority = priority;
len = len =
wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, wp_encode_apdu(&Handler_Transmit_Buffer[pdu_len], invoke_id, &data);
&data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
note: if there is a bottleneck router in between note: if there is a bottleneck router in between
@@ -101,11 +97,11 @@ uint8_t Send_Write_Property_Request_Data(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &Handler_Transmit_Buffer[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &Handler_Transmit_Buffer[0],
bytes_sent = (uint16_t)pdu_len);
datalink_send_pdu(&dest, &npdu_data, bytes_sent = datalink_send_pdu(
&Handler_Transmit_Buffer[0], pdu_len); &dest, &npdu_data, &Handler_Transmit_Buffer[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) if (bytes_sent <= 0)
fprintf(stderr, "Failed to Send WriteProperty Request (%s)!\n", fprintf(stderr, "Failed to Send WriteProperty Request (%s)!\n",
@@ -125,7 +121,6 @@ uint8_t Send_Write_Property_Request_Data(
return invoke_id; return invoke_id;
} }
/** Sends a Write Property request. /** Sends a Write Property request.
* @ingroup DSWP * @ingroup DSWP
* *
@@ -141,25 +136,24 @@ uint8_t Send_Write_Property_Request_Data(
* - BACNET_ARRAY_ALL (~0) for the array value to be ignored (not sent) * - BACNET_ARRAY_ALL (~0) for the array value to be ignored (not sent)
* @return invoke id of outgoing message, or 0 on failure. * @return invoke id of outgoing message, or 0 on failure.
*/ */
uint8_t Send_Write_Property_Request( uint8_t Send_Write_Property_Request(uint32_t device_id,
uint32_t device_id,
BACNET_OBJECT_TYPE object_type, BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_PROPERTY_ID object_property, BACNET_PROPERTY_ID object_property,
BACNET_APPLICATION_DATA_VALUE* object_value, BACNET_APPLICATION_DATA_VALUE* object_value,
uint8_t priority, uint8_t priority, uint32_t array_index)
uint32_t array_index)
{ {
uint8_t application_data[MAX_APDU] = {0}; uint8_t application_data[MAX_APDU] = {0};
int apdu_len = 0, len = 0; int apdu_len = 0, len = 0;
while (object_value) { while (object_value) {
#if PRINT_ENABLED_DEBUG #if PRINT_ENABLED_DEBUG
fprintf(stderr, "WriteProperty service: " "%s tag=%d\n", fprintf(stderr,
"WriteProperty service: "
"%s tag=%d\n",
(object_value->context_specific ? "context" : "application"), (object_value->context_specific ? "context" : "application"),
(int) (object_value-> (int)(object_value->context_specific ? object_value->context_tag
context_specific ? object_value->context_tag : object_value-> : object_value->tag));
tag));
#endif #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) { if ((len + apdu_len) < MAX_APDU) {
@@ -170,7 +164,7 @@ uint8_t Send_Write_Property_Request(
object_value = object_value->next; object_value = object_value->next;
} }
return Send_Write_Property_Request_Data(device_id, object_type, return Send_Write_Property_Request_Data(
object_instance, object_property, &application_data[0], apdu_len, device_id, object_type, object_instance, object_property,
priority, array_index); &application_data[0], apdu_len, priority, array_index);
} }
+8 -12
View File
@@ -55,12 +55,11 @@
* @param device_id [in] ID of the destination device * @param device_id [in] ID of the destination device
* @param write_access_data [in] Ptr to structure with the linked list of * @param write_access_data [in] Ptr to structure with the linked list of
* objects and properties to be written. * objects and properties to be written.
* @return invoke id of outgoing message, or 0 if device is not bound or no tsm available * @return invoke id of outgoing message, or 0 if device is not bound or no tsm
* available
*/ */
uint8_t Send_Write_Property_Multiple_Request( uint8_t Send_Write_Property_Multiple_Request(
uint8_t * pdu, uint8_t* pdu, size_t max_pdu, uint32_t device_id,
size_t max_pdu,
uint32_t device_id,
BACNET_WRITE_ACCESS_DATA* write_access_data) BACNET_WRITE_ACCESS_DATA* write_access_data)
{ {
BACNET_ADDRESS dest; BACNET_ADDRESS dest;
@@ -89,9 +88,8 @@ uint8_t Send_Write_Property_Multiple_Request(
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(&pdu[0], &dest, &my_address, &npdu_data); pdu_len = npdu_encode_pdu(&pdu[0], &dest, &my_address, &npdu_data);
/* encode the APDU portion of the packet */ /* encode the APDU portion of the packet */
len = len = wpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, invoke_id,
wpm_encode_apdu(&pdu[pdu_len], max_pdu - pdu_len, write_access_data);
invoke_id, write_access_data);
pdu_len += len; pdu_len += len;
/* will it fit in the sender? /* will it fit in the sender?
@@ -100,11 +98,9 @@ uint8_t Send_Write_Property_Multiple_Request(
we have a way to check for that and update the we have a way to check for that and update the
max_apdu in the address binding table. */ max_apdu in the address binding table. */
if ((unsigned)pdu_len < max_apdu) { if ((unsigned)pdu_len < max_apdu) {
tsm_set_confirmed_unsegmented_transaction(invoke_id, &dest, tsm_set_confirmed_unsegmented_transaction(
&npdu_data, &pdu[0], (uint16_t) pdu_len); invoke_id, &dest, &npdu_data, &pdu[0], (uint16_t)pdu_len);
bytes_sent = bytes_sent = datalink_send_pdu(&dest, &npdu_data, &pdu[0], pdu_len);
datalink_send_pdu(&dest, &npdu_data,
&pdu[0], pdu_len);
#if PRINT_ENABLED #if PRINT_ENABLED
if (bytes_sent <= 0) { if (bytes_sent <= 0) {
fprintf(stderr, fprintf(stderr,
+18 -25
View File
@@ -55,11 +55,8 @@ static int Target_Segmentation = SEGMENTATION_NONE;
/* flag for signalling errors */ /* flag for signalling errors */
static bool Error_Detected = false; static bool Error_Detected = false;
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
(void)src; (void)src;
(void)invoke_id; (void)invoke_id;
@@ -68,9 +65,7 @@ void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
(void)src; (void)src;
@@ -79,8 +74,7 @@ void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
/* we need to handle who-is /* we need to handle who-is
@@ -88,8 +82,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -111,7 +104,8 @@ static void print_usage(char *filename)
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Send BACnet I-Am message for a device.\n"); printf("Send BACnet I-Am message for a device.\n");
printf("--mac A\n" printf(
"--mac A\n"
"Optional BACnet mac address." "Optional BACnet mac address."
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
@@ -123,12 +117,14 @@ static void print_help(char *filename)
"and 65535 is network broadcast.\n" "and 65535 is network broadcast.\n"
"\n" "\n"
"--dadr A\n" "--dadr A\n"
"Optional BACnet mac address on the destination BACnet network number.\n" "Optional BACnet mac address on the destination BACnet network "
"number.\n"
"Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n" "Valid ranges are from 00 to FF (hex) for MS/TP or ARCNET,\n"
"or an IP string with optional port number like 10.1.2.3:47808\n" "or an IP string with optional port number like 10.1.2.3:47808\n"
"or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n" "or an Ethernet MAC in hex like 00:21:70:7e:32:bb\n"
"\n"); "\n");
printf("device-instance:\n" printf(
"device-instance:\n"
" BACnet device-ID 0..4194303\n" " BACnet device-ID 0..4194303\n"
"vendor-id:\n" "vendor-id:\n"
" Vendor Identifier 0..65535\n" " Vendor Identifier 0..65535\n"
@@ -141,9 +137,7 @@ static void print_help(char *filename)
filename); filename);
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
long dnet = -1; long dnet = -1;
BACNET_MAC_ADDRESS mac = {0}; BACNET_MAC_ADDRESS mac = {0};
@@ -163,8 +157,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2016 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2016 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0; return 0;
@@ -245,11 +241,8 @@ int main(
dlenv_init(); dlenv_init();
atexit(datalink_cleanup); atexit(datalink_cleanup);
/* send the request */ /* send the request */
Send_I_Am_To_Network(&dest, Send_I_Am_To_Network(&dest, Target_Device_ID, Target_Max_APDU,
Target_Device_ID, Target_Segmentation, Target_Vendor_ID);
Target_Max_APDU,
Target_Segmentation,
Target_Vendor_ID);
return 0; return 0;
} }
+16 -20
View File
@@ -53,11 +53,8 @@ static int Target_Router_Networks[MAX_ROUTER_DNETS] = { -1 };
static bool Error_Detected = false; static bool Error_Detected = false;
void MyAbortHandler( void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -67,9 +64,7 @@ void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
void MyRejectHandler( void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
@@ -79,8 +74,7 @@ void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
/* we need to handle who-is /* we need to handle who-is
@@ -88,8 +82,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -108,19 +101,20 @@ static void print_usage(char *filename)
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Send BACnet I-Am-Router-To-Network message for \n" printf(
"one or more networks.\n" "\nDNET:\n" "Send BACnet I-Am-Router-To-Network message for \n"
"one or more networks.\n"
"\nDNET:\n"
"BACnet destination network number 0-65534\n" "BACnet destination network number 0-65534\n"
"To send a I-Am-Router-To-Network message for DNET 86:\n" "To send a I-Am-Router-To-Network message for DNET 86:\n"
"%s 86\n" "%s 86\n"
"To send a I-Am-Router-To-Network message for multiple DNETs\n" "To send a I-Am-Router-To-Network message for multiple DNETs\n"
"use the following command:\n" "%s 86 42 24 14\n", "use the following command:\n"
"%s 86 42 24 14\n",
filename, filename); filename, filename);
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
unsigned arg_count = 0; unsigned arg_count = 0;
int argi = 0; int argi = 0;
@@ -135,8 +129,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
exit(0); exit(0);
+30 -40
View File
@@ -68,11 +68,8 @@ int DNET_list[2] = {
static bool Error_Detected = false; static bool Error_Detected = false;
static void MyAbortHandler( static void MyAbortHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src, uint8_t abort_reason, bool server)
uint8_t invoke_id,
uint8_t abort_reason,
bool server)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
(void)src; (void)src;
@@ -82,9 +79,7 @@ static void MyAbortHandler(
Error_Detected = true; Error_Detected = true;
} }
static void MyRejectHandler( static void MyRejectHandler(BACNET_ADDRESS *src, uint8_t invoke_id,
BACNET_ADDRESS * src,
uint8_t invoke_id,
uint8_t reject_reason) uint8_t reject_reason)
{ {
/* FIXME: verify src and invoke id */ /* FIXME: verify src and invoke id */
@@ -94,9 +89,7 @@ static void MyRejectHandler(
Error_Detected = true; Error_Detected = true;
} }
static void My_Router_Handler( static void My_Router_Handler(BACNET_ADDRESS *src, BACNET_NPDU_DATA *npdu_data,
BACNET_ADDRESS * src,
BACNET_NPDU_DATA * npdu_data,
uint8_t *npdu, /* PDU data */ uint8_t *npdu, /* PDU data */
uint16_t npdu_len) uint16_t npdu_len)
{ {
@@ -183,8 +176,7 @@ static void My_Router_Handler(
} }
} }
static void My_NPDU_Handler( static void My_NPDU_Handler(BACNET_ADDRESS *src, /* source address */
BACNET_ADDRESS * src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t pdu_len) uint16_t pdu_len)
{ /* length PDU */ { /* length PDU */
@@ -219,8 +211,7 @@ static void My_NPDU_Handler(
return; return;
} }
static void Init_Service_Handlers( static void Init_Service_Handlers(void)
void)
{ {
Device_Init(NULL); Device_Init(NULL);
/* we need to handle who-is /* we need to handle who-is
@@ -228,8 +219,7 @@ static void Init_Service_Handlers(
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 /* set the handler for all the services we don't implement
It is required to send the proper reject message... */ It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
(handler_unrecognized_service);
/* we must implement read property - it's required! */ /* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY, apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property); handler_read_property);
@@ -248,23 +238,27 @@ static void print_usage(char *filename)
static void print_help(char *filename) static void print_help(char *filename)
{ {
printf("Send BACnet Initialize-Routing-Table message to a network\n" printf(
"Send BACnet Initialize-Routing-Table message to a network\n"
"and wait for responses. Displays their network information.\n" "and wait for responses. Displays their network information.\n"
"\n" "address:\n" "\n"
"address:\n"
"MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\n" "MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\n"
"DNET ID Len Info:\n" "Port-info data:\n" " DNET:\n" "DNET ID Len Info:\n"
" Destination network number 0-65534\n" " ID:\n" "Port-info data:\n"
" Port Identifier number 0-255\n" " Info:\n" " DNET:\n"
" Destination network number 0-65534\n"
" ID:\n"
" Port Identifier number 0-255\n"
" Info:\n"
" Octet string of data, up to 255 octets\n" " Octet string of data, up to 255 octets\n"
"To query the complete routing table, do not include any port-info.\n" "To query the complete routing table, do not include any port-info.\n"
"To query using Initialize-Routing-Table message to 192.168.0.18:\n" "To query using Initialize-Routing-Table message to 192.168.0.18:\n"
"%s 192.168.0.18:47808\n", filename); "%s 192.168.0.18:47808\n",
filename);
} }
static void address_parse( static void address_parse(BACNET_ADDRESS *dst, int argc, char *argv[])
BACNET_ADDRESS * dst,
int argc,
char *argv[])
{ {
unsigned mac[6]; unsigned mac[6];
unsigned port; unsigned port;
@@ -272,8 +266,7 @@ static void address_parse(
int index = 0; int index = 0;
if (argc > 0) { if (argc > 0) {
count = count = sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
sscanf(argv[0], "%u.%u.%u.%u:%u", &mac[0], &mac[1], &mac[2],
&mac[3], &port); &mac[3], &port);
if (count == 5) { if (count == 5) {
dst->mac_len = 6; dst->mac_len = 6;
@@ -282,9 +275,8 @@ static void address_parse(
} }
encode_unsigned16(&dst->mac[4], port); encode_unsigned16(&dst->mac[4], port);
} else { } else {
count = count = sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1],
sscanf(argv[0], "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[2], &mac[3], &mac[4], &mac[5]);
&mac[3], &mac[4], &mac[5]);
dst->mac_len = count; dst->mac_len = count;
for (index = 0; index < MAX_MAC_LEN; index++) { for (index = 0; index < MAX_MAC_LEN; index++) {
if (index < count) { if (index < count) {
@@ -302,13 +294,9 @@ static void address_parse(
} }
} }
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
BACNET_ADDRESS src = { BACNET_ADDRESS src = {0}; /* address where message came from */
0
}; /* address where message came from */
uint16_t pdu_len = 0; uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */ unsigned timeout = 100; /* milliseconds */
time_t total_seconds = 0; time_t total_seconds = 0;
@@ -328,8 +316,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("%s %s\n", filename, BACNET_VERSION_TEXT); printf("%s %s\n", filename, BACNET_VERSION_TEXT);
printf("Copyright (C) 2014 by Steve Karg and others.\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2014 by Steve Karg and others.\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
exit(0); exit(0);
+81 -119
View File
@@ -133,23 +133,18 @@ struct mstp_statistics {
static struct mstp_statistics MSTP_Statistics[MAX_MSTP_DEVICES]; static struct mstp_statistics MSTP_Statistics[MAX_MSTP_DEVICES];
static uint32_t Invalid_Frame_Count; static uint32_t Invalid_Frame_Count;
static uint32_t timeval_diff_ms( static uint32_t timeval_diff_ms(struct timeval *old, struct timeval *now)
struct timeval *old,
struct timeval *now)
{ {
uint32_t ms = 0; uint32_t ms = 0;
/* convert to milliseconds */ /* convert to milliseconds */
ms = (now->tv_sec - old->tv_sec) * 1000 + (now->tv_usec - ms = (now->tv_sec - old->tv_sec) * 1000 +
old->tv_usec) / 1000; (now->tv_usec - old->tv_usec) / 1000;
return ms; return ms;
} }
static void mstp_monitor_i_am( static void mstp_monitor_i_am(uint8_t mac, uint8_t *pdu, uint16_t pdu_len)
uint8_t mac,
uint8_t * pdu,
uint16_t pdu_len)
{ {
BACNET_ADDRESS src = {0}; BACNET_ADDRESS src = {0};
BACNET_ADDRESS dest = {0}; BACNET_ADDRESS dest = {0};
@@ -176,9 +171,8 @@ static void mstp_monitor_i_am(
service_choice = apdu[1]; service_choice = apdu[1];
service_request = &apdu[2]; service_request = &apdu[2];
if (service_choice == SERVICE_UNCONFIRMED_I_AM) { if (service_choice == SERVICE_UNCONFIRMED_I_AM) {
len = len = iam_decode_service_request(
iam_decode_service_request(service_request, &device_id, service_request, &device_id, NULL, NULL, NULL);
NULL, NULL, NULL);
if (len != -1) { if (len != -1) {
MSTP_Statistics[mac].device_id = device_id; MSTP_Statistics[mac].device_id = device_id;
} }
@@ -188,8 +182,7 @@ static void mstp_monitor_i_am(
} }
} }
static void packet_statistics( static void packet_statistics(struct timeval *tv,
struct timeval *tv,
volatile struct mstp_port_struct_t *mstp_port) volatile struct mstp_port_struct_t *mstp_port)
{ {
static struct timeval old_tv = {0}; static struct timeval old_tv = {0};
@@ -243,8 +236,7 @@ static void packet_statistics(
break; break;
case FRAME_TYPE_POLL_FOR_MASTER: case FRAME_TYPE_POLL_FOR_MASTER:
if (MSTP_Statistics[src].last_pfm_tokens) { if (MSTP_Statistics[src].last_pfm_tokens) {
npoll = npoll = MSTP_Statistics[src].token_received_count -
MSTP_Statistics[src].token_received_count -
MSTP_Statistics[src].last_pfm_tokens; MSTP_Statistics[src].last_pfm_tokens;
if (npoll > MSTP_Statistics[src].npoll) { if (npoll > MSTP_Statistics[src].npoll) {
MSTP_Statistics[src].npoll = npoll; MSTP_Statistics[src].npoll = npoll;
@@ -324,8 +316,7 @@ static void packet_statistics(
old_tv.tv_usec = tv->tv_usec; old_tv.tv_usec = tv->tv_usec;
} }
static void packet_statistics_print( static void packet_statistics_print(void)
void)
{ {
unsigned i; /* loop counter */ unsigned i; /* loop counter */
unsigned node_count = 0; unsigned node_count = 0;
@@ -333,14 +324,14 @@ static void packet_statistics_print(
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, "==== MS/TP Frame Counts ====\n"); fprintf(stdout, "==== MS/TP Frame Counts ====\n");
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", "Device",
"Device", "Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq", "Tokens", "PFM", "RPFM", "DER", "Postpd", "DNER", "TestReq",
"TestRsp"); "TestRsp");
fprintf(stdout, "\n"); fprintf(stdout, "\n");
for (i = 0; i < MAX_MSTP_DEVICES; i++) { for (i = 0; i < MAX_MSTP_DEVICES; i++) {
/* check for masters or slaves */ /* check for masters or slaves */
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply) if ((MSTP_Statistics[i].token_count) ||
|| (MSTP_Statistics[i].pfm_count)) { (MSTP_Statistics[i].der_reply) || (MSTP_Statistics[i].pfm_count)) {
node_count++; node_count++;
fprintf(stdout, "%-8u", i); fprintf(stdout, "%-8u", i);
if (MSTP_Statistics[i].device_id <= 4194303) { if (MSTP_Statistics[i].device_id <= 4194303) {
@@ -367,13 +358,13 @@ static void packet_statistics_print(
fprintf(stdout, "\n"); fprintf(stdout, "\n");
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n"); fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\n");
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC", fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s", "MAC",
"MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage", "Trpfm", "MaxMstr", "Retries", "Npoll", "Self/TT", "Treply", "Tusage",
"Tder", "Tpostpd"); "Trpfm", "Tder", "Tpostpd");
fprintf(stdout, "\n"); fprintf(stdout, "\n");
for (i = 0; i < MAX_MSTP_DEVICES; i++) { for (i = 0; i < MAX_MSTP_DEVICES; i++) {
/* check for masters or slaves */ /* check for masters or slaves */
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply) if ((MSTP_Statistics[i].token_count) ||
|| (MSTP_Statistics[i].pfm_count)) { (MSTP_Statistics[i].der_reply) || (MSTP_Statistics[i].pfm_count)) {
node_count++; node_count++;
self_or_ooo_count = MSTP_Statistics[i].self_token_count + self_or_ooo_count = MSTP_Statistics[i].self_token_count +
MSTP_Statistics[i].ooo_token_count; MSTP_Statistics[i].ooo_token_count;
@@ -397,8 +388,7 @@ static void packet_statistics_print(
(long unsigned int)Invalid_Frame_Count); (long unsigned int)Invalid_Frame_Count);
} }
static void packet_statistics_clear( static void packet_statistics_clear(void)
void)
{ {
unsigned i = 0; unsigned i = 0;
@@ -409,21 +399,18 @@ static void packet_statistics_clear(
Invalid_Frame_Count = 0; Invalid_Frame_Count = 0;
} }
static uint32_t Timer_Silence( static uint32_t Timer_Silence(void *pArg)
void *pArg)
{ {
return timer_milliseconds(TIMER_SILENCE); return timer_milliseconds(TIMER_SILENCE);
} }
static void Timer_Silence_Reset( static void Timer_Silence_Reset(void *pArg)
void *pArg)
{ {
timer_reset(TIMER_SILENCE); timer_reset(TIMER_SILENCE);
} }
/* functions used by the MS/TP state machine to put or get data */ /* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive( uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
(void)mstp_port; (void)mstp_port;
@@ -432,8 +419,7 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */ /* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */ /* Return: amount of PDU data */
uint16_t MSTP_Get_Send( uint16_t MSTP_Get_Send(volatile struct mstp_port_struct_t *mstp_port,
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout) unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
@@ -441,8 +427,7 @@ uint16_t MSTP_Get_Send(
return 0; return 0;
} }
uint16_t MSTP_Get_Reply( uint16_t MSTP_Get_Reply(volatile struct mstp_port_struct_t *mstp_port,
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout) unsigned timeout)
{ /* milliseconds to wait for a packet */ { /* milliseconds to wait for a packet */
(void)mstp_port; (void)mstp_port;
@@ -454,31 +439,23 @@ static char Capture_Filename[64] = "mstp_20090123091200.cap";
static FILE *pFile = NULL; /* stream pointer */ static FILE *pFile = NULL; /* stream pointer */
#if defined(_WIN32) #if defined(_WIN32)
static HANDLE hPipe = INVALID_HANDLE_VALUE; /* pipe handle */ static HANDLE hPipe = INVALID_HANDLE_VALUE; /* pipe handle */
static void named_pipe_create( static void named_pipe_create(char *pipe_name)
char *pipe_name)
{ {
if (!Wireshark_Capture) { if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: Creating Named Pipe \"%s\"\n", pipe_name); fprintf(stdout, "mstpcap: Creating Named Pipe \"%s\"\n", pipe_name);
} }
/* create the pipe */ /* create the pipe */
while (hPipe == INVALID_HANDLE_VALUE) while (hPipe == INVALID_HANDLE_VALUE) {
{
/* use CreateFile rather than CreateNamedPipe */ /* use CreateFile rather than CreateNamedPipe */
hPipe = CreateFile( hPipe = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
pipe_name, OPEN_EXISTING, 0, NULL);
GENERIC_READ |
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hPipe != INVALID_HANDLE_VALUE) { if (hPipe != INVALID_HANDLE_VALUE) {
break; break;
} }
/* if an error occured at handle creation */ /* if an error occured at handle creation */
if (!WaitNamedPipe(pipe_name, 20000)) { if (!WaitNamedPipe(pipe_name, 20000)) {
printf("Could not open pipe: waited for 20sec!\n" printf(
"Could not open pipe: waited for 20sec!\n"
"If this message was issued before the 20sec finished,\n" "If this message was issued before the 20sec finished,\n"
"then the pipe doesn't exist!\n"); "then the pipe doesn't exist!\n");
Exit_Requested = true; Exit_Requested = true;
@@ -488,10 +465,7 @@ static void named_pipe_create(
ConnectNamedPipe(hPipe, NULL); ConnectNamedPipe(hPipe, NULL);
} }
size_t data_write( size_t data_write(const void *ptr, size_t size, size_t nitems)
const void *ptr,
size_t size,
size_t nitems)
{ {
DWORD cbWritten = 0; DWORD cbWritten = 0;
if (hPipe != INVALID_HANDLE_VALUE) { if (hPipe != INVALID_HANDLE_VALUE) {
@@ -505,10 +479,7 @@ size_t data_write(
return fwrite(ptr, size, nitems, pFile); return fwrite(ptr, size, nitems, pFile);
} }
size_t data_write_header( size_t data_write_header(const void *ptr, size_t size, size_t nitems,
const void *ptr,
size_t size,
size_t nitems,
bool pipe_enable) bool pipe_enable)
{ {
DWORD cbWritten = 0; DWORD cbWritten = 0;
@@ -524,8 +495,7 @@ size_t data_write_header(
} }
#else #else
static int FD_Pipe = -1; static int FD_Pipe = -1;
static void named_pipe_create( static void named_pipe_create(char *name)
char *name)
{ {
int rv = 0; int rv = 0;
rv = mkfifo(name, 0666); rv = mkfifo(name, 0666);
@@ -540,10 +510,7 @@ static void named_pipe_create(
} }
} }
size_t data_write( size_t data_write(const void *ptr, size_t size, size_t nitems)
const void *ptr,
size_t size,
size_t nitems)
{ {
ssize_t bytes = 0; ssize_t bytes = 0;
if (FD_Pipe != -1) { if (FD_Pipe != -1) {
@@ -553,10 +520,7 @@ size_t data_write(
return fwrite(ptr, size, nitems, pFile); return fwrite(ptr, size, nitems, pFile);
} }
size_t data_write_header( size_t data_write_header(const void *ptr, size_t size, size_t nitems,
const void *ptr,
size_t size,
size_t nitems,
bool pipe_enable) bool pipe_enable)
{ {
ssize_t bytes = 0; ssize_t bytes = 0;
@@ -568,8 +532,7 @@ size_t data_write_header(
} }
#endif #endif
static void filename_create( static void filename_create(char *filename)
char *filename)
{ {
time_t my_time; time_t my_time;
struct tm *today; struct tm *today;
@@ -584,8 +547,7 @@ static void filename_create(
} }
/* write packet to file in libpcap format */ /* write packet to file in libpcap format */
static void write_global_header( static void write_global_header(const char *filename)
const char *filename)
{ {
static bool pipe_enable = true; /* don't write more than one header */ static bool pipe_enable = true; /* don't write more than one header */
uint32_t magic_number = 0xa1b2c3d4; /* magic number */ uint32_t magic_number = 0xa1b2c3d4; /* magic number */
@@ -622,9 +584,7 @@ static void write_global_header(
} }
} }
static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port,
static void write_received_packet(
volatile struct mstp_port_struct_t *mstp_port,
size_t header_len) size_t header_len)
{ {
uint32_t ts_sec = 0; /* timestamp seconds */ uint32_t ts_sec = 0; /* timestamp seconds */
@@ -655,7 +615,8 @@ static void write_received_packet(
} }
} else { } else {
if (mstp_port->DataLength) { if (mstp_port->DataLength) {
max_data = min(mstp_port->InputBufferSize, mstp_port->DataLength); max_data =
min(mstp_port->InputBufferSize, mstp_port->DataLength);
incl_len = orig_len = header_len + max_data + 2 /* checksum*/; incl_len = orig_len = header_len + max_data + 2 /* checksum*/;
} else { } else {
/* header only - or at least some bytes of the header */ /* header only - or at least some bytes of the header */
@@ -692,8 +653,7 @@ static void write_received_packet(
} }
/* read header from file in libpcap format */ /* read header from file in libpcap format */
static bool test_global_header( static bool test_global_header(const char *filename)
const char *filename)
{ {
uint32_t magic_number = 0; /* magic number */ uint32_t magic_number = 0; /* magic number */
uint16_t version_major = 0; /* major version number */ uint16_t version_major = 0; /* major version number */
@@ -765,8 +725,7 @@ static bool test_global_header(
return true; return true;
} }
static bool read_received_packet( static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
uint32_t ts_sec = 0; /* timestamp seconds */ uint32_t ts_sec = 0; /* timestamp seconds */
uint32_t ts_usec = 0; /* timestamp microseconds */ uint32_t ts_usec = 0; /* timestamp microseconds */
@@ -855,8 +814,7 @@ static bool read_received_packet(
} }
mstp_port->DataCRC = 0xFFFF; mstp_port->DataCRC = 0xFFFF;
for (i = 0; i < mstp_port->DataLength; i++) { for (i = 0; i < mstp_port->DataLength; i++) {
mstp_port->DataCRC = mstp_port->DataCRC = CRC_Calc_Data(mstp_port->InputBuffer[i],
CRC_Calc_Data(mstp_port->InputBuffer[i],
mstp_port->DataCRC); mstp_port->DataCRC);
} }
mstp_port->DataCRC = mstp_port->DataCRC =
@@ -888,8 +846,7 @@ static bool read_received_packet(
return true; return true;
} }
static void cleanup( static void cleanup(void)
void)
{ {
if (!Wireshark_Capture) { if (!Wireshark_Capture) {
packet_statistics_print(); packet_statistics_print();
@@ -902,8 +859,7 @@ static void cleanup(
} }
#if defined(_WIN32) #if defined(_WIN32)
static BOOL WINAPI CtrlCHandler( static BOOL WINAPI CtrlCHandler(DWORD dwCtrlType)
DWORD dwCtrlType)
{ {
dwCtrlType = dwCtrlType; dwCtrlType = dwCtrlType;
@@ -923,8 +879,7 @@ static BOOL WINAPI CtrlCHandler(
return TRUE; return TRUE;
} }
#else #else
static void sig_int( static void sig_int(int signo)
int signo)
{ {
(void)signo; (void)signo;
if (FD_Pipe != -1) { if (FD_Pipe != -1) {
@@ -934,8 +889,7 @@ static void sig_int(
exit(0); exit(0);
} }
void signal_init( void signal_init(void)
void)
{ {
signal(SIGINT, sig_int); signal(SIGINT, sig_int);
signal(SIGHUP, sig_int); signal(SIGHUP, sig_int);
@@ -943,8 +897,7 @@ void signal_init(
} }
#endif #endif
void filename_create_new( void filename_create_new(void)
void)
{ {
if (pFile) { if (pFile) {
fclose(pFile); fclose(pFile);
@@ -954,8 +907,7 @@ void filename_create_new(
write_global_header(&Capture_Filename[0]); write_global_header(&Capture_Filename[0]);
} }
static void print_usage( static void print_usage(char *filename)
char *filename)
{ {
printf("Usage: %s", filename); printf("Usage: %s", filename);
printf(" [--scan <filename>]\n"); printf(" [--scan <filename>]\n");
@@ -965,15 +917,19 @@ static void print_usage(
printf(" [--version][--help]\n"); printf(" [--version][--help]\n");
} }
static void print_help(char *filename) { static void print_help(char *filename)
printf("%s --scan <filename>\n" {
printf(
"%s --scan <filename>\n"
"perform statistic analysis on MS/TP capture file.\n", "perform statistic analysis on MS/TP capture file.\n",
filename); filename);
printf("\n"); printf("\n");
printf("Captures MS/TP packets from a serial interface\n" printf(
"Captures MS/TP packets from a serial interface\n"
"and saves them to a file. Saves packets in a\n" "and saves them to a file. Saves packets in a\n"
"filename mstp_20090123091200.cap that has data and time.\n" "filename mstp_20090123091200.cap that has data and time.\n"
"After receiving 65535 packets, a new file is created.\n" "\n" "After receiving 65535 packets, a new file is created.\n"
"\n"
"Command line options:\n" "Command line options:\n"
"[--extcap-interface port] - serial interface.\n" "[--extcap-interface port] - serial interface.\n"
#if defined(_WIN32) #if defined(_WIN32)
@@ -992,7 +948,8 @@ static void print_help(char *filename) {
#endif #endif
" Use that name as the interface name in Wireshark.\n"); " Use that name as the interface name in Wireshark.\n");
printf("\n"); printf("\n");
printf("%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n" printf(
"%s [--extcap-interfaces][--extcap-dlts][--extcap-config]\n"
"[--capture][--baud baud][--fifo pipe]\n" "[--capture][--baud baud][--fifo pipe]\n"
"[--extcap-interface iface]\n" "[--extcap-interface iface]\n"
"Usage from Wireshark ExtCap interface\n", "Usage from Wireshark ExtCap interface\n",
@@ -1000,8 +957,7 @@ static void print_help(char *filename) {
} }
/* initialize some of the variables in the MS/TP Receive structure */ /* initialize some of the variables in the MS/TP Receive structure */
static void mstp_structure_init( static void mstp_structure_init(volatile struct mstp_port_struct_t *mstp_port)
volatile struct mstp_port_struct_t *mstp_port)
{ {
if (mstp_port) { if (mstp_port) {
mstp_port->FrameType = FRAME_TYPE_PROPRIETARY_MAX; mstp_port->FrameType = FRAME_TYPE_PROPRIETARY_MAX;
@@ -1019,9 +975,7 @@ static void mstp_structure_init(
} }
/* simple test to packetize the data and print it */ /* simple test to packetize the data and print it */
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
volatile struct mstp_port_struct_t *mstp_port; volatile struct mstp_port_struct_t *mstp_port;
long my_baud = 38400; long my_baud = 38400;
@@ -1053,8 +1007,10 @@ int main(
} }
if (strcmp(argv[argi], "--version") == 0) { if (strcmp(argv[argi], "--version") == 0) {
printf("mstpcap %s\n", BACNET_VERSION_TEXT); printf("mstpcap %s\n", BACNET_VERSION_TEXT);
printf("Copyright (C) 2011-2016 by Steve Karg\n" printf(
"This is free software; see the source for copying conditions.\n" "Copyright (C) 2011-2016 by Steve Karg\n"
"This is free software; see the source for copying "
"conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or\n" "There is NO warranty; not even for MERCHANTABILITY or\n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"); "FITNESS FOR A PARTICULAR PURPOSE.\n");
return 0; return 0;
@@ -1070,8 +1026,7 @@ int main(
if (test_global_header(argv[argi])) { if (test_global_header(argv[argi])) {
while (read_received_packet(mstp_port)) { while (read_received_packet(mstp_port)) {
packet_count++; packet_count++;
fprintf(stderr, "\r%u packets", fprintf(stderr, "\r%u packets", (unsigned)packet_count);
(unsigned) packet_count);
} }
if (packet_count) { if (packet_count) {
packet_statistics_print(); packet_statistics_print();
@@ -1092,21 +1047,27 @@ int main(
printf("An interface must be provided.\n"); printf("An interface must be provided.\n");
return 0; return 0;
} }
printf("dlt {number=%u}{name=BACnet MS/TP}" printf(
"dlt {number=%u}{name=BACnet MS/TP}"
"{display=BACnet MS/TP}\n", "{display=BACnet MS/TP}\n",
DLT_BACNET_MS_TP); DLT_BACNET_MS_TP);
Exit_Requested = true; Exit_Requested = true;
} }
if (strcmp(argv[argi], "--extcap-config") == 0) { if (strcmp(argv[argi], "--extcap-config") == 0) {
printf("arg {number=0}{call=--baud}{display=Baud Rate}" printf(
"arg {number=0}{call=--baud}{display=Baud Rate}"
"{tooltip=Serial port baud rate in bits per second}" "{tooltip=Serial port baud rate in bits per second}"
"{type=selector}\n"); "{type=selector}\n");
printf("value {arg=0}{value=9600}{display=9600}{default=false}\n"); printf("value {arg=0}{value=9600}{display=9600}{default=false}\n");
printf("value {arg=0}{value=19200}{display=19200}{default=false}\n"); printf(
"value {arg=0}{value=19200}{display=19200}{default=false}\n");
printf("value {arg=0}{value=38400}{display=38400}{default=true}\n"); printf("value {arg=0}{value=38400}{display=38400}{default=true}\n");
printf("value {arg=0}{value=57600}{display=57600}{default=false}\n"); printf(
printf("value {arg=0}{value=76800}{display=76800}{default=false}\n"); "value {arg=0}{value=57600}{display=57600}{default=false}\n");
printf("value {arg=0}{value=115200}{display=115200}{default=false}\n"); printf(
"value {arg=0}{value=76800}{display=76800}{default=false}\n");
printf(
"value {arg=0}{value=115200}{display=115200}{default=false}\n");
return 0; return 0;
} }
if (strcmp(argv[argi], "--capture") == 0) { if (strcmp(argv[argi], "--capture") == 0) {
@@ -1116,7 +1077,8 @@ int main(
if (strcmp(argv[argi], "--extcap-interface") == 0) { if (strcmp(argv[argi], "--extcap-interface") == 0) {
argi++; argi++;
if (argi >= argc) { if (argi >= argc) {
printf("An interface must be provided or " printf(
"An interface must be provided or "
"the selection must be displayed.\n"); "the selection must be displayed.\n");
return 0; return 0;
} }
@@ -1228,8 +1190,8 @@ int main(
} }
if (!Wireshark_Capture) { if (!Wireshark_Capture) {
if (!(packet_count % 100)) { if (!(packet_count % 100)) {
fprintf(stdout, "\r%hu packets, %hu invalid frames", packet_count, fprintf(stdout, "\r%hu packets, %hu invalid frames",
Invalid_Frame_Count); packet_count, Invalid_Frame_Count);
} }
if (packet_count >= 65535) { if (packet_count >= 65535) {
packet_statistics_print(); packet_statistics_print();
+13 -21
View File
@@ -74,8 +74,7 @@ static FILE *pText_File = NULL; /* stream pointer */
* RETURN: nothing * RETURN: nothing
* NOTES: none * NOTES: none
******************************************************************/ ******************************************************************/
static void Parse_Number( static void Parse_Number(char *argi)
char *argi)
{ {
long long_value = 0; long long_value = 0;
@@ -96,9 +95,7 @@ static void Parse_Number(
* RETURN: number of arguments parsed * RETURN: number of arguments parsed
* NOTES: none * NOTES: none
******************************************************************/ ******************************************************************/
static void Parse_Arguments( static void Parse_Arguments(int argc, char *argv[])
int argc,
char *argv[])
{ {
int i = 0; int i = 0;
long long_value = 0; long long_value = 0;
@@ -156,8 +153,7 @@ static void Parse_Arguments(
} }
} }
static void filename_create( static void filename_create(char *filename)
char *filename)
{ {
time_t my_time; time_t my_time;
struct tm *today; struct tm *today;
@@ -172,8 +168,7 @@ static void filename_create(
} }
/* write packet to file in libpcap format */ /* write packet to file in libpcap format */
static void write_global_header( static void write_global_header(const char *filename)
const char *filename)
{ {
uint32_t magic_number = 0xa1b2c3d4; /* magic number */ uint32_t magic_number = 0xa1b2c3d4; /* magic number */
uint16_t version_major = 2; /* major version number */ uint16_t version_major = 2; /* major version number */
@@ -201,9 +196,7 @@ static void write_global_header(
} }
} }
static void write_received_packet( static void write_received_packet(uint8_t *buffer, unsigned length)
uint8_t * buffer,
unsigned length)
{ {
uint32_t ts_sec; /* timestamp seconds */ uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */ uint32_t ts_usec; /* timestamp microseconds */
@@ -227,9 +220,7 @@ static void write_received_packet(
} }
} }
static void Write_Pcap( static void Write_Pcap(uint8_t *buffer, unsigned length)
uint8_t * buffer,
unsigned length)
{ {
filename_create(&Capture_Filename[0]); filename_create(&Capture_Filename[0]);
write_global_header(&Capture_Filename[0]); write_global_header(&Capture_Filename[0]);
@@ -269,9 +260,7 @@ static void Process_Text_File(void)
} }
/* simple program to CRC the data and print the CRC */ /* simple program to CRC the data and print the CRC */
int main( int main(int argc, char *argv[])
int argc,
char *argv[])
{ {
/* accumulates the crc value */ /* accumulates the crc value */
uint8_t crc8 = 0xff; uint8_t crc8 = 0xff;
@@ -280,8 +269,10 @@ int main(
/* initialize our interface */ /* initialize our interface */
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("mstpcrc [options] <05 03 01 0D...>\r\n" printf(
"perform MS/TP CRC on data bytes.\r\n" "options:\r\n" "mstpcrc [options] <05 03 01 0D...>\r\n"
"perform MS/TP CRC on data bytes.\r\n"
"options:\r\n"
"[-x] interprete the arguments as ascii hex (default)\r\n" "[-x] interprete the arguments as ascii hex (default)\r\n"
"[-d] interprete the argument as ascii decimal\r\n" "[-d] interprete the argument as ascii decimal\r\n"
"[-m] Write the bytes to Wireshark capture file\r\n" "[-m] Write the bytes to Wireshark capture file\r\n"
@@ -294,7 +285,8 @@ int main(
} }
if ((argc > 1) && (strcmp(argv[1], "--version") == 0)) { if ((argc > 1) && (strcmp(argv[1], "--version") == 0)) {
printf("mstpcap %s\r\n", BACNET_VERSION_TEXT); printf("mstpcap %s\r\n", BACNET_VERSION_TEXT);
printf("Copyright (C) 2012 by Steve Karg\r\n" printf(
"Copyright (C) 2012 by Steve Karg\r\n"
"This is free software; see the source for copying conditions.\r\n" "This is free software; see the source for copying conditions.\r\n"
"There is NO warranty; not even for MERCHANTABILITY or\r\n" "There is NO warranty; not even for MERCHANTABILITY or\r\n"
"FITNESS FOR A PARTICULAR PURPOSE.\r\n"); "FITNESS FOR A PARTICULAR PURPOSE.\r\n");
+61 -94
View File
@@ -43,8 +43,7 @@ static bool Access_Credential_Initialized = false;
static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS]; static ACCESS_CREDENTIAL_DESCR ac_descr[MAX_ACCESS_CREDENTIALS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER, PROP_GLOBAL_IDENTIFIER,
@@ -57,19 +56,13 @@ static const int Properties_Required[] = {
PROP_EXPIRATION_TIME, PROP_EXPIRATION_TIME,
PROP_CREDENTIAL_DISABLE, PROP_CREDENTIAL_DISABLE,
PROP_ASSIGNED_ACCESS_RIGHTS, PROP_ASSIGNED_ACCESS_RIGHTS,
-1 -1};
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Access_Credential_Property_Lists( void Access_Credential_Property_Lists(const int **pRequired,
const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
@@ -83,8 +76,7 @@ void Access_Credential_Property_Lists(
return; return;
} }
void Access_Credential_Init( void Access_Credential_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -92,7 +84,8 @@ void Access_Credential_Init(
Access_Credential_Initialized = true; Access_Credential_Initialized = true;
for (i = 0; i < MAX_ACCESS_CREDENTIALS; i++) { for (i = 0; i < MAX_ACCESS_CREDENTIALS; i++) {
ac_descr[i].global_identifier = 0; /* set to some meaningful value */ ac_descr[i].global_identifier =
0; /* set to some meaningful value */
ac_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED; ac_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
ac_descr[i].credential_status = false; ac_descr[i].credential_status = false;
ac_descr[i].reasons_count = 0; ac_descr[i].reasons_count = 0;
@@ -110,8 +103,7 @@ void Access_Credential_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Access_Credential_Valid_Instance( bool Access_Credential_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ACCESS_CREDENTIALS) if (object_instance < MAX_ACCESS_CREDENTIALS)
return true; return true;
@@ -121,8 +113,7 @@ bool Access_Credential_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Access_Credential_Count( unsigned Access_Credential_Count(void)
void)
{ {
return MAX_ACCESS_CREDENTIALS; return MAX_ACCESS_CREDENTIALS;
} }
@@ -130,8 +121,7 @@ unsigned Access_Credential_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Access_Credential_Index_To_Instance( uint32_t Access_Credential_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -139,8 +129,7 @@ uint32_t Access_Credential_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Access_Credential_Instance_To_Index( unsigned Access_Credential_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ACCESS_CREDENTIALS; unsigned index = MAX_ACCESS_CREDENTIALS;
@@ -151,8 +140,7 @@ unsigned Access_Credential_Instance_To_Index(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Access_Credential_Object_Name( bool Access_Credential_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -168,8 +156,7 @@ bool Access_Credential_Object_Name(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Credential_Read_Property( int Access_Credential_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -184,13 +171,11 @@ int Access_Credential_Read_Property(
return 0; return 0;
} }
apdu = rpdata->application_data; apdu = rpdata->application_data;
object_index = object_index = Access_Credential_Instance_To_Index(rpdata->object_instance);
Access_Credential_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], &apdu[0], OBJECT_ACCESS_CREDENTIAL, rpdata->object_instance);
OBJECT_ACCESS_CREDENTIAL, rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Access_Credential_Object_Name(rpdata->object_instance, Access_Credential_Object_Name(rpdata->object_instance,
@@ -199,14 +184,12 @@ int Access_Credential_Read_Property(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len = encode_application_enumerated(&apdu[0],
encode_application_enumerated(&apdu[0],
OBJECT_ACCESS_CREDENTIAL); OBJECT_ACCESS_CREDENTIAL);
break; break;
case PROP_GLOBAL_IDENTIFIER: case PROP_GLOBAL_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ac_descr[object_index].global_identifier);
ac_descr[object_index].global_identifier);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -217,20 +200,17 @@ int Access_Credential_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ac_descr[object_index].reliability);
ac_descr[object_index].reliability);
break; break;
case PROP_CREDENTIAL_STATUS: case PROP_CREDENTIAL_STATUS:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ac_descr[object_index].credential_status);
ac_descr[object_index].credential_status);
break; break;
case PROP_REASON_FOR_DISABLE: case PROP_REASON_FOR_DISABLE:
for (i = 0; i < ac_descr[object_index].reasons_count; i++) { for (i = 0; i < ac_descr[object_index].reasons_count; i++) {
len = len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ac_descr[object_index].reason_for_disable[i]);
ac_descr[object_index].reason_for_disable[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
@@ -243,14 +223,13 @@ int Access_Credential_Read_Property(
break; break;
case PROP_AUTHENTICATION_FACTORS: case PROP_AUTHENTICATION_FACTORS:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ac_descr[object_index].auth_factors_count);
ac_descr[object_index].auth_factors_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < ac_descr[object_index].auth_factors_count; i++) { for (i = 0; i < ac_descr[object_index].auth_factors_count;
len = i++) {
bacapp_encode_credential_authentication_factor(&apdu len = bacapp_encode_credential_authentication_factor(
[0], &ac_descr[object_index].auth_factors[i]); &apdu[0], &ac_descr[object_index].auth_factors[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
@@ -263,11 +242,9 @@ int Access_Credential_Read_Property(
} else { } else {
if (rpdata->array_index <= if (rpdata->array_index <=
ac_descr[object_index].auth_factors_count) { ac_descr[object_index].auth_factors_count) {
apdu_len = apdu_len = bacapp_encode_credential_authentication_factor(
bacapp_encode_credential_authentication_factor(&apdu &apdu[0], &ac_descr[object_index]
[0], .auth_factors[rpdata->array_index - 1]);
&ac_descr[object_index].
auth_factors[rpdata->array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -276,31 +253,28 @@ int Access_Credential_Read_Property(
} }
break; break;
case PROP_ACTIVATION_TIME: case PROP_ACTIVATION_TIME:
apdu_len = apdu_len = bacapp_encode_datetime(
bacapp_encode_datetime(&apdu[0], &apdu[0], &ac_descr[object_index].activation_time);
&ac_descr[object_index].activation_time);
break; break;
case PROP_EXPIRATION_TIME: case PROP_EXPIRATION_TIME:
apdu_len = apdu_len = bacapp_encode_datetime(
bacapp_encode_datetime(&apdu[0], &apdu[0], &ac_descr[object_index].expiration_time);
&ac_descr[object_index].expiration_time);
break; break;
case PROP_CREDENTIAL_DISABLE: case PROP_CREDENTIAL_DISABLE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ac_descr[object_index].credential_disable);
ac_descr[object_index].credential_disable);
break; break;
case PROP_ASSIGNED_ACCESS_RIGHTS: case PROP_ASSIGNED_ACCESS_RIGHTS:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0],
ac_descr[object_index].assigned_access_rights_count); ac_descr[object_index].assigned_access_rights_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; for (i = 0;
i < ac_descr[object_index].assigned_access_rights_count; i < ac_descr[object_index].assigned_access_rights_count;
i++) { i++) {
len = len = bacapp_encode_assigned_access_rights(
bacapp_encode_assigned_access_rights(&apdu[0], &apdu[0],
&ac_descr[object_index].assigned_access_rights[i]); &ac_descr[object_index].assigned_access_rights[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
@@ -314,10 +288,10 @@ int Access_Credential_Read_Property(
} else { } else {
if (rpdata->array_index <= if (rpdata->array_index <=
ac_descr[object_index].assigned_access_rights_count) { ac_descr[object_index].assigned_access_rights_count) {
apdu_len = apdu_len = bacapp_encode_assigned_access_rights(
bacapp_encode_assigned_access_rights(&apdu[0], &apdu[0],
&ac_descr[object_index]. &ac_descr[object_index]
assigned_access_rights[rpdata->array_index - 1]); .assigned_access_rights[rpdata->array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -333,9 +307,9 @@ int Access_Credential_Read_Property(
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
(rpdata->object_property != PROP_AUTHENTICATION_FACTORS) (rpdata->object_property != PROP_AUTHENTICATION_FACTORS) &&
&& (rpdata->object_property != PROP_ASSIGNED_ACCESS_RIGHTS) (rpdata->object_property != PROP_ASSIGNED_ACCESS_RIGHTS) &&
&& (rpdata->array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -345,8 +319,7 @@ int Access_Credential_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Access_Credential_Write_Property( bool Access_Credential_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -354,8 +327,7 @@ bool Access_Credential_Write_Property(
unsigned object_index = 0; unsigned object_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -365,9 +337,9 @@ bool Access_Credential_Write_Property(
return false; return false;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((wp_data->object_property != PROP_AUTHENTICATION_FACTORS) if ((wp_data->object_property != PROP_AUTHENTICATION_FACTORS) &&
&& (wp_data->object_property != PROP_ASSIGNED_ACCESS_RIGHTS) (wp_data->object_property != PROP_ASSIGNED_ACCESS_RIGHTS) &&
&& (wp_data->array_index != BACNET_ARRAY_ALL)) { (wp_data->array_index != BACNET_ARRAY_ALL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false; return false;
@@ -408,16 +380,13 @@ bool Access_Credential_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -428,8 +397,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAccessCredential( void testAccessCredential(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -458,8 +426,7 @@ void testAccessCredential(
} }
#ifdef TEST_ACCESS_CREDENTIAL #ifdef TEST_ACCESS_CREDENTIAL
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+77 -128
View File
@@ -42,8 +42,7 @@ static bool Access_Door_Initialized = false;
static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS]; static ACCESS_DOOR_DESCR ad_descr[MAX_ACCESS_DOORS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
@@ -56,25 +55,16 @@ static const int Properties_Required[] = {
PROP_DOOR_PULSE_TIME, PROP_DOOR_PULSE_TIME,
PROP_DOOR_EXTENDED_PULSE_TIME, PROP_DOOR_EXTENDED_PULSE_TIME,
PROP_DOOR_OPEN_TOO_LONG_TIME, PROP_DOOR_OPEN_TOO_LONG_TIME,
-1 -1};
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {
PROP_DOOR_STATUS, PROP_DOOR_STATUS, PROP_LOCK_STATUS,
PROP_LOCK_STATUS, PROP_SECURED_STATUS, PROP_DOOR_UNLOCK_DELAY_TIME,
PROP_SECURED_STATUS, PROP_DOOR_ALARM_STATE, -1};
PROP_DOOR_UNLOCK_DELAY_TIME,
PROP_DOOR_ALARM_STATE,
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Access_Door_Property_Lists( void Access_Door_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -87,8 +77,7 @@ void Access_Door_Property_Lists(
return; return;
} }
void Access_Door_Init( void Access_Door_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
@@ -123,8 +112,7 @@ void Access_Door_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Access_Door_Valid_Instance( bool Access_Door_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ACCESS_DOORS) if (object_instance < MAX_ACCESS_DOORS)
return true; return true;
@@ -134,8 +122,7 @@ bool Access_Door_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Access_Door_Count( unsigned Access_Door_Count(void)
void)
{ {
return MAX_ACCESS_DOORS; return MAX_ACCESS_DOORS;
} }
@@ -143,8 +130,7 @@ unsigned Access_Door_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Access_Door_Index_To_Instance( uint32_t Access_Door_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -152,8 +138,7 @@ uint32_t Access_Door_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Access_Door_Instance_To_Index( unsigned Access_Door_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ACCESS_DOORS; unsigned index = MAX_ACCESS_DOORS;
@@ -163,8 +148,7 @@ unsigned Access_Door_Instance_To_Index(
return index; return index;
} }
BACNET_DOOR_VALUE Access_Door_Present_Value( BACNET_DOOR_VALUE Access_Door_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
unsigned i = 0; unsigned i = 0;
@@ -183,8 +167,7 @@ BACNET_DOOR_VALUE Access_Door_Present_Value(
return value; return value;
} }
unsigned Access_Door_Present_Value_Priority( unsigned Access_Door_Present_Value_Priority(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; /* instance to index conversion */ unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
@@ -203,10 +186,8 @@ unsigned Access_Door_Present_Value_Priority(
return priority; return priority;
} }
bool Access_Door_Present_Value_Set( bool Access_Door_Present_Value_Set(uint32_t object_instance,
uint32_t object_instance, BACNET_DOOR_VALUE value, unsigned priority)
BACNET_DOOR_VALUE value,
unsigned priority)
{ {
unsigned index = 0; unsigned index = 0;
bool status = false; bool status = false;
@@ -214,8 +195,7 @@ bool Access_Door_Present_Value_Set(
index = Access_Door_Instance_To_Index(object_instance); index = Access_Door_Instance_To_Index(object_instance);
if (index < MAX_ACCESS_DOORS) { if (index < MAX_ACCESS_DOORS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) && (priority != 6 /* reserved */) && (value >= DOOR_VALUE_LOCK) &&
(value >= DOOR_VALUE_LOCK) &&
(value <= DOOR_VALUE_EXTENDED_PULSE_UNLOCK)) { (value <= DOOR_VALUE_EXTENDED_PULSE_UNLOCK)) {
ad_descr[index].value_active[priority - 1] = true; ad_descr[index].value_active[priority - 1] = true;
ad_descr[index].priority_array[priority - 1] = value; ad_descr[index].priority_array[priority - 1] = value;
@@ -232,8 +212,7 @@ bool Access_Door_Present_Value_Set(
return status; return status;
} }
bool Access_Door_Present_Value_Relinquish( bool Access_Door_Present_Value_Relinquish(uint32_t object_instance,
uint32_t object_instance,
unsigned priority) unsigned priority)
{ {
unsigned index = 0; unsigned index = 0;
@@ -257,8 +236,7 @@ bool Access_Door_Present_Value_Relinquish(
return status; return status;
} }
BACNET_DOOR_VALUE Access_Door_Relinquish_Default( BACNET_DOOR_VALUE Access_Door_Relinquish_Default(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_DOOR_VALUE status = -1; BACNET_DOOR_VALUE status = -1;
unsigned index = 0; unsigned index = 0;
@@ -271,24 +249,21 @@ BACNET_DOOR_VALUE Access_Door_Relinquish_Default(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Access_Door_Object_Name( bool Access_Door_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
bool status = false; bool status = false;
if (object_instance < MAX_ACCESS_DOORS) { if (object_instance < MAX_ACCESS_DOORS) {
sprintf(text_string, "ACCESS DOOR %lu", sprintf(text_string, "ACCESS DOOR %lu", (unsigned long)object_instance);
(unsigned long) object_instance);
status = characterstring_init_ansi(object_name, text_string); status = characterstring_init_ansi(object_name, text_string);
} }
return status; return status;
} }
bool Access_Door_Out_Of_Service( bool Access_Door_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned index = 0; unsigned index = 0;
bool oos_flag = false; bool oos_flag = false;
@@ -301,9 +276,7 @@ bool Access_Door_Out_Of_Service(
return oos_flag; return oos_flag;
} }
void Access_Door_Out_Of_Service_Set( void Access_Door_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
uint32_t instance,
bool oos_flag)
{ {
unsigned index = 0; unsigned index = 0;
@@ -314,8 +287,7 @@ void Access_Door_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Door_Read_Property( int Access_Door_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -334,9 +306,8 @@ int Access_Door_Read_Property(
object_index = Access_Door_Instance_To_Index(rpdata->object_instance); object_index = Access_Door_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ACCESS_DOOR, &apdu[0], OBJECT_ACCESS_DOOR, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Access_Door_Object_Name(rpdata->object_instance, &char_string); Access_Door_Object_Name(rpdata->object_instance, &char_string);
@@ -348,9 +319,8 @@ int Access_Door_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ACCESS_DOOR); encode_application_enumerated(&apdu[0], OBJECT_ACCESS_DOOR);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Access_Door_Present_Value(rpdata->object_instance));
Access_Door_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -362,14 +332,12 @@ int Access_Door_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ad_descr[object_index].event_state);
ad_descr[object_index].event_state);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ad_descr[object_index].reliability);
ad_descr[object_index].reliability);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
state = Access_Door_Out_Of_Service(rpdata->object_instance); state = Access_Door_Out_Of_Service(rpdata->object_instance);
@@ -388,8 +356,8 @@ int Access_Door_Read_Property(
if (ad_descr[object_index].value_active[i]) if (ad_descr[object_index].value_active[i])
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
else else
len = len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len],
ad_descr[object_index].priority_array[i]); ad_descr[object_index].priority_array[i]);
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
@@ -406,8 +374,8 @@ int Access_Door_Read_Property(
if (ad_descr[object_index].value_active[i]) if (ad_descr[object_index].value_active[i])
apdu_len = encode_application_null(&apdu[0]); apdu_len = encode_application_null(&apdu[0]);
else { else {
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len],
ad_descr[object_index].priority_array[i]); ad_descr[object_index].priority_array[i]);
} }
} else { } else {
@@ -418,49 +386,41 @@ int Access_Door_Read_Property(
} }
break; break;
case PROP_RELINQUISH_DEFAULT: case PROP_RELINQUISH_DEFAULT:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0],
Access_Door_Relinquish_Default(rpdata->object_instance)); Access_Door_Relinquish_Default(rpdata->object_instance));
break; break;
case PROP_DOOR_STATUS: case PROP_DOOR_STATUS:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ad_descr[object_index].door_status);
ad_descr[object_index].door_status);
break; break;
case PROP_LOCK_STATUS: case PROP_LOCK_STATUS:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ad_descr[object_index].lock_status);
ad_descr[object_index].lock_status);
break; break;
case PROP_SECURED_STATUS: case PROP_SECURED_STATUS:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ad_descr[object_index].secured_status);
ad_descr[object_index].secured_status);
break; break;
case PROP_DOOR_PULSE_TIME: case PROP_DOOR_PULSE_TIME:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ad_descr[object_index].door_pulse_time);
ad_descr[object_index].door_pulse_time);
break; break;
case PROP_DOOR_EXTENDED_PULSE_TIME: case PROP_DOOR_EXTENDED_PULSE_TIME:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ad_descr[object_index].door_extended_pulse_time);
ad_descr[object_index].door_extended_pulse_time);
break; break;
case PROP_DOOR_UNLOCK_DELAY_TIME: case PROP_DOOR_UNLOCK_DELAY_TIME:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ad_descr[object_index].door_unlock_delay_time);
ad_descr[object_index].door_unlock_delay_time);
break; break;
case PROP_DOOR_OPEN_TOO_LONG_TIME: case PROP_DOOR_OPEN_TOO_LONG_TIME:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ad_descr[object_index].door_open_too_long_time);
ad_descr[object_index].door_open_too_long_time);
break; break;
case PROP_DOOR_ALARM_STATE: case PROP_DOOR_ALARM_STATE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ad_descr[object_index].door_alarm_state);
ad_descr[object_index].door_alarm_state);
break; break;
default: default:
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -480,8 +440,7 @@ int Access_Door_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Access_Door_Write_Property( bool Access_Door_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -489,8 +448,7 @@ bool Access_Door_Write_Property(
unsigned object_index = 0; unsigned object_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -513,9 +471,9 @@ bool Access_Door_Write_Property(
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
object. */ object. */
status = status = Access_Door_Present_Value_Set(wp_data->object_instance,
Access_Door_Present_Value_Set(wp_data->object_instance, value.type.Enumerated,
value.type.Enumerated, wp_data->priority); wp_data->priority);
if (wp_data->priority == 6) { if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
@@ -527,13 +485,12 @@ bool Access_Door_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, &wp_data->error_class,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_code);
if (status) { if (status) {
status = status = Access_Door_Present_Value_Relinquish(
Access_Door_Present_Value_Relinquish wp_data->object_instance, wp_data->priority);
(wp_data->object_instance, wp_data->priority);
if (!status) { if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -552,10 +509,9 @@ bool Access_Door_Write_Property(
break; break;
case PROP_DOOR_STATUS: case PROP_DOOR_STATUS:
if (Access_Door_Out_Of_Service(wp_data->object_instance)) { if (Access_Door_Out_Of_Service(wp_data->object_instance)) {
status = status = WPValidateArgType(
WPValidateArgType(&value, &value, BACNET_APPLICATION_TAG_ENUMERATED,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class, &wp_data->error_class, &wp_data->error_code);
&wp_data->error_code);
if (status) { if (status) {
ad_descr[object_index].door_status = value.type.Enumerated; ad_descr[object_index].door_status = value.type.Enumerated;
} }
@@ -566,10 +522,9 @@ bool Access_Door_Write_Property(
break; break;
case PROP_LOCK_STATUS: case PROP_LOCK_STATUS:
if (Access_Door_Out_Of_Service(wp_data->object_instance)) { if (Access_Door_Out_Of_Service(wp_data->object_instance)) {
status = status = WPValidateArgType(
WPValidateArgType(&value, &value, BACNET_APPLICATION_TAG_ENUMERATED,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class, &wp_data->error_class, &wp_data->error_code);
&wp_data->error_code);
if (status) { if (status) {
ad_descr[object_index].lock_status = value.type.Enumerated; ad_descr[object_index].lock_status = value.type.Enumerated;
} }
@@ -580,10 +535,9 @@ bool Access_Door_Write_Property(
break; break;
case PROP_DOOR_ALARM_STATE: case PROP_DOOR_ALARM_STATE:
if (Access_Door_Out_Of_Service(wp_data->object_instance)) { if (Access_Door_Out_Of_Service(wp_data->object_instance)) {
status = status = WPValidateArgType(
WPValidateArgType(&value, &value, BACNET_APPLICATION_TAG_ENUMERATED,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class, &wp_data->error_class, &wp_data->error_code);
&wp_data->error_code);
if (status) { if (status) {
ad_descr[object_index].door_alarm_state = ad_descr[object_index].door_alarm_state =
value.type.Enumerated; value.type.Enumerated;
@@ -618,16 +572,13 @@ bool Access_Door_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -638,8 +589,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAccessDoor( void testAccessDoor(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -668,8 +618,7 @@ void testAccessDoor(
} }
#ifdef TEST_ACCESS_DOOR #ifdef TEST_ACCESS_DOOR
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+49 -87
View File
@@ -60,20 +60,13 @@ static const int Properties_Required[] = {
PROP_ACCESS_EVENT_CREDENTIAL, PROP_ACCESS_EVENT_CREDENTIAL,
PROP_ACCESS_DOORS, PROP_ACCESS_DOORS,
PROP_PRIORITY_FOR_WRITING, PROP_PRIORITY_FOR_WRITING,
-1 -1};
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Access_Point_Property_Lists( void Access_Point_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -86,8 +79,7 @@ void Access_Point_Property_Lists(
return; return;
} }
void Access_Point_Init( void Access_Point_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -98,8 +90,7 @@ void Access_Point_Init(
ap_descr[i].event_state = EVENT_STATE_NORMAL; ap_descr[i].event_state = EVENT_STATE_NORMAL;
ap_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED; ap_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
ap_descr[i].out_of_service = false; ap_descr[i].out_of_service = false;
ap_descr[i].authentication_status = ap_descr[i].authentication_status = AUTHENTICATION_STATUS_NOT_READY;
AUTHENTICATION_STATUS_NOT_READY;
ap_descr[i].active_authentication_policy = 0; ap_descr[i].active_authentication_policy = 0;
ap_descr[i].number_of_authentication_policies = 0; ap_descr[i].number_of_authentication_policies = 0;
ap_descr[i].authorization_mode = AUTHORIZATION_MODE_AUTHORIZE; ap_descr[i].authorization_mode = AUTHORIZATION_MODE_AUTHORIZE;
@@ -118,8 +109,7 @@ void Access_Point_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Access_Point_Valid_Instance( bool Access_Point_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ACCESS_POINTS) if (object_instance < MAX_ACCESS_POINTS)
return true; return true;
@@ -129,8 +119,7 @@ bool Access_Point_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Access_Point_Count( unsigned Access_Point_Count(void)
void)
{ {
return MAX_ACCESS_POINTS; return MAX_ACCESS_POINTS;
} }
@@ -138,8 +127,7 @@ unsigned Access_Point_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Access_Point_Index_To_Instance( uint32_t Access_Point_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -147,8 +135,7 @@ uint32_t Access_Point_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Access_Point_Instance_To_Index( unsigned Access_Point_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ACCESS_POINTS; unsigned index = MAX_ACCESS_POINTS;
@@ -159,8 +146,7 @@ unsigned Access_Point_Instance_To_Index(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Access_Point_Object_Name( bool Access_Point_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -175,8 +161,7 @@ bool Access_Point_Object_Name(
return status; return status;
} }
bool Access_Point_Out_Of_Service( bool Access_Point_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned index = 0; unsigned index = 0;
bool oos_flag = false; bool oos_flag = false;
@@ -189,9 +174,7 @@ bool Access_Point_Out_Of_Service(
return oos_flag; return oos_flag;
} }
void Access_Point_Out_Of_Service_Set( void Access_Point_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
uint32_t instance,
bool oos_flag)
{ {
unsigned index = 0; unsigned index = 0;
@@ -202,8 +185,7 @@ void Access_Point_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Point_Read_Property( int Access_Point_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -222,9 +204,8 @@ int Access_Point_Read_Property(
object_index = Access_Point_Instance_To_Index(rpdata->object_instance); object_index = Access_Point_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ACCESS_POINT, &apdu[0], OBJECT_ACCESS_POINT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Access_Point_Object_Name(rpdata->object_instance, &char_string); Access_Point_Object_Name(rpdata->object_instance, &char_string);
@@ -245,69 +226,58 @@ int Access_Point_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ap_descr[object_index].event_state);
ap_descr[object_index].event_state);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ap_descr[object_index].reliability);
ap_descr[object_index].reliability);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
state = Access_Point_Out_Of_Service(rpdata->object_instance); state = Access_Point_Out_Of_Service(rpdata->object_instance);
apdu_len = encode_application_boolean(&apdu[0], state); apdu_len = encode_application_boolean(&apdu[0], state);
break; break;
case PROP_AUTHENTICATION_STATUS: case PROP_AUTHENTICATION_STATUS:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ap_descr[object_index].authentication_status);
ap_descr[object_index].authentication_status);
break; break;
case PROP_ACTIVE_AUTHENTICATION_POLICY: case PROP_ACTIVE_AUTHENTICATION_POLICY:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ap_descr[object_index].active_authentication_policy);
ap_descr[object_index].active_authentication_policy);
break; break;
case PROP_NUMBER_OF_AUTHENTICATION_POLICIES: case PROP_NUMBER_OF_AUTHENTICATION_POLICIES:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0],
ap_descr[object_index].number_of_authentication_policies); ap_descr[object_index].number_of_authentication_policies);
break; break;
case PROP_AUTHORIZATION_MODE: case PROP_AUTHORIZATION_MODE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ap_descr[object_index].authorization_mode);
ap_descr[object_index].authorization_mode);
break; break;
case PROP_ACCESS_EVENT: case PROP_ACCESS_EVENT:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ap_descr[object_index].access_event);
ap_descr[object_index].access_event);
break; break;
case PROP_ACCESS_EVENT_TAG: case PROP_ACCESS_EVENT_TAG:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ap_descr[object_index].access_event_tag);
ap_descr[object_index].access_event_tag);
break; break;
case PROP_ACCESS_EVENT_TIME: case PROP_ACCESS_EVENT_TIME:
apdu_len = apdu_len = bacapp_encode_timestamp(
bacapp_encode_timestamp(&apdu[0], &apdu[0], &ap_descr[object_index].access_event_time);
&ap_descr[object_index].access_event_time);
break; break;
case PROP_ACCESS_EVENT_CREDENTIAL: case PROP_ACCESS_EVENT_CREDENTIAL:
apdu_len = apdu_len = bacapp_encode_device_obj_ref(
bacapp_encode_device_obj_ref(&apdu[0], &apdu[0], &ap_descr[object_index].access_event_credential);
&ap_descr[object_index].access_event_credential);
break; break;
case PROP_ACCESS_DOORS: case PROP_ACCESS_DOORS:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ap_descr[object_index].num_doors);
ap_descr[object_index].num_doors);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < ap_descr[object_index].num_doors; i++) { for (i = 0; i < ap_descr[object_index].num_doors; i++) {
len = len = bacapp_encode_device_obj_ref(
bacapp_encode_device_obj_ref(&apdu[0], &apdu[0], &ap_descr[object_index].access_doors[i]);
&ap_descr[object_index].access_doors[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
@@ -319,10 +289,9 @@ int Access_Point_Read_Property(
} }
} else { } else {
if (rpdata->array_index <= ap_descr[object_index].num_doors) { if (rpdata->array_index <= ap_descr[object_index].num_doors) {
apdu_len = apdu_len = bacapp_encode_device_obj_ref(
bacapp_encode_device_obj_ref(&apdu[0], &apdu[0], &ap_descr[object_index]
&ap_descr[object_index].access_doors[rpdata-> .access_doors[rpdata->array_index - 1]);
array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -348,16 +317,14 @@ int Access_Point_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Access_Point_Write_Property( bool Access_Point_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -404,16 +371,13 @@ bool Access_Point_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -424,8 +388,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAccessPoint( void testAccessPoint(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -454,8 +417,7 @@ void testAccessPoint(
} }
#ifdef TEST_ACCESS_POINT #ifdef TEST_ACCESS_POINT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+50 -75
View File
@@ -42,8 +42,7 @@ static bool Access_Rights_Initialized = false;
static ACCESS_RIGHTS_DESCR ar_descr[MAX_ACCESS_RIGHTSS]; static ACCESS_RIGHTS_DESCR ar_descr[MAX_ACCESS_RIGHTSS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_GLOBAL_IDENTIFIER, PROP_GLOBAL_IDENTIFIER,
@@ -52,20 +51,13 @@ static const int Properties_Required[] = {
PROP_ENABLE, PROP_ENABLE,
PROP_NEGATIVE_ACCESS_RULES, PROP_NEGATIVE_ACCESS_RULES,
PROP_POSITIVE_ACCESS_RULES, PROP_POSITIVE_ACCESS_RULES,
-1 -1};
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Access_Rights_Property_Lists( void Access_Rights_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -78,8 +70,7 @@ void Access_Rights_Property_Lists(
return; return;
} }
void Access_Rights_Init( void Access_Rights_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -87,7 +78,8 @@ void Access_Rights_Init(
Access_Rights_Initialized = true; Access_Rights_Initialized = true;
for (i = 0; i < MAX_ACCESS_RIGHTSS; i++) { for (i = 0; i < MAX_ACCESS_RIGHTSS; i++) {
ar_descr[i].global_identifier = 0; /* set to some meaningful value */ ar_descr[i].global_identifier =
0; /* set to some meaningful value */
ar_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED; ar_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
ar_descr[i].enable = false; ar_descr[i].enable = false;
ar_descr[i].negative_access_rules_count = 0; ar_descr[i].negative_access_rules_count = 0;
@@ -102,8 +94,7 @@ void Access_Rights_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Access_Rights_Valid_Instance( bool Access_Rights_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ACCESS_RIGHTSS) if (object_instance < MAX_ACCESS_RIGHTSS)
return true; return true;
@@ -113,8 +104,7 @@ bool Access_Rights_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Access_Rights_Count( unsigned Access_Rights_Count(void)
void)
{ {
return MAX_ACCESS_RIGHTSS; return MAX_ACCESS_RIGHTSS;
} }
@@ -122,8 +112,7 @@ unsigned Access_Rights_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Access_Rights_Index_To_Instance( uint32_t Access_Rights_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -131,8 +120,7 @@ uint32_t Access_Rights_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Access_Rights_Instance_To_Index( unsigned Access_Rights_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ACCESS_RIGHTSS; unsigned index = MAX_ACCESS_RIGHTSS;
@@ -143,8 +131,7 @@ unsigned Access_Rights_Instance_To_Index(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Access_Rights_Object_Name( bool Access_Rights_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -160,8 +147,7 @@ bool Access_Rights_Object_Name(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Rights_Read_Property( int Access_Rights_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -179,9 +165,8 @@ int Access_Rights_Read_Property(
object_index = Access_Rights_Instance_To_Index(rpdata->object_instance); object_index = Access_Rights_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ACCESS_RIGHTS, &apdu[0], OBJECT_ACCESS_RIGHTS, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Access_Rights_Object_Name(rpdata->object_instance, &char_string); Access_Rights_Object_Name(rpdata->object_instance, &char_string);
@@ -193,9 +178,8 @@ int Access_Rights_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ACCESS_RIGHTS); encode_application_enumerated(&apdu[0], OBJECT_ACCESS_RIGHTS);
break; break;
case PROP_GLOBAL_IDENTIFIER: case PROP_GLOBAL_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], ar_descr[object_index].global_identifier);
ar_descr[object_index].global_identifier);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -206,26 +190,24 @@ int Access_Rights_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], ar_descr[object_index].reliability);
ar_descr[object_index].reliability);
break; break;
case PROP_ENABLE: case PROP_ENABLE:
apdu_len = apdu_len = encode_application_boolean(
encode_application_boolean(&apdu[0], &apdu[0], ar_descr[object_index].enable);
ar_descr[object_index].enable);
break; break;
case PROP_NEGATIVE_ACCESS_RULES: case PROP_NEGATIVE_ACCESS_RULES:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0],
ar_descr[object_index].negative_access_rules_count); ar_descr[object_index].negative_access_rules_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; for (i = 0;
i < ar_descr[object_index].negative_access_rules_count; i < ar_descr[object_index].negative_access_rules_count;
i++) { i++) {
len = len = bacapp_encode_access_rule(
bacapp_encode_access_rule(&apdu[0], &apdu[0],
&ar_descr[object_index].negative_access_rules[i]); &ar_descr[object_index].negative_access_rules[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
@@ -239,10 +221,10 @@ int Access_Rights_Read_Property(
} else { } else {
if (rpdata->array_index <= if (rpdata->array_index <=
ar_descr[object_index].negative_access_rules_count) { ar_descr[object_index].negative_access_rules_count) {
apdu_len = apdu_len = bacapp_encode_access_rule(
bacapp_encode_access_rule(&apdu[0], &apdu[0],
&ar_descr[object_index]. &ar_descr[object_index]
negative_access_rules[rpdata->array_index - 1]); .negative_access_rules[rpdata->array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -252,15 +234,15 @@ int Access_Rights_Read_Property(
break; break;
case PROP_POSITIVE_ACCESS_RULES: case PROP_POSITIVE_ACCESS_RULES:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0],
ar_descr[object_index].positive_access_rules_count); ar_descr[object_index].positive_access_rules_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; for (i = 0;
i < ar_descr[object_index].positive_access_rules_count; i < ar_descr[object_index].positive_access_rules_count;
i++) { i++) {
len = len = bacapp_encode_access_rule(
bacapp_encode_access_rule(&apdu[0], &apdu[0],
&ar_descr[object_index].positive_access_rules[i]); &ar_descr[object_index].positive_access_rules[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
@@ -274,10 +256,10 @@ int Access_Rights_Read_Property(
} else { } else {
if (rpdata->array_index <= if (rpdata->array_index <=
ar_descr[object_index].positive_access_rules_count) { ar_descr[object_index].positive_access_rules_count) {
apdu_len = apdu_len = bacapp_encode_access_rule(
bacapp_encode_access_rule(&apdu[0], &apdu[0],
&ar_descr[object_index]. &ar_descr[object_index]
positive_access_rules[rpdata->array_index - 1]); .positive_access_rules[rpdata->array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -293,9 +275,9 @@ int Access_Rights_Read_Property(
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && if ((apdu_len >= 0) &&
(rpdata->object_property != PROP_NEGATIVE_ACCESS_RULES) (rpdata->object_property != PROP_NEGATIVE_ACCESS_RULES) &&
&& (rpdata->object_property != PROP_POSITIVE_ACCESS_RULES) (rpdata->object_property != PROP_POSITIVE_ACCESS_RULES) &&
&& (rpdata->array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -305,8 +287,7 @@ int Access_Rights_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Access_Rights_Write_Property( bool Access_Rights_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -314,8 +295,7 @@ bool Access_Rights_Write_Property(
unsigned object_index = 0; unsigned object_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -325,9 +305,9 @@ bool Access_Rights_Write_Property(
return false; return false;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((wp_data->object_property != PROP_NEGATIVE_ACCESS_RULES) if ((wp_data->object_property != PROP_NEGATIVE_ACCESS_RULES) &&
&& (wp_data->object_property != PROP_POSITIVE_ACCESS_RULES) (wp_data->object_property != PROP_POSITIVE_ACCESS_RULES) &&
&& (wp_data->array_index != BACNET_ARRAY_ALL)) { (wp_data->array_index != BACNET_ARRAY_ALL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false; return false;
@@ -363,16 +343,13 @@ bool Access_Rights_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -383,8 +360,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAccessRights( void testAccessRights(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -413,8 +389,7 @@ void testAccessRights(
} }
#ifdef TEST_ACCESS_RIGHTS #ifdef TEST_ACCESS_RIGHTS
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+32 -64
View File
@@ -43,28 +43,15 @@ static ACCESS_USER_DESCR au_descr[MAX_ACCESS_USERS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_OBJECT_NAME, PROP_GLOBAL_IDENTIFIER, PROP_STATUS_FLAGS, PROP_RELIABILITY,
PROP_OBJECT_TYPE, PROP_USER_TYPE, PROP_CREDENTIALS, -1};
PROP_GLOBAL_IDENTIFIER,
PROP_STATUS_FLAGS,
PROP_RELIABILITY,
PROP_USER_TYPE,
PROP_CREDENTIALS,
-1
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Access_User_Property_Lists( void Access_User_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -77,8 +64,7 @@ void Access_User_Property_Lists(
return; return;
} }
void Access_User_Init( void Access_User_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -86,7 +72,8 @@ void Access_User_Init(
Access_User_Initialized = true; Access_User_Initialized = true;
for (i = 0; i < MAX_ACCESS_USERS; i++) { for (i = 0; i < MAX_ACCESS_USERS; i++) {
au_descr[i].global_identifier = 0; /* set to some meaningful value */ au_descr[i].global_identifier =
0; /* set to some meaningful value */
au_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED; au_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
au_descr[i].user_type = ACCESS_USER_TYPE_PERSON; au_descr[i].user_type = ACCESS_USER_TYPE_PERSON;
au_descr[i].credentials_count = 0; au_descr[i].credentials_count = 0;
@@ -100,8 +87,7 @@ void Access_User_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Access_User_Valid_Instance( bool Access_User_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ACCESS_USERS) if (object_instance < MAX_ACCESS_USERS)
return true; return true;
@@ -111,8 +97,7 @@ bool Access_User_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Access_User_Count( unsigned Access_User_Count(void)
void)
{ {
return MAX_ACCESS_USERS; return MAX_ACCESS_USERS;
} }
@@ -120,8 +105,7 @@ unsigned Access_User_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Access_User_Index_To_Instance( uint32_t Access_User_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -129,8 +113,7 @@ uint32_t Access_User_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Access_User_Instance_To_Index( unsigned Access_User_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ACCESS_USERS; unsigned index = MAX_ACCESS_USERS;
@@ -141,16 +124,14 @@ unsigned Access_User_Instance_To_Index(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Access_User_Object_Name( bool Access_User_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
bool status = false; bool status = false;
if (object_instance < MAX_ACCESS_USERS) { if (object_instance < MAX_ACCESS_USERS) {
sprintf(text_string, "ACCESS USER %lu", sprintf(text_string, "ACCESS USER %lu", (unsigned long)object_instance);
(unsigned long) object_instance);
status = characterstring_init_ansi(object_name, text_string); status = characterstring_init_ansi(object_name, text_string);
} }
@@ -158,8 +139,7 @@ bool Access_User_Object_Name(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_User_Read_Property( int Access_User_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -177,9 +157,8 @@ int Access_User_Read_Property(
object_index = Access_User_Instance_To_Index(rpdata->object_instance); object_index = Access_User_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ACCESS_USER, &apdu[0], OBJECT_ACCESS_USER, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Access_User_Object_Name(rpdata->object_instance, &char_string); Access_User_Object_Name(rpdata->object_instance, &char_string);
@@ -191,9 +170,8 @@ int Access_User_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ACCESS_USER); encode_application_enumerated(&apdu[0], OBJECT_ACCESS_USER);
break; break;
case PROP_GLOBAL_IDENTIFIER: case PROP_GLOBAL_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], au_descr[object_index].global_identifier);
au_descr[object_index].global_identifier);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -204,20 +182,17 @@ int Access_User_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], au_descr[object_index].reliability);
au_descr[object_index].reliability);
break; break;
case PROP_USER_TYPE: case PROP_USER_TYPE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], au_descr[object_index].user_type);
au_descr[object_index].user_type);
break; break;
case PROP_CREDENTIALS: case PROP_CREDENTIALS:
for (i = 0; i < au_descr[object_index].credentials_count; i++) { for (i = 0; i < au_descr[object_index].credentials_count; i++) {
len = len = bacapp_encode_device_obj_ref(
bacapp_encode_device_obj_ref(&apdu[0], &apdu[0], &au_descr[object_index].credentials[i]);
&au_descr[object_index].credentials[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
@@ -245,8 +220,7 @@ int Access_User_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Access_User_Write_Property( bool Access_User_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -254,8 +228,7 @@ bool Access_User_Write_Property(
unsigned object_index = 0; unsigned object_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -301,16 +274,13 @@ bool Access_User_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -321,8 +291,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAccessUser( void testAccessUser(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -351,8 +320,7 @@ void testAccessUser(
} }
#ifdef TEST_ACCESS_USER #ifdef TEST_ACCESS_USER
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+42 -82
View File
@@ -43,31 +43,16 @@ static ACCESS_ZONE_DESCR az_descr[MAX_ACCESS_ZONES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_OBJECT_NAME, PROP_GLOBAL_IDENTIFIER, PROP_OCCUPANCY_STATE, PROP_STATUS_FLAGS,
PROP_OBJECT_TYPE, PROP_EVENT_STATE, PROP_RELIABILITY, PROP_OUT_OF_SERVICE,
PROP_GLOBAL_IDENTIFIER, PROP_ENTRY_POINTS, PROP_EXIT_POINTS, -1};
PROP_OCCUPANCY_STATE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_RELIABILITY,
PROP_OUT_OF_SERVICE,
PROP_ENTRY_POINTS,
PROP_EXIT_POINTS,
-1
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Access_Zone_Property_Lists( void Access_Zone_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -80,8 +65,7 @@ void Access_Zone_Property_Lists(
return; return;
} }
void Access_Zone_Init( void Access_Zone_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -89,7 +73,8 @@ void Access_Zone_Init(
Access_Zone_Initialized = true; Access_Zone_Initialized = true;
for (i = 0; i < MAX_ACCESS_ZONES; i++) { for (i = 0; i < MAX_ACCESS_ZONES; i++) {
az_descr[i].global_identifier = 0; /* set to some meaningful value */ az_descr[i].global_identifier =
0; /* set to some meaningful value */
az_descr[i].occupancy_state = ACCESS_ZONE_OCCUPANCY_STATE_DISABLED; az_descr[i].occupancy_state = ACCESS_ZONE_OCCUPANCY_STATE_DISABLED;
az_descr[i].event_state = EVENT_STATE_NORMAL; az_descr[i].event_state = EVENT_STATE_NORMAL;
az_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED; az_descr[i].reliability = RELIABILITY_NO_FAULT_DETECTED;
@@ -106,8 +91,7 @@ void Access_Zone_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Access_Zone_Valid_Instance( bool Access_Zone_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ACCESS_ZONES) if (object_instance < MAX_ACCESS_ZONES)
return true; return true;
@@ -117,8 +101,7 @@ bool Access_Zone_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Access_Zone_Count( unsigned Access_Zone_Count(void)
void)
{ {
return MAX_ACCESS_ZONES; return MAX_ACCESS_ZONES;
} }
@@ -126,8 +109,7 @@ unsigned Access_Zone_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Access_Zone_Index_To_Instance( uint32_t Access_Zone_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -135,8 +117,7 @@ uint32_t Access_Zone_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Access_Zone_Instance_To_Index( unsigned Access_Zone_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ACCESS_ZONES; unsigned index = MAX_ACCESS_ZONES;
@@ -147,24 +128,21 @@ unsigned Access_Zone_Instance_To_Index(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Access_Zone_Object_Name( bool Access_Zone_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
bool status = false; bool status = false;
if (object_instance < MAX_ACCESS_ZONES) { if (object_instance < MAX_ACCESS_ZONES) {
sprintf(text_string, "ACCESS ZONE %lu", sprintf(text_string, "ACCESS ZONE %lu", (unsigned long)object_instance);
(unsigned long) object_instance);
status = characterstring_init_ansi(object_name, text_string); status = characterstring_init_ansi(object_name, text_string);
} }
return status; return status;
} }
bool Access_Zone_Out_Of_Service( bool Access_Zone_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned index = 0; unsigned index = 0;
bool oos_flag = false; bool oos_flag = false;
@@ -177,9 +155,7 @@ bool Access_Zone_Out_Of_Service(
return oos_flag; return oos_flag;
} }
void Access_Zone_Out_Of_Service_Set( void Access_Zone_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
uint32_t instance,
bool oos_flag)
{ {
unsigned index = 0; unsigned index = 0;
@@ -190,8 +166,7 @@ void Access_Zone_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Access_Zone_Read_Property( int Access_Zone_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -210,9 +185,8 @@ int Access_Zone_Read_Property(
object_index = Access_Zone_Instance_To_Index(rpdata->object_instance); object_index = Access_Zone_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ACCESS_ZONE, &apdu[0], OBJECT_ACCESS_ZONE, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Access_Zone_Object_Name(rpdata->object_instance, &char_string); Access_Zone_Object_Name(rpdata->object_instance, &char_string);
@@ -224,14 +198,12 @@ int Access_Zone_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_ACCESS_ZONE); encode_application_enumerated(&apdu[0], OBJECT_ACCESS_ZONE);
break; break;
case PROP_GLOBAL_IDENTIFIER: case PROP_GLOBAL_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], az_descr[object_index].global_identifier);
az_descr[object_index].global_identifier);
break; break;
case PROP_OCCUPANCY_STATE: case PROP_OCCUPANCY_STATE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], az_descr[object_index].occupancy_state);
az_descr[object_index].occupancy_state);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -243,14 +215,12 @@ int Access_Zone_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], az_descr[object_index].event_state);
az_descr[object_index].event_state);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], az_descr[object_index].reliability);
az_descr[object_index].reliability);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
state = Access_Zone_Out_Of_Service(rpdata->object_instance); state = Access_Zone_Out_Of_Service(rpdata->object_instance);
@@ -258,9 +228,8 @@ int Access_Zone_Read_Property(
break; break;
case PROP_ENTRY_POINTS: case PROP_ENTRY_POINTS:
for (i = 0; i < az_descr[object_index].entry_points_count; i++) { for (i = 0; i < az_descr[object_index].entry_points_count; i++) {
len = len = bacapp_encode_device_obj_ref(
bacapp_encode_device_obj_ref(&apdu[0], &apdu[0], &az_descr[object_index].entry_points[i]);
&az_descr[object_index].entry_points[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
@@ -273,9 +242,8 @@ int Access_Zone_Read_Property(
break; break;
case PROP_EXIT_POINTS: case PROP_EXIT_POINTS:
for (i = 0; i < az_descr[object_index].exit_points_count; i++) { for (i = 0; i < az_descr[object_index].exit_points_count; i++) {
len = len = bacapp_encode_device_obj_ref(
bacapp_encode_device_obj_ref(&apdu[0], &apdu[0], &az_descr[object_index].exit_points[i]);
&az_descr[object_index].exit_points[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
else { else {
@@ -303,8 +271,7 @@ int Access_Zone_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Access_Zone_Write_Property( bool Access_Zone_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -312,8 +279,7 @@ bool Access_Zone_Write_Property(
unsigned object_index = 0; unsigned object_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -341,10 +307,9 @@ bool Access_Zone_Write_Property(
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
if (Access_Zone_Out_Of_Service(wp_data->object_instance)) { if (Access_Zone_Out_Of_Service(wp_data->object_instance)) {
status = status = WPValidateArgType(
WPValidateArgType(&value, &value, BACNET_APPLICATION_TAG_ENUMERATED,
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class, &wp_data->error_class, &wp_data->error_code);
&wp_data->error_code);
if (status) { if (status) {
az_descr[object_index].reliability = value.type.Enumerated; az_descr[object_index].reliability = value.type.Enumerated;
} }
@@ -374,16 +339,13 @@ bool Access_Zone_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -394,8 +356,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAccessZone( void testAccessZone(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -424,8 +385,7 @@ void testAccessZone(
} }
#ifdef TEST_ACCESS_ZONE #ifdef TEST_ACCESS_ZONE
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+214 -255
View File
@@ -41,29 +41,19 @@
#include "timestamp.h" #include "timestamp.h"
#include "ai.h" #include "ai.h"
#ifndef MAX_ANALOG_INPUTS #ifndef MAX_ANALOG_INPUTS
#define MAX_ANALOG_INPUTS 4 #define MAX_ANALOG_INPUTS 4
#endif #endif
ANALOG_INPUT_DESCR AI_Descr[MAX_ANALOG_INPUTS]; ANALOG_INPUT_DESCR AI_Descr[MAX_ANALOG_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_OBJECT_NAME, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OBJECT_TYPE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1};
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {PROP_DESCRIPTION,
PROP_DESCRIPTION,
PROP_RELIABILITY, PROP_RELIABILITY,
PROP_COV_INCREMENT, PROP_COV_INCREMENT,
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -78,19 +68,11 @@ static const int Properties_Optional[] = {
PROP_NOTIFY_TYPE, PROP_NOTIFY_TYPE,
PROP_EVENT_TIME_STAMPS, PROP_EVENT_TIME_STAMPS,
#endif #endif
-1 -1};
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {9997, 9998, 9999, -1};
9997,
9998,
9999,
-1
};
void Analog_Input_Property_Lists( void Analog_Input_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -103,9 +85,7 @@ void Analog_Input_Property_Lists(
return; return;
} }
void Analog_Input_Init(void)
void Analog_Input_Init(
void)
{ {
unsigned i; unsigned i;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -146,8 +126,7 @@ void Analog_Input_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Input_Valid_Instance( bool Analog_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned int index; unsigned int index;
@@ -160,8 +139,7 @@ bool Analog_Input_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Input_Count( unsigned Analog_Input_Count(void)
void)
{ {
return MAX_ANALOG_INPUTS; return MAX_ANALOG_INPUTS;
} }
@@ -169,8 +147,7 @@ unsigned Analog_Input_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Input_Index_To_Instance( uint32_t Analog_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -178,8 +155,7 @@ uint32_t Analog_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Input_Instance_To_Index( unsigned Analog_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_INPUTS; unsigned index = MAX_ANALOG_INPUTS;
@@ -189,8 +165,7 @@ unsigned Analog_Input_Instance_To_Index(
return index; return index;
} }
float Analog_Input_Present_Value( float Analog_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0.0; float value = 0.0;
unsigned int index; unsigned int index;
@@ -203,8 +178,7 @@ float Analog_Input_Present_Value(
return value; return value;
} }
static void Analog_Input_COV_Detect(unsigned int index, static void Analog_Input_COV_Detect(unsigned int index, float value)
float value)
{ {
float prior_value = 0.0; float prior_value = 0.0;
float cov_increment = 0.0; float cov_increment = 0.0;
@@ -225,9 +199,7 @@ static void Analog_Input_COV_Detect(unsigned int index,
} }
} }
void Analog_Input_Present_Value_Set( void Analog_Input_Present_Value_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
unsigned int index = 0; unsigned int index = 0;
@@ -238,8 +210,7 @@ void Analog_Input_Present_Value_Set(
} }
} }
bool Analog_Input_Object_Name( bool Analog_Input_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -255,8 +226,7 @@ bool Analog_Input_Object_Name(
return status; return status;
} }
bool Analog_Input_Change_Of_Value( bool Analog_Input_Change_Of_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
bool changed = false; bool changed = false;
@@ -269,8 +239,7 @@ bool Analog_Input_Change_Of_Value(
return changed; return changed;
} }
void Analog_Input_Change_Of_Value_Clear( void Analog_Input_Change_Of_Value_Clear(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
@@ -288,8 +257,7 @@ void Analog_Input_Change_Of_Value_Clear(
* *
* @return true if the value list is encoded * @return true if the value list is encoded
*/ */
bool Analog_Input_Encode_Value_List( bool Analog_Input_Encode_Value_List(uint32_t object_instance,
uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list) BACNET_PROPERTY_VALUE *value_list)
{ {
bool status = false; bool status = false;
@@ -313,8 +281,8 @@ bool Analog_Input_Encode_Value_List(
bitstring_init(&value_list->value.type.Bit_String); bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_IN_ALARM, false); STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT,
STATUS_FLAG_FAULT, false); false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OVERRIDDEN, false); STATUS_FLAG_OVERRIDDEN, false);
if (Analog_Input_Out_Of_Service(object_instance)) { if (Analog_Input_Out_Of_Service(object_instance)) {
@@ -333,8 +301,7 @@ bool Analog_Input_Encode_Value_List(
return status; return status;
} }
float Analog_Input_COV_Increment( float Analog_Input_COV_Increment(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
float value = 0; float value = 0;
@@ -347,9 +314,7 @@ float Analog_Input_COV_Increment(
return value; return value;
} }
void Analog_Input_COV_Increment_Set( void Analog_Input_COV_Increment_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -360,8 +325,7 @@ void Analog_Input_COV_Increment_Set(
} }
} }
bool Analog_Input_Out_Of_Service( bool Analog_Input_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
bool value = false; bool value = false;
@@ -374,22 +338,20 @@ bool Analog_Input_Out_Of_Service(
return value; return value;
} }
void Analog_Input_Out_Of_Service_Set( void Analog_Input_Out_Of_Service_Set(uint32_t object_instance, bool value)
uint32_t object_instance,
bool value)
{ {
unsigned index = 0; unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance); index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
/* BACnet Testing Observed Incident oi00104 /* BACnet Testing Observed Incident oi00104
The Changed flag was not being set when a client wrote to the Out-of-Service bit. The Changed flag was not being set when a client wrote to the
Revealed by BACnet Test Client v1.8.16 ( www.bac-test.com/bacnet-test-client-download ) Out-of-Service bit. Revealed by BACnet Test Client v1.8.16 (
BC 135.1: 8.2.1-A www.bac-test.com/bacnet-test-client-download ) BC 135.1: 8.2.1-A BC
BC 135.1: 8.2.2-A 135.1: 8.2.2-A Any discussions can be directed to edward@bac-test.com
Any discussions can be directed to edward@bac-test.com Please feel free to remove this comment when my changes accepted after
Please feel free to remove this comment when my changes accepted after suitable time for suitable time for review by all interested parties. Say 6 months ->
review by all interested parties. Say 6 months -> September 2016 */ September 2016 */
if (AI_Descr[index].Out_Of_Service != value) { if (AI_Descr[index].Out_Of_Service != value) {
AI_Descr[index].Changed = true; AI_Descr[index].Changed = true;
} }
@@ -399,8 +361,7 @@ void Analog_Input_Out_Of_Service_Set(
/* return apdu length, or BACNET_STATUS_ERROR on error */ /* return apdu length, or BACNET_STATUS_ERROR on error */
/* assumption - object already exists */ /* assumption - object already exists */
int Analog_Input_Read_Property( int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -427,9 +388,8 @@ int Analog_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch ((int)rpdata->object_property) { switch ((int)rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_INPUT, &apdu[0], OBJECT_ANALOG_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -445,9 +405,8 @@ int Analog_Input_Read_Property(
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Analog_Input_Present_Value(rpdata->object_instance));
Analog_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -469,8 +428,7 @@ int Analog_Input_Read_Property(
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], CurrentAI->Event_State);
CurrentAI->Event_State);
#else #else
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
@@ -479,14 +437,12 @@ int Analog_Input_Read_Property(
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], CurrentAI->Reliability);
CurrentAI->Reliability);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
apdu_len = apdu_len =
encode_application_boolean(&apdu[0], encode_application_boolean(&apdu[0], CurrentAI->Out_Of_Service);
CurrentAI->Out_Of_Service);
break; break;
case PROP_UNITS: case PROP_UNITS:
@@ -495,8 +451,8 @@ int Analog_Input_Read_Property(
break; break;
case PROP_COV_INCREMENT: case PROP_COV_INCREMENT:
apdu_len = encode_application_real(&apdu[0], apdu_len =
CurrentAI->COV_Increment); encode_application_real(&apdu[0], CurrentAI->COV_Increment);
break; break;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -506,14 +462,12 @@ int Analog_Input_Read_Property(
break; break;
case PROP_NOTIFICATION_CLASS: case PROP_NOTIFICATION_CLASS:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], CurrentAI->Notification_Class);
CurrentAI->Notification_Class);
break; break;
case PROP_HIGH_LIMIT: case PROP_HIGH_LIMIT:
apdu_len = apdu_len = encode_application_real(&apdu[0], CurrentAI->High_Limit);
encode_application_real(&apdu[0], CurrentAI->High_Limit);
break; break;
case PROP_LOW_LIMIT: case PROP_LOW_LIMIT:
@@ -527,70 +481,73 @@ int Analog_Input_Read_Property(
case PROP_LIMIT_ENABLE: case PROP_LIMIT_ENABLE:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, 0, bitstring_set_bit(&bit_string, 0,
(CurrentAI-> (CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE)
Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true : false); ? true
bitstring_set_bit(&bit_string, 1, : false);
(CurrentAI-> bitstring_set_bit(
Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false); &bit_string, 1,
(CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true
: false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_ENABLE: case PROP_EVENT_ENABLE:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(
(CurrentAI-> &bit_string, TRANSITION_TO_OFFNORMAL,
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); (CurrentAI->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
: false);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
(CurrentAI-> (CurrentAI->Event_Enable & EVENT_ENABLE_TO_FAULT)
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false); ? true
: false);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
(CurrentAI-> (CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL)
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); ? true
: false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_ACKED_TRANSITIONS: case PROP_ACKED_TRANSITIONS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. &bit_string, TRANSITION_TO_OFFNORMAL,
bIsAcked); CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, bitstring_set_bit(
&bit_string, TRANSITION_TO_FAULT,
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, bitstring_set_bit(
&bit_string, TRANSITION_TO_NORMAL,
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_NOTIFY_TYPE: case PROP_NOTIFY_TYPE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], CurrentAI->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
CurrentAI->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
break; break;
case PROP_EVENT_TIME_STAMPS: case PROP_EVENT_TIME_STAMPS:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
if (rpdata->array_index == 0) if (rpdata->array_index == 0)
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], MAX_BACNET_EVENT_TRANSITION);
MAX_BACNET_EVENT_TRANSITION);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. */ /* into one packet. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) { for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) {
len = len = encode_opening_tag(&apdu[apdu_len],
encode_opening_tag(&apdu[apdu_len],
TIME_STAMP_DATETIME); TIME_STAMP_DATETIME);
len += len += encode_application_date(
encode_application_date(&apdu[apdu_len + len], &apdu[apdu_len + len],
&CurrentAI->Event_Time_Stamps[i].date); &CurrentAI->Event_Time_Stamps[i].date);
len += len += encode_application_time(
encode_application_time(&apdu[apdu_len + len], &apdu[apdu_len + len],
&CurrentAI->Event_Time_Stamps[i].time); &CurrentAI->Event_Time_Stamps[i].time);
len += len += encode_closing_tag(&apdu[apdu_len + len],
encode_closing_tag(&apdu[apdu_len + len],
TIME_STAMP_DATETIME); TIME_STAMP_DATETIME);
/* add it if we have room */ /* add it if we have room */
@@ -606,11 +563,11 @@ int Analog_Input_Read_Property(
} else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) {
apdu_len = apdu_len =
encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
apdu_len += apdu_len += encode_application_date(
encode_application_date(&apdu[apdu_len], &apdu[apdu_len],
&CurrentAI->Event_Time_Stamps[rpdata->array_index].date); &CurrentAI->Event_Time_Stamps[rpdata->array_index].date);
apdu_len += apdu_len += encode_application_time(
encode_application_time(&apdu[apdu_len], &apdu[apdu_len],
&CurrentAI->Event_Time_Stamps[rpdata->array_index].time); &CurrentAI->Event_Time_Stamps[rpdata->array_index].time);
apdu_len += apdu_len +=
encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
@@ -626,11 +583,13 @@ int Analog_Input_Read_Property(
apdu_len = encode_application_real(&apdu[0], 90.510F); apdu_len = encode_application_real(&apdu[0], 90.510F);
break; break;
case 9998: case 9998:
/* test case for unsigned encoding-decoding unsigned value correctly */ /* test case for unsigned encoding-decoding unsigned value correctly
*/
apdu_len = encode_application_unsigned(&apdu[0], 90); apdu_len = encode_application_unsigned(&apdu[0], 90);
break; break;
case 9999: case 9999:
/* test case for signed encoding-decoding negative value correctly */ /* test case for signed encoding-decoding negative value correctly
*/
apdu_len = encode_application_signed(&apdu[0], -200); apdu_len = encode_application_signed(&apdu[0], -200);
break; break;
default: default:
@@ -640,8 +599,9 @@ int Analog_Input_Read_Property(
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->object_property != PROP_EVENT_TIME_STAMPS) if ((apdu_len >= 0) &&
&& (rpdata->array_index != BACNET_ARRAY_ALL)) { (rpdata->object_property != PROP_EVENT_TIME_STAMPS) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -651,8 +611,7 @@ int Analog_Input_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Input_Write_Property( bool Analog_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -661,8 +620,7 @@ bool Analog_Input_Write_Property(
ANALOG_INPUT_DESCR *CurrentAI; ANALOG_INPUT_DESCR *CurrentAI;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -708,8 +666,7 @@ bool Analog_Input_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
Analog_Input_Out_Of_Service_Set( Analog_Input_Out_Of_Service_Set(wp_data->object_instance,
wp_data->object_instance,
value.type.Boolean); value.type.Boolean);
} }
break; break;
@@ -729,8 +686,7 @@ bool Analog_Input_Write_Property(
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if (value.type.Real >= 0.0) { if (value.type.Real >= 0.0) {
Analog_Input_COV_Increment_Set( Analog_Input_COV_Increment_Set(wp_data->object_instance,
wp_data->object_instance,
value.type.Real); value.type.Real);
} else { } else {
status = false; status = false;
@@ -872,9 +828,7 @@ bool Analog_Input_Write_Property(
return status; return status;
} }
void Analog_Input_Intrinsic_Reporting(uint32_t object_instance)
void Analog_Input_Intrinsic_Reporting(
uint32_t object_instance)
{ {
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
BACNET_EVENT_NOTIFICATION_DATA event_data; BACNET_EVENT_NOTIFICATION_DATA event_data;
@@ -887,7 +841,6 @@ void Analog_Input_Intrinsic_Reporting(
float PresentVal = 0.0f; float PresentVal = 0.0f;
bool SendNotify = false; bool SendNotify = false;
object_index = Analog_Input_Instance_To_Index(object_instance); object_index = Analog_Input_Instance_To_Index(object_instance);
if (object_index < MAX_ANALOG_INPUTS) if (object_index < MAX_ANALOG_INPUTS)
CurrentAI = &AI_Descr[object_index]; CurrentAI = &AI_Descr[object_index];
@@ -898,7 +851,6 @@ void Analog_Input_Intrinsic_Reporting(
if (!CurrentAI->Limit_Enable) if (!CurrentAI->Limit_Enable)
return; /* limits are not configured */ return; /* limits are not configured */
if (CurrentAI->Ack_notify_data.bSendAckNotify) { if (CurrentAI->Ack_notify_data.bSendAckNotify) {
/* clean bSendAckNotify flag */ /* clean bSendAckNotify flag */
CurrentAI->Ack_notify_data.bSendAckNotify = false; CurrentAI->Ack_notify_data.bSendAckNotify = false;
@@ -924,10 +876,12 @@ void Analog_Input_Intrinsic_Reporting(
switch (CurrentAI->Event_State) { switch (CurrentAI->Event_State) {
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
/* A TO-OFFNORMAL event is generated under these conditions: /* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the High_Limit for a minimum (a) the Present_Value must exceed the High_Limit for a
period of time, specified in the Time_Delay property, and minimum period of time, specified in the Time_Delay property,
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and and (b) the HighLimitEnable flag must be set in the
(c) the TO-OFFNORMAL flag must be set in the Event_Enable property. */ Limit_Enable property, and
(c) the TO-OFFNORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal > CurrentAI->High_Limit) && if ((PresentVal > CurrentAI->High_Limit) &&
((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) && EVENT_HIGH_LIMIT_ENABLE) &&
@@ -941,10 +895,12 @@ void Analog_Input_Intrinsic_Reporting(
} }
/* A TO-OFFNORMAL event is generated under these conditions: /* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband (a) the Present_Value must exceed the Low_Limit plus the
for a minimum period of time, specified in the Time_Delay property, and Deadband for a minimum period of time, specified in the
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and Time_Delay property, and (b) the LowLimitEnable flag must be
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ set in the Limit_Enable property, and
(c) the TO-NORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal < CurrentAI->Low_Limit) && if ((PresentVal < CurrentAI->Low_Limit) &&
((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) && EVENT_LOW_LIMIT_ENABLE) &&
@@ -961,14 +917,17 @@ void Analog_Input_Intrinsic_Reporting(
break; break;
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
/* Once exceeded, the Present_Value must fall below the High_Limit minus /* Once exceeded, the Present_Value must fall below the
the Deadband before a TO-NORMAL event is generated under these conditions: High_Limit minus the Deadband before a TO-NORMAL event is
(a) the Present_Value must fall below the High_Limit minus the Deadband generated under these conditions: (a) the Present_Value must
for a minimum period of time, specified in the Time_Delay property, and fall below the High_Limit minus the Deadband for a minimum
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and period of time, specified in the Time_Delay property, and (b)
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ the HighLimitEnable flag must be set in the Limit_Enable
if ((PresentVal < CurrentAI->High_Limit - CurrentAI->Deadband) property, and (c) the TO-NORMAL flag must be set in the
&& ((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == Event_Enable property. */
if ((PresentVal <
CurrentAI->High_Limit - CurrentAI->Deadband) &&
((CurrentAI->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) && EVENT_HIGH_LIMIT_ENABLE) &&
((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) { EVENT_ENABLE_TO_NORMAL)) {
@@ -986,12 +945,14 @@ void Analog_Input_Intrinsic_Reporting(
/* Once the Present_Value has fallen below the Low_Limit, /* Once the Present_Value has fallen below the Low_Limit,
the Present_Value must exceed the Low_Limit plus the Deadband the Present_Value must exceed the Low_Limit plus the Deadband
before a TO-NORMAL event is generated under these conditions: before a TO-NORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband (a) the Present_Value must exceed the Low_Limit plus the
for a minimum period of time, specified in the Time_Delay property, and Deadband for a minimum period of time, specified in the
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and Time_Delay property, and (b) the LowLimitEnable flag must be
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ set in the Limit_Enable property, and
if ((PresentVal > CurrentAI->Low_Limit + CurrentAI->Deadband) (c) the TO-NORMAL flag must be set in the Event_Enable
&& ((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == property. */
if ((PresentVal > CurrentAI->Low_Limit + CurrentAI->Deadband) &&
((CurrentAI->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) && EVENT_LOW_LIMIT_ENABLE) &&
((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) == ((CurrentAI->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) { EVENT_ENABLE_TO_NORMAL)) {
@@ -1030,12 +991,12 @@ void Analog_Input_Intrinsic_Reporting(
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
if (FromState == EVENT_STATE_HIGH_LIMIT) { if (FromState == EVENT_STATE_HIGH_LIMIT) {
ExceededLimit = CurrentAI->High_Limit; ExceededLimit = CurrentAI->High_Limit;
characterstring_init_ansi(&msgText, characterstring_init_ansi(
"Back to normal state from high limit"); &msgText, "Back to normal state from high limit");
} else { } else {
ExceededLimit = CurrentAI->Low_Limit; ExceededLimit = CurrentAI->Low_Limit;
characterstring_init_ansi(&msgText, characterstring_init_ansi(
"Back to normal state from low limit"); &msgText, "Back to normal state from low limit");
} }
break; break;
@@ -1046,8 +1007,8 @@ void Analog_Input_Intrinsic_Reporting(
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n", fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n",
bactext_object_type_name(OBJECT_ANALOG_INPUT), object_instance, bactext_object_type_name(OBJECT_ANALOG_INPUT),
bactext_event_state_name(FromState), object_instance, bactext_event_state_name(FromState),
bactext_event_state_name(ToState)); bactext_event_state_name(ToState));
#endif /* PRINT_ENABLED */ #endif /* PRINT_ENABLED */
@@ -1059,7 +1020,6 @@ void Analog_Input_Intrinsic_Reporting(
} }
} }
if (SendNotify) { if (SendNotify) {
/* Event Object Identifier */ /* Event Object Identifier */
event_data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT; event_data.eventObjectIdentifier.type = OBJECT_ANALOG_INPUT;
@@ -1115,18 +1075,20 @@ void Analog_Input_Intrinsic_Reporting(
event_data.notificationParams.outOfRange.exceedingValue = event_data.notificationParams.outOfRange.exceedingValue =
PresentVal; PresentVal;
/* Status_Flags of the referenced object. */ /* Status_Flags of the referenced object. */
bitstring_init(&event_data.notificationParams.outOfRange. bitstring_init(
statusFlags); &event_data.notificationParams.outOfRange.statusFlags);
bitstring_set_bit(&event_data.notificationParams.outOfRange. bitstring_set_bit(
statusFlags, STATUS_FLAG_IN_ALARM, &event_data.notificationParams.outOfRange.statusFlags,
CurrentAI->Event_State ? true : false); STATUS_FLAG_IN_ALARM, CurrentAI->Event_State ? true : false);
bitstring_set_bit(&event_data.notificationParams.outOfRange. bitstring_set_bit(
statusFlags, STATUS_FLAG_FAULT, false); &event_data.notificationParams.outOfRange.statusFlags,
bitstring_set_bit(&event_data.notificationParams.outOfRange. STATUS_FLAG_FAULT, false);
statusFlags, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(
bitstring_set_bit(&event_data.notificationParams.outOfRange. &event_data.notificationParams.outOfRange.statusFlags,
statusFlags, STATUS_FLAG_OUT_OF_SERVICE, STATUS_FLAG_OVERRIDDEN, false);
CurrentAI->Out_Of_Service); bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_OUT_OF_SERVICE, CurrentAI->Out_Of_Service);
/* Deadband used for limit checking. */ /* Deadband used for limit checking. */
event_data.notificationParams.outOfRange.deadband = event_data.notificationParams.outOfRange.deadband =
CurrentAI->Deadband; CurrentAI->Deadband;
@@ -1145,24 +1107,24 @@ void Analog_Input_Intrinsic_Reporting(
case EVENT_STATE_OFFNORMAL: case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT: case EVENT_STATE_LOW_LIMIT:
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bIsAcked = false; .bIsAcked = false;
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
case EVENT_STATE_FAULT: case EVENT_STATE_FAULT:
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]. CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked =
bIsAcked = false; false;
CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]. CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]
bIsAcked = false; .bIsAcked = false;
CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
} }
} }
@@ -1170,17 +1132,14 @@ void Analog_Input_Intrinsic_Reporting(
#endif /* defined(INTRINSIC_REPORTING) */ #endif /* defined(INTRINSIC_REPORTING) */
} }
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
int Analog_Input_Event_Information( int Analog_Input_Event_Information(
unsigned index, unsigned index, BACNET_GET_EVENT_INFORMATION_DATA *getevent_data)
BACNET_GET_EVENT_INFORMATION_DATA * getevent_data)
{ {
bool IsNotAckedTransitions; bool IsNotAckedTransitions;
bool IsActiveEvent; bool IsActiveEvent;
int i; int i;
/* check index */ /* check index */
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
/* Event_State not equal to NORMAL */ /* Event_State not equal to NORMAL */
@@ -1189,12 +1148,13 @@ int Analog_Input_Event_Information(
/* Acked_Transitions property, which has at least one of the bits /* Acked_Transitions property, which has at least one of the bits
(TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */
IsNotAckedTransitions = IsNotAckedTransitions =
(AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. (AI_Descr[index]
bIsAcked == .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT]. .bIsAcked == false) |
bIsAcked == (AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked ==
false) | (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL]. false) |
bIsAcked == false); (AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked ==
false);
} else } else
return -1; /* end of list */ return -1; /* end of list */
@@ -1209,13 +1169,14 @@ int Analog_Input_Event_Information(
bitstring_init(&getevent_data->acknowledgedTransitions); bitstring_init(&getevent_data->acknowledgedTransitions);
bitstring_set_bit(&getevent_data->acknowledgedTransitions, bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL, TRANSITION_TO_OFFNORMAL,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. AI_Descr[index]
bIsAcked); .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bitstring_set_bit(&getevent_data->acknowledgedTransitions, .bIsAcked);
TRANSITION_TO_FAULT, bitstring_set_bit(
&getevent_data->acknowledgedTransitions, TRANSITION_TO_FAULT,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); AI_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
bitstring_set_bit(&getevent_data->acknowledgedTransitions, bitstring_set_bit(
TRANSITION_TO_NORMAL, &getevent_data->acknowledgedTransitions, TRANSITION_TO_NORMAL,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); AI_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
/* Event Time Stamps */ /* Event Time Stamps */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@@ -1227,15 +1188,18 @@ int Analog_Input_Event_Information(
getevent_data->notifyType = AI_Descr[index].Notify_Type; getevent_data->notifyType = AI_Descr[index].Notify_Type;
/* Event Enable */ /* Event Enable */
bitstring_init(&getevent_data->eventEnable); bitstring_init(&getevent_data->eventEnable);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(
(AI_Descr[index]. &getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
: false);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT, bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT,
(AI_Descr[index]. (AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT)
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false); ? true
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL, : false);
(AI_Descr[index]. bitstring_set_bit(
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); &getevent_data->eventEnable, TRANSITION_TO_NORMAL,
(AI_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true
: false);
/* Event Priorities */ /* Event Priorities */
Notification_Class_Get_Priorities(AI_Descr[index].Notification_Class, Notification_Class_Get_Priorities(AI_Descr[index].Notification_Class,
getevent_data->eventPriorities); getevent_data->eventPriorities);
@@ -1245,18 +1209,14 @@ int Analog_Input_Event_Information(
return 0; /* no active event at this index */ return 0; /* no active event at this index */
} }
int Analog_Input_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data,
int Analog_Input_Alarm_Ack(
BACNET_ALARM_ACK_DATA * alarmack_data,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
ANALOG_INPUT_DESCR *CurrentAI; ANALOG_INPUT_DESCR *CurrentAI;
unsigned int object_index; unsigned int object_index;
object_index = Analog_Input_Instance_To_Index(
object_index = alarmack_data->eventObjectIdentifier.instance);
Analog_Input_Instance_To_Index(alarmack_data->eventObjectIdentifier.
instance);
if (object_index < MAX_ANALOG_INPUTS) if (object_index < MAX_ANALOG_INPUTS)
CurrentAI = &AI_Descr[object_index]; CurrentAI = &AI_Descr[object_index];
@@ -1269,22 +1229,23 @@ int Analog_Input_Alarm_Ack(
case EVENT_STATE_OFFNORMAL: case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT: case EVENT_STATE_LOW_LIMIT:
if (CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. if (CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bIsAcked == false) { .bIsAcked == false) {
if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) { if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAI-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp, &CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
/* FIXME: Send ack notification */ /* FIXME: Send ack notification */
CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAI->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked =
bIsAcked = true; true;
} else { } else {
*error_code = ERROR_CODE_INVALID_EVENT_STATE; *error_code = ERROR_CODE_INVALID_EVENT_STATE;
return -1; return -1;
@@ -1298,8 +1259,9 @@ int Analog_Input_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAI-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp, &CurrentAI->Acked_Transitions[TRANSITION_TO_FAULT]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
@@ -1321,8 +1283,9 @@ int Analog_Input_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAI-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp, &CurrentAI->Acked_Transitions[TRANSITION_TO_NORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
@@ -1346,11 +1309,9 @@ int Analog_Input_Alarm_Ack(
return 1; return 1;
} }
int Analog_Input_Alarm_Summary( int Analog_Input_Alarm_Summary(unsigned index,
unsigned index,
BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data)
{ {
/* check index */ /* check index */
if (index < MAX_ANALOG_INPUTS) { if (index < MAX_ANALOG_INPUTS) {
/* Event_State is not equal to NORMAL and /* Event_State is not equal to NORMAL and
@@ -1367,16 +1328,19 @@ int Analog_Input_Alarm_Summary(
bitstring_init(&getalarm_data->acknowledgedTransitions); bitstring_init(&getalarm_data->acknowledgedTransitions);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL, TRANSITION_TO_OFFNORMAL,
AI_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. AI_Descr[index]
bIsAcked); .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_FAULT, TRANSITION_TO_FAULT,
AI_Descr[index]. AI_Descr[index]
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); .Acked_Transitions[TRANSITION_TO_FAULT]
.bIsAcked);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_NORMAL, TRANSITION_TO_NORMAL,
AI_Descr[index]. AI_Descr[index]
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); .Acked_Transitions[TRANSITION_TO_NORMAL]
.bIsAcked);
return 1; /* active alarm */ return 1; /* active alarm */
} else } else
@@ -1386,16 +1350,13 @@ int Analog_Input_Alarm_Summary(
} }
#endif /* defined(INTRINSIC_REPORTING) */ #endif /* defined(INTRINSIC_REPORTING) */
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
bool bResult; bool bResult;
@@ -1414,8 +1375,7 @@ bool WPValidateArgType(
return (bResult); return (bResult);
} }
void testAnalogInput( void testAnalogInput(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -1444,8 +1404,7 @@ void testAnalogInput(
} }
#ifdef TEST_ANALOG_INPUT #ifdef TEST_ANALOG_INPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+39 -71
View File
@@ -60,8 +60,7 @@ static bool Out_Of_Service[MAX_ANALOG_OUTPUTS];
static bool Analog_Output_Initialized = false; static bool Analog_Output_Initialized = false;
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
@@ -71,20 +70,13 @@ static const int Properties_Required[] = {
PROP_UNITS, PROP_UNITS,
PROP_PRIORITY_ARRAY, PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT, PROP_RELINQUISH_DEFAULT,
-1 -1};
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Analog_Output_Property_Lists( void Analog_Output_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -97,8 +89,7 @@ void Analog_Output_Property_Lists(
return; return;
} }
void Analog_Output_Init( void Analog_Output_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
@@ -119,8 +110,7 @@ void Analog_Output_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Output_Valid_Instance( bool Analog_Output_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_OUTPUTS) if (object_instance < MAX_ANALOG_OUTPUTS)
return true; return true;
@@ -130,8 +120,7 @@ bool Analog_Output_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Output_Count( unsigned Analog_Output_Count(void)
void)
{ {
return MAX_ANALOG_OUTPUTS; return MAX_ANALOG_OUTPUTS;
} }
@@ -139,8 +128,7 @@ unsigned Analog_Output_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Output_Index_To_Instance( uint32_t Analog_Output_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -148,8 +136,7 @@ uint32_t Analog_Output_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Output_Instance_To_Index( unsigned Analog_Output_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_OUTPUTS; unsigned index = MAX_ANALOG_OUTPUTS;
@@ -159,8 +146,7 @@ unsigned Analog_Output_Instance_To_Index(
return index; return index;
} }
float Analog_Output_Present_Value( float Analog_Output_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = AO_RELINQUISH_DEFAULT; float value = AO_RELINQUISH_DEFAULT;
unsigned index = 0; unsigned index = 0;
@@ -179,8 +165,7 @@ float Analog_Output_Present_Value(
return value; return value;
} }
unsigned Analog_Output_Present_Value_Priority( unsigned Analog_Output_Present_Value_Priority(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; /* instance to index conversion */ unsigned index = 0; /* instance to index conversion */
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
@@ -199,9 +184,7 @@ unsigned Analog_Output_Present_Value_Priority(
return priority; return priority;
} }
bool Analog_Output_Present_Value_Set( bool Analog_Output_Present_Value_Set(uint32_t object_instance, float value,
uint32_t object_instance,
float value,
unsigned priority) unsigned priority)
{ {
unsigned index = 0; unsigned index = 0;
@@ -210,8 +193,8 @@ bool Analog_Output_Present_Value_Set(
index = Analog_Output_Instance_To_Index(object_instance); index = Analog_Output_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_OUTPUTS) { if (index < MAX_ANALOG_OUTPUTS) {
if (priority && (priority <= BACNET_MAX_PRIORITY) && if (priority && (priority <= BACNET_MAX_PRIORITY) &&
(priority != 6 /* reserved */ ) && (priority != 6 /* reserved */) && (value >= 0.0) &&
(value >= 0.0) && (value <= 100.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 /* Note: you could set the physical output here to the next
highest priority, or to the relinquish default if no highest priority, or to the relinquish default if no
@@ -226,8 +209,7 @@ bool Analog_Output_Present_Value_Set(
return status; return status;
} }
bool Analog_Output_Present_Value_Relinquish( bool Analog_Output_Present_Value_Relinquish(uint32_t object_instance,
uint32_t object_instance,
unsigned priority) unsigned priority)
{ {
unsigned index = 0; unsigned index = 0;
@@ -252,8 +234,7 @@ bool Analog_Output_Present_Value_Relinquish(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Analog_Output_Object_Name( bool Analog_Output_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -268,8 +249,7 @@ bool Analog_Output_Object_Name(
return status; return status;
} }
bool Analog_Output_Out_Of_Service( bool Analog_Output_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned index = 0; unsigned index = 0;
bool oos_flag = false; bool oos_flag = false;
@@ -282,9 +262,7 @@ bool Analog_Output_Out_Of_Service(
return oos_flag; return oos_flag;
} }
void Analog_Output_Out_Of_Service_Set( void Analog_Output_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
uint32_t instance,
bool oos_flag)
{ {
unsigned index = 0; unsigned index = 0;
@@ -295,8 +273,7 @@ void Analog_Output_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Analog_Output_Read_Property( int Analog_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -315,9 +292,8 @@ int Analog_Output_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_OUTPUT, &apdu[0], OBJECT_ANALOG_OUTPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Analog_Output_Object_Name(rpdata->object_instance, &char_string); Analog_Output_Object_Name(rpdata->object_instance, &char_string);
@@ -368,8 +344,7 @@ int Analog_Output_Read_Property(
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
else { else {
real_value = Analog_Output_Level[object_index][i]; real_value = Analog_Output_Level[object_index][i];
len = len = encode_application_real(&apdu[apdu_len],
encode_application_real(&apdu[apdu_len],
real_value); real_value);
} }
/* add it if we have room */ /* add it if we have room */
@@ -390,7 +365,8 @@ int Analog_Output_Read_Property(
1] == AO_LEVEL_NULL) 1] == AO_LEVEL_NULL)
apdu_len = encode_application_null(&apdu[0]); apdu_len = encode_application_null(&apdu[0]);
else { else {
real_value = Analog_Output_Level[object_index] real_value =
Analog_Output_Level[object_index]
[rpdata->array_index - 1]; [rpdata->array_index - 1];
apdu_len = apdu_len =
encode_application_real(&apdu[0], real_value); encode_application_real(&apdu[0], real_value);
@@ -424,16 +400,14 @@ int Analog_Output_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Output_Write_Property( bool Analog_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -455,9 +429,9 @@ bool Analog_Output_Write_Property(
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
object. */ object. */
status = status = Analog_Output_Present_Value_Set(
Analog_Output_Present_Value_Set(wp_data->object_instance, wp_data->object_instance, value.type.Real,
value.type.Real, wp_data->priority); wp_data->priority);
if (wp_data->priority == 6) { if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
@@ -469,13 +443,12 @@ bool Analog_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, &wp_data->error_class,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_code);
if (status) { if (status) {
status = status = Analog_Output_Present_Value_Relinquish(
Analog_Output_Present_Value_Relinquish wp_data->object_instance, wp_data->priority);
(wp_data->object_instance, wp_data->priority);
if (!status) { if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -512,16 +485,13 @@ bool Analog_Output_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
bool bResult; bool bResult;
@@ -540,8 +510,7 @@ bool WPValidateArgType(
return (bResult); return (bResult);
} }
void testAnalogOutput( void testAnalogOutput(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -570,8 +539,7 @@ void testAnalogOutput(
} }
#ifdef TEST_ANALOG_OUTPUT #ifdef TEST_ANALOG_OUTPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+195 -226
View File
@@ -41,7 +41,6 @@
#include "handlers.h" #include "handlers.h"
#include "av.h" #include "av.h"
#ifndef MAX_ANALOG_VALUES #ifndef MAX_ANALOG_VALUES
#define MAX_ANALOG_VALUES 4 #define MAX_ANALOG_VALUES 4
#endif #endif
@@ -50,19 +49,11 @@ ANALOG_VALUE_DESCR AV_Descr[MAX_ANALOG_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* 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_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_OBJECT_NAME, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OBJECT_TYPE, PROP_OUT_OF_SERVICE, PROP_UNITS, -1};
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Value_Properties_Optional[] = { static const int Analog_Value_Properties_Optional[] = {PROP_DESCRIPTION,
PROP_DESCRIPTION,
PROP_COV_INCREMENT, PROP_COV_INCREMENT,
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
PROP_TIME_DELAY, PROP_TIME_DELAY,
@@ -76,16 +67,11 @@ static const int Analog_Value_Properties_Optional[] = {
PROP_NOTIFY_TYPE, PROP_NOTIFY_TYPE,
PROP_EVENT_TIME_STAMPS, PROP_EVENT_TIME_STAMPS,
#endif #endif
-1 -1};
};
static const int Analog_Value_Properties_Proprietary[] = { static const int Analog_Value_Properties_Proprietary[] = {-1};
-1
};
void Analog_Value_Property_Lists( void Analog_Value_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -98,8 +84,7 @@ void Analog_Value_Property_Lists(
return; return;
} }
void Analog_Value_Init( void Analog_Value_Init(void)
void)
{ {
unsigned i; unsigned i;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -139,8 +124,7 @@ void Analog_Value_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Analog_Value_Valid_Instance( bool Analog_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_ANALOG_VALUES) if (object_instance < MAX_ANALOG_VALUES)
return true; return true;
@@ -150,8 +134,7 @@ bool Analog_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Analog_Value_Count( unsigned Analog_Value_Count(void)
void)
{ {
return MAX_ANALOG_VALUES; return MAX_ANALOG_VALUES;
} }
@@ -159,8 +142,7 @@ unsigned Analog_Value_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Analog_Value_Index_To_Instance( uint32_t Analog_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -168,8 +150,7 @@ uint32_t Analog_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Analog_Value_Instance_To_Index( unsigned Analog_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_ANALOG_VALUES; unsigned index = MAX_ANALOG_VALUES;
@@ -179,8 +160,7 @@ unsigned Analog_Value_Instance_To_Index(
return index; return index;
} }
static void Analog_Value_COV_Detect(unsigned int index, static void Analog_Value_COV_Detect(unsigned int index, float value)
float value)
{ {
float prior_value = 0.0; float prior_value = 0.0;
float cov_increment = 0.0; float cov_increment = 0.0;
@@ -211,9 +191,7 @@ static void Analog_Value_COV_Detect(unsigned int index,
* *
* @return true if values are within range and present-value is set. * @return true if values are within range and present-value is set.
*/ */
bool Analog_Value_Present_Value_Set( bool Analog_Value_Present_Value_Set(uint32_t object_instance, float value,
uint32_t object_instance,
float value,
uint8_t priority) uint8_t priority)
{ {
unsigned index = 0; unsigned index = 0;
@@ -228,8 +206,7 @@ bool Analog_Value_Present_Value_Set(
return status; return status;
} }
float Analog_Value_Present_Value( float Analog_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
float value = 0; float value = 0;
unsigned index = 0; unsigned index = 0;
@@ -243,8 +220,7 @@ float Analog_Value_Present_Value(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Analog_Value_Object_Name( bool Analog_Value_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -303,8 +279,7 @@ void Analog_Value_Change_Of_Value_Clear(uint32_t object_instance)
* *
* @return true if the value list is encoded * @return true if the value list is encoded
*/ */
bool Analog_Value_Encode_Value_List( bool Analog_Value_Encode_Value_List(uint32_t object_instance,
uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list) BACNET_PROPERTY_VALUE *value_list)
{ {
bool status = false; bool status = false;
@@ -328,8 +303,8 @@ bool Analog_Value_Encode_Value_List(
bitstring_init(&value_list->value.type.Bit_String); bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_IN_ALARM, false); STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT,
STATUS_FLAG_FAULT, false); false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OVERRIDDEN, false); STATUS_FLAG_OVERRIDDEN, false);
if (Analog_Value_Out_Of_Service(object_instance)) { if (Analog_Value_Out_Of_Service(object_instance)) {
@@ -348,8 +323,7 @@ bool Analog_Value_Encode_Value_List(
return status; return status;
} }
float Analog_Value_COV_Increment( float Analog_Value_COV_Increment(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
float value = 0; float value = 0;
@@ -362,9 +336,7 @@ float Analog_Value_COV_Increment(
return value; return value;
} }
void Analog_Value_COV_Increment_Set( void Analog_Value_COV_Increment_Set(uint32_t object_instance, float value)
uint32_t object_instance,
float value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -375,8 +347,7 @@ void Analog_Value_COV_Increment_Set(
} }
} }
bool Analog_Value_Out_Of_Service( bool Analog_Value_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; unsigned index = 0;
bool value = false; bool value = false;
@@ -389,9 +360,7 @@ bool Analog_Value_Out_Of_Service(
return value; return value;
} }
void Analog_Value_Out_Of_Service_Set( void Analog_Value_Out_Of_Service_Set(uint32_t object_instance, bool value)
uint32_t object_instance,
bool value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -405,8 +374,7 @@ void Analog_Value_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Analog_Value_Read_Property( int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -436,9 +404,8 @@ int Analog_Value_Read_Property(
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_ANALOG_VALUE, &apdu[0], OBJECT_ANALOG_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -477,8 +444,7 @@ int Analog_Value_Read_Property(
case PROP_EVENT_STATE: case PROP_EVENT_STATE:
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], CurrentAV->Event_State);
CurrentAV->Event_State);
#else #else
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
@@ -496,8 +462,8 @@ int Analog_Value_Read_Property(
break; break;
case PROP_COV_INCREMENT: case PROP_COV_INCREMENT:
apdu_len = encode_application_real(&apdu[0], apdu_len =
CurrentAV->COV_Increment); encode_application_real(&apdu[0], CurrentAV->COV_Increment);
break; break;
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
@@ -507,14 +473,12 @@ int Analog_Value_Read_Property(
break; break;
case PROP_NOTIFICATION_CLASS: case PROP_NOTIFICATION_CLASS:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], CurrentAV->Notification_Class);
CurrentAV->Notification_Class);
break; break;
case PROP_HIGH_LIMIT: case PROP_HIGH_LIMIT:
apdu_len = apdu_len = encode_application_real(&apdu[0], CurrentAV->High_Limit);
encode_application_real(&apdu[0], CurrentAV->High_Limit);
break; break;
case PROP_LOW_LIMIT: case PROP_LOW_LIMIT:
@@ -528,70 +492,73 @@ int Analog_Value_Read_Property(
case PROP_LIMIT_ENABLE: case PROP_LIMIT_ENABLE:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, 0, bitstring_set_bit(&bit_string, 0,
(CurrentAV-> (CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE)
Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ? true : false); ? true
bitstring_set_bit(&bit_string, 1, : false);
(CurrentAV-> bitstring_set_bit(
Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true : false); &bit_string, 1,
(CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ? true
: false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_EVENT_ENABLE: case PROP_EVENT_ENABLE:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(
(CurrentAV-> &bit_string, TRANSITION_TO_OFFNORMAL,
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); (CurrentAV->Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
: false);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT,
(CurrentAV-> (CurrentAV->Event_Enable & EVENT_ENABLE_TO_FAULT)
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false); ? true
: false);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL,
(CurrentAV-> (CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL)
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); ? true
: false);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_ACKED_TRANSITIONS: case PROP_ACKED_TRANSITIONS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. &bit_string, TRANSITION_TO_OFFNORMAL,
bIsAcked); CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_FAULT, bitstring_set_bit(
&bit_string, TRANSITION_TO_FAULT,
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
bitstring_set_bit(&bit_string, TRANSITION_TO_NORMAL, bitstring_set_bit(
&bit_string, TRANSITION_TO_NORMAL,
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_NOTIFY_TYPE: case PROP_NOTIFY_TYPE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], CurrentAV->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
CurrentAV->Notify_Type ? NOTIFY_EVENT : NOTIFY_ALARM);
break; break;
case PROP_EVENT_TIME_STAMPS: case PROP_EVENT_TIME_STAMPS:
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
if (rpdata->array_index == 0) if (rpdata->array_index == 0)
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], MAX_BACNET_EVENT_TRANSITION);
MAX_BACNET_EVENT_TRANSITION);
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list */
/* into one packet. */ /* into one packet. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) { for (i = 0; i < MAX_BACNET_EVENT_TRANSITION; i++) {
len = len = encode_opening_tag(&apdu[apdu_len],
encode_opening_tag(&apdu[apdu_len],
TIME_STAMP_DATETIME); TIME_STAMP_DATETIME);
len += len += encode_application_date(
encode_application_date(&apdu[apdu_len + len], &apdu[apdu_len + len],
&CurrentAV->Event_Time_Stamps[i].date); &CurrentAV->Event_Time_Stamps[i].date);
len += len += encode_application_time(
encode_application_time(&apdu[apdu_len + len], &apdu[apdu_len + len],
&CurrentAV->Event_Time_Stamps[i].time); &CurrentAV->Event_Time_Stamps[i].time);
len += len += encode_closing_tag(&apdu[apdu_len + len],
encode_closing_tag(&apdu[apdu_len + len],
TIME_STAMP_DATETIME); TIME_STAMP_DATETIME);
/* add it if we have room */ /* add it if we have room */
@@ -607,11 +574,11 @@ int Analog_Value_Read_Property(
} else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) { } else if (rpdata->array_index <= MAX_BACNET_EVENT_TRANSITION) {
apdu_len = apdu_len =
encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); encode_opening_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
apdu_len += apdu_len += encode_application_date(
encode_application_date(&apdu[apdu_len], &apdu[apdu_len],
&CurrentAV->Event_Time_Stamps[rpdata->array_index].date); &CurrentAV->Event_Time_Stamps[rpdata->array_index].date);
apdu_len += apdu_len += encode_application_time(
encode_application_time(&apdu[apdu_len], &apdu[apdu_len],
&CurrentAV->Event_Time_Stamps[rpdata->array_index].time); &CurrentAV->Event_Time_Stamps[rpdata->array_index].time);
apdu_len += apdu_len +=
encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME); encode_closing_tag(&apdu[apdu_len], TIME_STAMP_DATETIME);
@@ -642,8 +609,7 @@ int Analog_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Analog_Value_Write_Property( bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -652,8 +618,7 @@ bool Analog_Value_Write_Property(
ANALOG_VALUE_DESCR *CurrentAV; ANALOG_VALUE_DESCR *CurrentAV;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -683,7 +648,8 @@ bool Analog_Value_Write_Property(
algorithm and may not be used for other purposes in any algorithm and may not be used for other purposes in any
object. */ object. */
if (Analog_Value_Present_Value_Set(wp_data->object_instance, if (Analog_Value_Present_Value_Set(wp_data->object_instance,
value.type.Real, wp_data->priority)) { value.type.Real,
wp_data->priority)) {
status = true; status = true;
} else if (wp_data->priority == 6) { } else if (wp_data->priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
@@ -726,8 +692,7 @@ bool Analog_Value_Write_Property(
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if (value.type.Real >= 0.0) { if (value.type.Real >= 0.0) {
Analog_Value_COV_Increment_Set( Analog_Value_COV_Increment_Set(wp_data->object_instance,
wp_data->object_instance,
value.type.Real); value.type.Real);
} else { } else {
status = false; status = false;
@@ -867,9 +832,7 @@ bool Analog_Value_Write_Property(
return status; return status;
} }
void Analog_Value_Intrinsic_Reporting(uint32_t object_instance)
void Analog_Value_Intrinsic_Reporting(
uint32_t object_instance)
{ {
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
BACNET_EVENT_NOTIFICATION_DATA event_data; BACNET_EVENT_NOTIFICATION_DATA event_data;
@@ -882,7 +845,6 @@ void Analog_Value_Intrinsic_Reporting(
float PresentVal = 0.0f; float PresentVal = 0.0f;
bool SendNotify = false; bool SendNotify = false;
object_index = Analog_Value_Instance_To_Index(object_instance); object_index = Analog_Value_Instance_To_Index(object_instance);
if (object_index < MAX_ANALOG_VALUES) if (object_index < MAX_ANALOG_VALUES)
CurrentAV = &AV_Descr[object_index]; CurrentAV = &AV_Descr[object_index];
@@ -893,7 +855,6 @@ void Analog_Value_Intrinsic_Reporting(
if (!CurrentAV->Limit_Enable) if (!CurrentAV->Limit_Enable)
return; /* limits are not configured */ return; /* limits are not configured */
if (CurrentAV->Ack_notify_data.bSendAckNotify) { if (CurrentAV->Ack_notify_data.bSendAckNotify) {
/* clean bSendAckNotify flag */ /* clean bSendAckNotify flag */
CurrentAV->Ack_notify_data.bSendAckNotify = false; CurrentAV->Ack_notify_data.bSendAckNotify = false;
@@ -919,10 +880,12 @@ void Analog_Value_Intrinsic_Reporting(
switch (CurrentAV->Event_State) { switch (CurrentAV->Event_State) {
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
/* A TO-OFFNORMAL event is generated under these conditions: /* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the High_Limit for a minimum (a) the Present_Value must exceed the High_Limit for a
period of time, specified in the Time_Delay property, and minimum period of time, specified in the Time_Delay property,
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and and (b) the HighLimitEnable flag must be set in the
(c) the TO-OFFNORMAL flag must be set in the Event_Enable property. */ Limit_Enable property, and
(c) the TO-OFFNORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal > CurrentAV->High_Limit) && if ((PresentVal > CurrentAV->High_Limit) &&
((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == ((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) && EVENT_HIGH_LIMIT_ENABLE) &&
@@ -936,10 +899,12 @@ void Analog_Value_Intrinsic_Reporting(
} }
/* A TO-OFFNORMAL event is generated under these conditions: /* A TO-OFFNORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband (a) the Present_Value must exceed the Low_Limit plus the
for a minimum period of time, specified in the Time_Delay property, and Deadband for a minimum period of time, specified in the
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and Time_Delay property, and (b) the LowLimitEnable flag must be
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ set in the Limit_Enable property, and
(c) the TO-NORMAL flag must be set in the Event_Enable
property. */
if ((PresentVal < CurrentAV->Low_Limit) && if ((PresentVal < CurrentAV->Low_Limit) &&
((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == ((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) && EVENT_LOW_LIMIT_ENABLE) &&
@@ -956,14 +921,17 @@ void Analog_Value_Intrinsic_Reporting(
break; break;
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
/* Once exceeded, the Present_Value must fall below the High_Limit minus /* Once exceeded, the Present_Value must fall below the
the Deadband before a TO-NORMAL event is generated under these conditions: High_Limit minus the Deadband before a TO-NORMAL event is
(a) the Present_Value must fall below the High_Limit minus the Deadband generated under these conditions: (a) the Present_Value must
for a minimum period of time, specified in the Time_Delay property, and fall below the High_Limit minus the Deadband for a minimum
(b) the HighLimitEnable flag must be set in the Limit_Enable property, and period of time, specified in the Time_Delay property, and (b)
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ the HighLimitEnable flag must be set in the Limit_Enable
if ((PresentVal < CurrentAV->High_Limit - CurrentAV->Deadband) property, and (c) the TO-NORMAL flag must be set in the
&& ((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) == Event_Enable property. */
if ((PresentVal <
CurrentAV->High_Limit - CurrentAV->Deadband) &&
((CurrentAV->Limit_Enable & EVENT_HIGH_LIMIT_ENABLE) ==
EVENT_HIGH_LIMIT_ENABLE) && EVENT_HIGH_LIMIT_ENABLE) &&
((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) == ((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) { EVENT_ENABLE_TO_NORMAL)) {
@@ -981,12 +949,14 @@ void Analog_Value_Intrinsic_Reporting(
/* Once the Present_Value has fallen below the Low_Limit, /* Once the Present_Value has fallen below the Low_Limit,
the Present_Value must exceed the Low_Limit plus the Deadband the Present_Value must exceed the Low_Limit plus the Deadband
before a TO-NORMAL event is generated under these conditions: before a TO-NORMAL event is generated under these conditions:
(a) the Present_Value must exceed the Low_Limit plus the Deadband (a) the Present_Value must exceed the Low_Limit plus the
for a minimum period of time, specified in the Time_Delay property, and Deadband for a minimum period of time, specified in the
(b) the LowLimitEnable flag must be set in the Limit_Enable property, and Time_Delay property, and (b) the LowLimitEnable flag must be
(c) the TO-NORMAL flag must be set in the Event_Enable property. */ set in the Limit_Enable property, and
if ((PresentVal > CurrentAV->Low_Limit + CurrentAV->Deadband) (c) the TO-NORMAL flag must be set in the Event_Enable
&& ((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) == property. */
if ((PresentVal > CurrentAV->Low_Limit + CurrentAV->Deadband) &&
((CurrentAV->Limit_Enable & EVENT_LOW_LIMIT_ENABLE) ==
EVENT_LOW_LIMIT_ENABLE) && EVENT_LOW_LIMIT_ENABLE) &&
((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) == ((CurrentAV->Event_Enable & EVENT_ENABLE_TO_NORMAL) ==
EVENT_ENABLE_TO_NORMAL)) { EVENT_ENABLE_TO_NORMAL)) {
@@ -1025,12 +995,12 @@ void Analog_Value_Intrinsic_Reporting(
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
if (FromState == EVENT_STATE_HIGH_LIMIT) { if (FromState == EVENT_STATE_HIGH_LIMIT) {
ExceededLimit = CurrentAV->High_Limit; ExceededLimit = CurrentAV->High_Limit;
characterstring_init_ansi(&msgText, characterstring_init_ansi(
"Back to normal state from high limit"); &msgText, "Back to normal state from high limit");
} else { } else {
ExceededLimit = CurrentAV->Low_Limit; ExceededLimit = CurrentAV->Low_Limit;
characterstring_init_ansi(&msgText, characterstring_init_ansi(
"Back to normal state from low limit"); &msgText, "Back to normal state from low limit");
} }
break; break;
@@ -1041,8 +1011,8 @@ void Analog_Value_Intrinsic_Reporting(
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n", fprintf(stderr, "Event_State for (%s,%d) goes from %s to %s.\n",
bactext_object_type_name(OBJECT_ANALOG_VALUE), object_instance, bactext_object_type_name(OBJECT_ANALOG_VALUE),
bactext_event_state_name(FromState), object_instance, bactext_event_state_name(FromState),
bactext_event_state_name(ToState)); bactext_event_state_name(ToState));
#endif /* PRINT_ENABLED */ #endif /* PRINT_ENABLED */
@@ -1054,7 +1024,6 @@ void Analog_Value_Intrinsic_Reporting(
} }
} }
if (SendNotify) { if (SendNotify) {
/* Event Object Identifier */ /* Event Object Identifier */
event_data.eventObjectIdentifier.type = OBJECT_ANALOG_VALUE; event_data.eventObjectIdentifier.type = OBJECT_ANALOG_VALUE;
@@ -1110,18 +1079,20 @@ void Analog_Value_Intrinsic_Reporting(
event_data.notificationParams.outOfRange.exceedingValue = event_data.notificationParams.outOfRange.exceedingValue =
PresentVal; PresentVal;
/* Status_Flags of the referenced object. */ /* Status_Flags of the referenced object. */
bitstring_init(&event_data.notificationParams.outOfRange. bitstring_init(
statusFlags); &event_data.notificationParams.outOfRange.statusFlags);
bitstring_set_bit(&event_data.notificationParams.outOfRange. bitstring_set_bit(
statusFlags, STATUS_FLAG_IN_ALARM, &event_data.notificationParams.outOfRange.statusFlags,
CurrentAV->Event_State ? true : false); STATUS_FLAG_IN_ALARM, CurrentAV->Event_State ? true : false);
bitstring_set_bit(&event_data.notificationParams.outOfRange. bitstring_set_bit(
statusFlags, STATUS_FLAG_FAULT, false); &event_data.notificationParams.outOfRange.statusFlags,
bitstring_set_bit(&event_data.notificationParams.outOfRange. STATUS_FLAG_FAULT, false);
statusFlags, STATUS_FLAG_OVERRIDDEN, false); bitstring_set_bit(
bitstring_set_bit(&event_data.notificationParams.outOfRange. &event_data.notificationParams.outOfRange.statusFlags,
statusFlags, STATUS_FLAG_OUT_OF_SERVICE, STATUS_FLAG_OVERRIDDEN, false);
CurrentAV->Out_Of_Service); bitstring_set_bit(
&event_data.notificationParams.outOfRange.statusFlags,
STATUS_FLAG_OUT_OF_SERVICE, CurrentAV->Out_Of_Service);
/* Deadband used for limit checking. */ /* Deadband used for limit checking. */
event_data.notificationParams.outOfRange.deadband = event_data.notificationParams.outOfRange.deadband =
CurrentAV->Deadband; CurrentAV->Deadband;
@@ -1140,24 +1111,24 @@ void Analog_Value_Intrinsic_Reporting(
case EVENT_STATE_OFFNORMAL: case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT: case EVENT_STATE_LOW_LIMIT:
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bIsAcked = false; .bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
case EVENT_STATE_FAULT: case EVENT_STATE_FAULT:
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT]. CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked =
bIsAcked = false; false;
CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT]. CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
case EVENT_STATE_NORMAL: case EVENT_STATE_NORMAL:
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]. CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]
bIsAcked = false; .bIsAcked = false;
CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]. CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]
Time_Stamp = event_data.timeStamp.value.dateTime; .Time_Stamp = event_data.timeStamp.value.dateTime;
break; break;
} }
} }
@@ -1165,17 +1136,14 @@ void Analog_Value_Intrinsic_Reporting(
#endif /* defined(INTRINSIC_REPORTING) */ #endif /* defined(INTRINSIC_REPORTING) */
} }
#if defined(INTRINSIC_REPORTING) #if defined(INTRINSIC_REPORTING)
int Analog_Value_Event_Information( int Analog_Value_Event_Information(
unsigned index, unsigned index, BACNET_GET_EVENT_INFORMATION_DATA *getevent_data)
BACNET_GET_EVENT_INFORMATION_DATA * getevent_data)
{ {
bool IsNotAckedTransitions; bool IsNotAckedTransitions;
bool IsActiveEvent; bool IsActiveEvent;
int i; int i;
/* check index */ /* check index */
if (index < MAX_ANALOG_VALUES) { if (index < MAX_ANALOG_VALUES) {
/* Event_State not equal to NORMAL */ /* Event_State not equal to NORMAL */
@@ -1184,12 +1152,13 @@ int Analog_Value_Event_Information(
/* Acked_Transitions property, which has at least one of the bits /* Acked_Transitions property, which has at least one of the bits
(TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */ (TO-OFFNORMAL, TO-FAULT, TONORMAL) set to FALSE. */
IsNotAckedTransitions = IsNotAckedTransitions =
(AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. (AV_Descr[index]
bIsAcked == .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT]. .bIsAcked == false) |
bIsAcked == (AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked ==
false) | (AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL]. false) |
bIsAcked == false); (AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked ==
false);
} else } else
return -1; /* end of list */ return -1; /* end of list */
@@ -1204,13 +1173,14 @@ int Analog_Value_Event_Information(
bitstring_init(&getevent_data->acknowledgedTransitions); bitstring_init(&getevent_data->acknowledgedTransitions);
bitstring_set_bit(&getevent_data->acknowledgedTransitions, bitstring_set_bit(&getevent_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL, TRANSITION_TO_OFFNORMAL,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. AV_Descr[index]
bIsAcked); .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bitstring_set_bit(&getevent_data->acknowledgedTransitions, .bIsAcked);
TRANSITION_TO_FAULT, bitstring_set_bit(
&getevent_data->acknowledgedTransitions, TRANSITION_TO_FAULT,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); AV_Descr[index].Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked);
bitstring_set_bit(&getevent_data->acknowledgedTransitions, bitstring_set_bit(
TRANSITION_TO_NORMAL, &getevent_data->acknowledgedTransitions, TRANSITION_TO_NORMAL,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); AV_Descr[index].Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked);
/* Event Time Stamps */ /* Event Time Stamps */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@@ -1222,15 +1192,18 @@ int Analog_Value_Event_Information(
getevent_data->notifyType = AV_Descr[index].Notify_Type; getevent_data->notifyType = AV_Descr[index].Notify_Type;
/* Event Enable */ /* Event Enable */
bitstring_init(&getevent_data->eventEnable); bitstring_init(&getevent_data->eventEnable);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL, bitstring_set_bit(
(AV_Descr[index]. &getevent_data->eventEnable, TRANSITION_TO_OFFNORMAL,
Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true : false); (AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_OFFNORMAL) ? true
: false);
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT, bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_FAULT,
(AV_Descr[index]. (AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_FAULT)
Event_Enable & EVENT_ENABLE_TO_FAULT) ? true : false); ? true
bitstring_set_bit(&getevent_data->eventEnable, TRANSITION_TO_NORMAL, : false);
(AV_Descr[index]. bitstring_set_bit(
Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true : false); &getevent_data->eventEnable, TRANSITION_TO_NORMAL,
(AV_Descr[index].Event_Enable & EVENT_ENABLE_TO_NORMAL) ? true
: false);
/* Event Priorities */ /* Event Priorities */
Notification_Class_Get_Priorities(AV_Descr[index].Notification_Class, Notification_Class_Get_Priorities(AV_Descr[index].Notification_Class,
getevent_data->eventPriorities); getevent_data->eventPriorities);
@@ -1240,17 +1213,14 @@ int Analog_Value_Event_Information(
return 0; /* no active event at this index */ return 0; /* no active event at this index */
} }
int Analog_Value_Alarm_Ack( int Analog_Value_Alarm_Ack(BACNET_ALARM_ACK_DATA *alarmack_data,
BACNET_ALARM_ACK_DATA * alarmack_data,
BACNET_ERROR_CODE *error_code) BACNET_ERROR_CODE *error_code)
{ {
ANALOG_VALUE_DESCR *CurrentAV; ANALOG_VALUE_DESCR *CurrentAV;
unsigned int object_index; unsigned int object_index;
object_index = Analog_Value_Instance_To_Index(
object_index = alarmack_data->eventObjectIdentifier.instance);
Analog_Value_Instance_To_Index(alarmack_data->eventObjectIdentifier.
instance);
if (object_index < MAX_ANALOG_VALUES) if (object_index < MAX_ANALOG_VALUES)
CurrentAV = &AV_Descr[object_index]; CurrentAV = &AV_Descr[object_index];
@@ -1263,22 +1233,23 @@ int Analog_Value_Alarm_Ack(
case EVENT_STATE_OFFNORMAL: case EVENT_STATE_OFFNORMAL:
case EVENT_STATE_HIGH_LIMIT: case EVENT_STATE_HIGH_LIMIT:
case EVENT_STATE_LOW_LIMIT: case EVENT_STATE_LOW_LIMIT:
if (CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. if (CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
bIsAcked == false) { .bIsAcked == false) {
if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) { if (alarmack_data->eventTimeStamp.tag != TIME_STAMP_DATETIME) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAV-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_OFFNORMAL].Time_Stamp, &CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
/* Clean transitions flag. */ /* Clean transitions flag. */
CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL]. CurrentAV->Acked_Transitions[TRANSITION_TO_OFFNORMAL].bIsAcked =
bIsAcked = true; true;
} else { } else {
*error_code = ERROR_CODE_INVALID_EVENT_STATE; *error_code = ERROR_CODE_INVALID_EVENT_STATE;
return -1; return -1;
@@ -1292,8 +1263,9 @@ int Analog_Value_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAV-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_NORMAL].Time_Stamp, &CurrentAV->Acked_Transitions[TRANSITION_TO_NORMAL]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
@@ -1315,8 +1287,9 @@ int Analog_Value_Alarm_Ack(
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
} }
if (datetime_compare(&CurrentAV-> if (datetime_compare(
Acked_Transitions[TRANSITION_TO_FAULT].Time_Stamp, &CurrentAV->Acked_Transitions[TRANSITION_TO_FAULT]
.Time_Stamp,
&alarmack_data->eventTimeStamp.value.dateTime) > 0) { &alarmack_data->eventTimeStamp.value.dateTime) > 0) {
*error_code = ERROR_CODE_INVALID_TIME_STAMP; *error_code = ERROR_CODE_INVALID_TIME_STAMP;
return -1; return -1;
@@ -1343,11 +1316,9 @@ int Analog_Value_Alarm_Ack(
return 1; return 1;
} }
int Analog_Value_Alarm_Summary( int Analog_Value_Alarm_Summary(unsigned index,
unsigned index,
BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data) BACNET_GET_ALARM_SUMMARY_DATA *getalarm_data)
{ {
/* check index */ /* check index */
if (index < MAX_ANALOG_VALUES) { if (index < MAX_ANALOG_VALUES) {
/* Event_State is not equal to NORMAL and /* Event_State is not equal to NORMAL and
@@ -1364,16 +1335,19 @@ int Analog_Value_Alarm_Summary(
bitstring_init(&getalarm_data->acknowledgedTransitions); bitstring_init(&getalarm_data->acknowledgedTransitions);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_OFFNORMAL, TRANSITION_TO_OFFNORMAL,
AV_Descr[index].Acked_Transitions[TRANSITION_TO_OFFNORMAL]. AV_Descr[index]
bIsAcked); .Acked_Transitions[TRANSITION_TO_OFFNORMAL]
.bIsAcked);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_FAULT, TRANSITION_TO_FAULT,
AV_Descr[index]. AV_Descr[index]
Acked_Transitions[TRANSITION_TO_FAULT].bIsAcked); .Acked_Transitions[TRANSITION_TO_FAULT]
.bIsAcked);
bitstring_set_bit(&getalarm_data->acknowledgedTransitions, bitstring_set_bit(&getalarm_data->acknowledgedTransitions,
TRANSITION_TO_NORMAL, TRANSITION_TO_NORMAL,
AV_Descr[index]. AV_Descr[index]
Acked_Transitions[TRANSITION_TO_NORMAL].bIsAcked); .Acked_Transitions[TRANSITION_TO_NORMAL]
.bIsAcked);
return 1; /* active alarm */ return 1; /* active alarm */
} else } else
@@ -1383,16 +1357,13 @@ int Analog_Value_Alarm_Summary(
} }
#endif /* defined(INTRINSIC_REPORTING) */ #endif /* defined(INTRINSIC_REPORTING) */
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -1403,8 +1374,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testAnalog_Value( void testAnalog_Value(Test *pTest)
Test * pTest)
{ {
BACNET_READ_PROPERTY_DATA rpdata; BACNET_READ_PROPERTY_DATA rpdata;
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
@@ -1433,8 +1403,7 @@ void testAnalog_Value(
} }
#ifdef TEST_ANALOG_VALUE #ifdef TEST_ANALOG_VALUE
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+43 -74
View File
@@ -61,8 +61,7 @@ static BACNET_FILE_LISTING BACnet_File_Listing[] = {
}; };
/* These three arrays are used by the ReadPropertyMultiple handler */ /* 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_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_FILE_TYPE, PROP_FILE_TYPE,
@@ -71,21 +70,13 @@ static const int bacfile_Properties_Required[] = {
PROP_ARCHIVE, PROP_ARCHIVE,
PROP_READ_ONLY, PROP_READ_ONLY,
PROP_FILE_ACCESS_METHOD, PROP_FILE_ACCESS_METHOD,
-1 -1};
};
static const int bacfile_Properties_Optional[] = { static const int bacfile_Properties_Optional[] = {PROP_DESCRIPTION, -1};
PROP_DESCRIPTION,
-1
};
static const int bacfile_Properties_Proprietary[] = { static const int bacfile_Properties_Proprietary[] = {-1};
-1
};
void BACfile_Property_Lists( void BACfile_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -98,8 +89,7 @@ void BACfile_Property_Lists(
return; return;
} }
static char *bacfile_name( static char *bacfile_name(uint32_t instance)
uint32_t instance)
{ {
uint32_t index = 0; uint32_t index = 0;
char *filename = NULL; char *filename = NULL;
@@ -116,8 +106,7 @@ static char *bacfile_name(
return filename; return filename;
} }
bool bacfile_object_name( bool bacfile_object_name(uint32_t instance,
uint32_t instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
bool status = false; bool status = false;
@@ -131,14 +120,12 @@ bool bacfile_object_name(
return status; return status;
} }
bool bacfile_valid_instance( bool bacfile_valid_instance(uint32_t object_instance)
uint32_t object_instance)
{ {
return bacfile_name(object_instance) ? true : false; return bacfile_name(object_instance) ? true : false;
} }
uint32_t bacfile_count( uint32_t bacfile_count(void)
void)
{ {
uint32_t index = 0; uint32_t index = 0;
@@ -150,8 +137,7 @@ uint32_t bacfile_count(
return index; return index;
} }
uint32_t bacfile_index_to_instance( uint32_t bacfile_index_to_instance(unsigned find_index)
unsigned find_index)
{ {
uint32_t instance = BACNET_MAX_INSTANCE + 1; uint32_t instance = BACNET_MAX_INSTANCE + 1;
uint32_t index = 0; uint32_t index = 0;
@@ -168,8 +154,7 @@ uint32_t bacfile_index_to_instance(
return instance; return instance;
} }
static long fsize( static long fsize(FILE *pFile)
FILE * pFile)
{ {
long size = 0; long size = 0;
long origin = 0; long origin = 0;
@@ -183,8 +168,7 @@ static long fsize(
return (size); return (size);
} }
unsigned bacfile_file_size( unsigned bacfile_file_size(uint32_t object_instance)
uint32_t object_instance)
{ {
char *pFilename = NULL; char *pFilename = NULL;
FILE *pFile = NULL; FILE *pFile = NULL;
@@ -203,8 +187,7 @@ unsigned bacfile_file_size(
} }
/* return the number of bytes used, or -1 on error */ /* return the number of bytes used, or -1 on error */
int bacfile_read_property( int bacfile_read_property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
char text_string[32] = {""}; char text_string[32] = {""};
@@ -220,8 +203,7 @@ int bacfile_read_property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(&apdu[0], OBJECT_FILE,
encode_application_object_id(&apdu[0], OBJECT_FILE,
rpdata->object_instance); rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -246,9 +228,8 @@ int bacfile_read_property(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_FILE_SIZE: case PROP_FILE_SIZE:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], bacfile_file_size(rpdata->object_instance));
bacfile_file_size(rpdata->object_instance));
break; break;
case PROP_MODIFICATION_DATE: case PROP_MODIFICATION_DATE:
/* FIXME: get the actual value instead of April Fool's Day */ /* FIXME: get the actual value instead of April Fool's Day */
@@ -280,9 +261,8 @@ int bacfile_read_property(
apdu_len = encode_application_boolean(&apdu[0], true); apdu_len = encode_application_boolean(&apdu[0], true);
break; break;
case PROP_FILE_ACCESS_METHOD: case PROP_FILE_ACCESS_METHOD:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], FILE_RECORD_AND_STREAM_ACCESS);
FILE_RECORD_AND_STREAM_ACCESS);
break; break;
default: default:
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -295,8 +275,7 @@ int bacfile_read_property(
} }
/* returns true if successful */ /* returns true if successful */
bool bacfile_write_property( bool bacfile_write_property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -314,8 +293,7 @@ bool bacfile_write_property(
return false; return false;
} }
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -375,8 +353,7 @@ bool bacfile_write_property(
return status; return status;
} }
uint32_t bacfile_instance( uint32_t bacfile_instance(char *filename)
char *filename)
{ {
uint32_t index = 0; uint32_t index = 0;
uint32_t instance = BACNET_MAX_INSTANCE + 1; uint32_t instance = BACNET_MAX_INSTANCE + 1;
@@ -399,8 +376,7 @@ uint32_t bacfile_instance(
/* Another way would be to store the */ /* Another way would be to store the */
/* invokeID and file instance in a list or table */ /* invokeID and file instance in a list or table */
/* when the request was sent */ /* when the request was sent */
uint32_t bacfile_instance_from_tsm( uint32_t bacfile_instance_from_tsm(uint8_t invokeID)
uint8_t invokeID)
{ {
BACNET_NPDU_DATA npdu_data = {0}; /* dummy for getting npdu length */ BACNET_NPDU_DATA npdu_data = {0}; /* dummy for getting npdu length */
BACNET_CONFIRMED_SERVICE_DATA service_data = {0}; BACNET_CONFIRMED_SERVICE_DATA service_data = {0};
@@ -415,19 +391,17 @@ uint32_t bacfile_instance_from_tsm(
uint32_t object_instance = BACNET_MAX_INSTANCE + 1; /* return value */ uint32_t object_instance = BACNET_MAX_INSTANCE + 1; /* return value */
bool found = false; bool found = false;
found = found = tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0],
tsm_get_transaction_pdu(invokeID, &dest, &npdu_data, &apdu[0],
&apdu_len); &apdu_len);
if (found) { if (found) {
if (!npdu_data.network_layer_message && npdu_data.data_expecting_reply if (!npdu_data.network_layer_message &&
&& (apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) { npdu_data.data_expecting_reply &&
len = (apdu[0] == PDU_TYPE_CONFIRMED_SERVICE_REQUEST)) {
apdu_decode_confirmed_service_request(&apdu[0], apdu_len, len = apdu_decode_confirmed_service_request(
&service_data, &service_choice, &service_request, &apdu[0], apdu_len, &service_data, &service_choice,
&service_request_len); &service_request, &service_request_len);
if (service_choice == SERVICE_CONFIRMED_ATOMIC_READ_FILE) { if (service_choice == SERVICE_CONFIRMED_ATOMIC_READ_FILE) {
len = len = arf_decode_service_request(service_request,
arf_decode_service_request(service_request,
service_request_len, &data); service_request_len, &data);
if (len > 0) { if (len > 0) {
if (data.object_type == OBJECT_FILE) if (data.object_type == OBJECT_FILE)
@@ -441,8 +415,7 @@ uint32_t bacfile_instance_from_tsm(
} }
#endif #endif
bool bacfile_read_stream_data( bool bacfile_read_stream_data(BACNET_ATOMIC_READ_FILE_DATA *data)
BACNET_ATOMIC_READ_FILE_DATA * data)
{ {
char *pFilename = NULL; char *pFilename = NULL;
bool found = false; bool found = false;
@@ -455,8 +428,7 @@ bool bacfile_read_stream_data(
pFile = fopen(pFilename, "rb"); pFile = fopen(pFilename, "rb");
if (pFile) { if (pFile) {
(void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET); (void)fseek(pFile, data->type.stream.fileStartPosition, SEEK_SET);
len = len = fread(octetstring_value(&data->fileData[0]), 1,
fread(octetstring_value(&data->fileData[0]), 1,
data->type.stream.requestedOctetCount, pFile); data->type.stream.requestedOctetCount, pFile);
if (len < data->type.stream.requestedOctetCount) if (len < data->type.stream.requestedOctetCount)
data->endOfFile = true; data->endOfFile = true;
@@ -476,8 +448,7 @@ bool bacfile_read_stream_data(
return found; return found;
} }
bool bacfile_write_stream_data( bool bacfile_write_stream_data(BACNET_ATOMIC_WRITE_FILE_DATA *data)
BACNET_ATOMIC_WRITE_FILE_DATA * data)
{ {
char *pFilename = NULL; char *pFilename = NULL;
bool found = false; bool found = false;
@@ -514,8 +485,7 @@ bool bacfile_write_stream_data(
return found; return found;
} }
bool bacfile_write_record_data( bool bacfile_write_record_data(BACNET_ATOMIC_WRITE_FILE_DATA *data)
BACNET_ATOMIC_WRITE_FILE_DATA * data)
{ {
char *pFilename = NULL; char *pFilename = NULL;
bool found = false; bool found = false;
@@ -542,7 +512,8 @@ bool bacfile_write_record_data(
if (pFile) { if (pFile) {
if ((data->type.record.fileStartRecord != -1) && if ((data->type.record.fileStartRecord != -1) &&
(data->type.record.fileStartRecord > 0)) { (data->type.record.fileStartRecord > 0)) {
for (i = 0; i < (uint32_t)data->type.record.fileStartRecord; i++) { for (i = 0; i < (uint32_t)data->type.record.fileStartRecord;
i++) {
pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile); pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile);
if ((pData == NULL) || feof(pFile)) { if ((pData == NULL) || feof(pFile)) {
break; break;
@@ -563,8 +534,7 @@ bool bacfile_write_record_data(
return found; return found;
} }
bool bacfile_read_ack_stream_data( bool bacfile_read_ack_stream_data(uint32_t instance,
uint32_t instance,
BACNET_ATOMIC_READ_FILE_DATA *data) BACNET_ATOMIC_READ_FILE_DATA *data)
{ {
bool found = false; bool found = false;
@@ -591,8 +561,7 @@ bool bacfile_read_ack_stream_data(
return found; return found;
} }
bool bacfile_read_ack_record_data( bool bacfile_read_ack_record_data(uint32_t instance,
uint32_t instance,
BACNET_ATOMIC_READ_FILE_DATA *data) BACNET_ATOMIC_READ_FILE_DATA *data)
{ {
bool found = false; bool found = false;
@@ -608,7 +577,8 @@ bool bacfile_read_ack_record_data(
pFile = fopen(pFilename, "rb"); pFile = fopen(pFilename, "rb");
if (pFile) { if (pFile) {
if (data->type.record.fileStartRecord > 0) { if (data->type.record.fileStartRecord > 0) {
for (i = 0; i < (uint32_t)data->type.record.fileStartRecord; i++) { for (i = 0; i < (uint32_t)data->type.record.fileStartRecord;
i++) {
pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile); pData = fgets(&dummy_data[0], sizeof(dummy_data), pFile);
if ((pData == NULL) || feof(pFile)) { if ((pData == NULL) || feof(pFile)) {
break; break;
@@ -620,8 +590,8 @@ bool bacfile_read_ack_record_data(
octetstring_length(&data->fileData[i]), 1, octetstring_length(&data->fileData[i]), 1,
pFile) != 1) { pFile) != 1) {
#if PRINT_ENABLED #if PRINT_ENABLED
fprintf(stderr, "Failed to write to %s (%lu)!\n", fprintf(stderr, "Failed to write to %s (%lu)!\n", pFilename,
pFilename, (unsigned long) instance); (unsigned long)instance);
#endif #endif
} }
} }
@@ -632,7 +602,6 @@ bool bacfile_read_ack_record_data(
return found; return found;
} }
void bacfile_init( void bacfile_init(void)
void)
{ {
} }
+40 -78
View File
@@ -54,29 +54,15 @@ static BACNET_POLARITY Polarity[MAX_BINARY_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* 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_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_OBJECT_NAME, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_OBJECT_TYPE, PROP_OUT_OF_SERVICE, PROP_POLARITY, -1};
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_POLARITY,
-1
};
static const int Binary_Input_Properties_Optional[] = { static const int Binary_Input_Properties_Optional[] = {PROP_DESCRIPTION, -1};
PROP_DESCRIPTION,
-1
};
static const int Binary_Input_Properties_Proprietary[] = { static const int Binary_Input_Properties_Proprietary[] = {-1};
-1
};
void Binary_Input_Property_Lists( void Binary_Input_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) { if (pRequired) {
@@ -95,8 +81,7 @@ void Binary_Input_Property_Lists(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Binary_Input_Valid_Instance( bool Binary_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_INPUTS) { if (object_instance < MAX_BINARY_INPUTS) {
return true; return true;
@@ -107,8 +92,7 @@ bool Binary_Input_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Binary_Input_Count( unsigned Binary_Input_Count(void)
void)
{ {
return MAX_BINARY_INPUTS; return MAX_BINARY_INPUTS;
} }
@@ -116,14 +100,12 @@ unsigned Binary_Input_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Binary_Input_Index_To_Instance( uint32_t Binary_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
void Binary_Input_Init( void Binary_Input_Init(void)
void)
{ {
static bool initialized = false; static bool initialized = false;
unsigned i; unsigned i;
@@ -143,8 +125,7 @@ void Binary_Input_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Input_Instance_To_Index( unsigned Binary_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_INPUTS; unsigned index = MAX_BINARY_INPUTS;
@@ -155,8 +136,7 @@ unsigned Binary_Input_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Input_Present_Value( BACNET_BINARY_PV Binary_Input_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = BINARY_INACTIVE; BACNET_BINARY_PV value = BINARY_INACTIVE;
unsigned index = 0; unsigned index = 0;
@@ -176,8 +156,7 @@ BACNET_BINARY_PV Binary_Input_Present_Value(
return value; return value;
} }
bool Binary_Input_Out_Of_Service( bool Binary_Input_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
bool value = false; bool value = false;
unsigned index = 0; unsigned index = 0;
@@ -190,8 +169,7 @@ bool Binary_Input_Out_Of_Service(
return value; return value;
} }
bool Binary_Input_Change_Of_Value( bool Binary_Input_Change_Of_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
bool status = false; bool status = false;
unsigned index; unsigned index;
@@ -204,8 +182,7 @@ bool Binary_Input_Change_Of_Value(
return status; return status;
} }
void Binary_Input_Change_Of_Value_Clear( void Binary_Input_Change_Of_Value_Clear(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index; unsigned index;
@@ -225,8 +202,7 @@ void Binary_Input_Change_Of_Value_Clear(
* *
* @return true if the value list is encoded * @return true if the value list is encoded
*/ */
bool Binary_Input_Encode_Value_List( bool Binary_Input_Encode_Value_List(uint32_t object_instance,
uint32_t object_instance,
BACNET_PROPERTY_VALUE *value_list) BACNET_PROPERTY_VALUE *value_list)
{ {
bool status = false; bool status = false;
@@ -251,8 +227,8 @@ bool Binary_Input_Encode_Value_List(
bitstring_init(&value_list->value.type.Bit_String); bitstring_init(&value_list->value.type.Bit_String);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_IN_ALARM, false); STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String, STATUS_FLAG_FAULT,
STATUS_FLAG_FAULT, false); false);
bitstring_set_bit(&value_list->value.type.Bit_String, bitstring_set_bit(&value_list->value.type.Bit_String,
STATUS_FLAG_OVERRIDDEN, false); STATUS_FLAG_OVERRIDDEN, false);
if (Binary_Input_Out_Of_Service(object_instance)) { if (Binary_Input_Out_Of_Service(object_instance)) {
@@ -270,8 +246,7 @@ bool Binary_Input_Encode_Value_List(
return status; return status;
} }
bool Binary_Input_Present_Value_Set( bool Binary_Input_Present_Value_Set(uint32_t object_instance,
uint32_t object_instance,
BACNET_BINARY_PV value) BACNET_BINARY_PV value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -296,9 +271,7 @@ bool Binary_Input_Present_Value_Set(
return status; return status;
} }
void Binary_Input_Out_Of_Service_Set( void Binary_Input_Out_Of_Service_Set(uint32_t object_instance, bool value)
uint32_t object_instance,
bool value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -313,8 +286,7 @@ void Binary_Input_Out_Of_Service_Set(
return; return;
} }
bool Binary_Input_Object_Name( bool Binary_Input_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -331,8 +303,7 @@ bool Binary_Input_Object_Name(
return status; return status;
} }
BACNET_POLARITY Binary_Input_Polarity( BACNET_POLARITY Binary_Input_Polarity(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_POLARITY polarity = POLARITY_NORMAL; BACNET_POLARITY polarity = POLARITY_NORMAL;
unsigned index = 0; unsigned index = 0;
@@ -345,8 +316,7 @@ BACNET_POLARITY Binary_Input_Polarity(
return polarity; return polarity;
} }
bool Binary_Input_Polarity_Set( bool Binary_Input_Polarity_Set(uint32_t object_instance,
uint32_t object_instance,
BACNET_POLARITY polarity) BACNET_POLARITY polarity)
{ {
bool status = false; bool status = false;
@@ -362,8 +332,7 @@ bool Binary_Input_Polarity_Set(
/* return apdu length, or BACNET_STATUS_ERROR on error */ /* return apdu length, or BACNET_STATUS_ERROR on error */
/* assumption - object already exists, and has been bounds checked */ /* assumption - object already exists, and has been bounds checked */
int Binary_Input_Read_Property( int Binary_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -378,9 +347,8 @@ int Binary_Input_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_INPUT, &apdu[0], OBJECT_BINARY_INPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
@@ -395,9 +363,8 @@ int Binary_Input_Read_Property(
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
/* note: you need to look up the actual value */ /* note: you need to look up the actual value */
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Binary_Input_Present_Value(rpdata->object_instance));
Binary_Input_Present_Value(rpdata->object_instance));
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
/* note: see the details in the standard on how to use these */ /* note: see the details in the standard on how to use these */
@@ -419,9 +386,8 @@ int Binary_Input_Read_Property(
apdu_len = encode_application_boolean(&apdu[0], state); apdu_len = encode_application_boolean(&apdu[0], state);
break; break;
case PROP_POLARITY: case PROP_POLARITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Binary_Input_Polarity(rpdata->object_instance));
Binary_Input_Polarity(rpdata->object_instance));
break; break;
default: default:
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -440,16 +406,14 @@ int Binary_Input_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Input_Write_Property( bool Binary_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -471,7 +435,8 @@ bool Binary_Input_Write_Property(
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if (value.type.Enumerated <= MAX_BINARY_PV) { if (value.type.Enumerated <= MAX_BINARY_PV) {
Binary_Input_Present_Value_Set(wp_data->object_instance, Binary_Input_Present_Value_Set(
wp_data->object_instance,
(BACNET_BINARY_PV)value.type.Enumerated); (BACNET_BINARY_PV)value.type.Enumerated);
} else { } else {
status = false; status = false;
@@ -495,7 +460,8 @@ bool Binary_Input_Write_Property(
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if (value.type.Enumerated < MAX_POLARITY) { if (value.type.Enumerated < MAX_POLARITY) {
Binary_Input_Polarity_Set(wp_data->object_instance, Binary_Input_Polarity_Set(
wp_data->object_instance,
(BACNET_POLARITY)value.type.Enumerated); (BACNET_POLARITY)value.type.Enumerated);
} else { } else {
status = false; status = false;
@@ -527,10 +493,8 @@ bool Binary_Input_Write_Property(
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -541,8 +505,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testBinaryInput( void testBinaryInput(Test *pTest)
Test * pTest)
{ {
BACNET_READ_PROPERTY_DATA rpdata; BACNET_READ_PROPERTY_DATA rpdata;
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
@@ -571,8 +534,7 @@ void testBinaryInput(
} }
#ifdef TEST_BINARY_INPUT #ifdef TEST_BINARY_INPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+46 -75
View File
@@ -46,15 +46,14 @@
/* the Relinquish Default value */ /* the Relinquish Default value */
#define RELINQUISH_DEFAULT BINARY_INACTIVE #define RELINQUISH_DEFAULT BINARY_INACTIVE
/* Here is our Priority Array.*/ /* Here is our Priority Array.*/
static BACNET_BINARY_PV static BACNET_BINARY_PV Binary_Output_Level[MAX_BINARY_OUTPUTS]
Binary_Output_Level[MAX_BINARY_OUTPUTS][BACNET_MAX_PRIORITY]; [BACNET_MAX_PRIORITY];
/* Writable out-of-service allows others to play with our Present Value */ /* Writable out-of-service allows others to play with our Present Value */
/* without changing the physical output */ /* without changing the physical output */
static bool Out_Of_Service[MAX_BINARY_OUTPUTS]; static bool Out_Of_Service[MAX_BINARY_OUTPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* 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_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
@@ -64,23 +63,14 @@ static const int Binary_Output_Properties_Required[] = {
PROP_POLARITY, PROP_POLARITY,
PROP_PRIORITY_ARRAY, PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT, PROP_RELINQUISH_DEFAULT,
-1 -1};
};
static const int Binary_Output_Properties_Optional[] = { static const int Binary_Output_Properties_Optional[] = {
PROP_DESCRIPTION, PROP_DESCRIPTION, PROP_ACTIVE_TEXT, PROP_INACTIVE_TEXT, -1};
PROP_ACTIVE_TEXT,
PROP_INACTIVE_TEXT,
-1
};
static const int Binary_Output_Properties_Proprietary[] = { static const int Binary_Output_Properties_Proprietary[] = {-1};
-1
};
void Binary_Output_Property_Lists( void Binary_Output_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -93,8 +83,7 @@ void Binary_Output_Property_Lists(
return; return;
} }
void Binary_Output_Init( void Binary_Output_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
static bool initialized = false; static bool initialized = false;
@@ -116,8 +105,7 @@ void Binary_Output_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Binary_Output_Valid_Instance( bool Binary_Output_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_OUTPUTS) if (object_instance < MAX_BINARY_OUTPUTS)
return true; return true;
@@ -127,8 +115,7 @@ bool Binary_Output_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Binary_Output_Count( unsigned Binary_Output_Count(void)
void)
{ {
return MAX_BINARY_OUTPUTS; return MAX_BINARY_OUTPUTS;
} }
@@ -136,8 +123,7 @@ unsigned Binary_Output_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Binary_Output_Index_To_Instance( uint32_t Binary_Output_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -145,8 +131,7 @@ uint32_t Binary_Output_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Output_Instance_To_Index( unsigned Binary_Output_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_OUTPUTS; unsigned index = MAX_BINARY_OUTPUTS;
@@ -156,8 +141,7 @@ unsigned Binary_Output_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Output_Present_Value( BACNET_BINARY_PV Binary_Output_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = RELINQUISH_DEFAULT; BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0; unsigned index = 0;
@@ -176,8 +160,7 @@ BACNET_BINARY_PV Binary_Output_Present_Value(
return value; return value;
} }
bool Binary_Output_Out_Of_Service( bool Binary_Output_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
bool value = false; bool value = false;
unsigned index = 0; unsigned index = 0;
@@ -191,8 +174,7 @@ bool Binary_Output_Out_Of_Service(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Binary_Output_Object_Name( bool Binary_Output_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -208,8 +190,7 @@ bool Binary_Output_Object_Name(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Binary_Output_Read_Property( int Binary_Output_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -229,9 +210,8 @@ int Binary_Output_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_OUTPUT, &apdu[0], OBJECT_BINARY_OUTPUT, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
@@ -289,8 +269,7 @@ int Binary_Output_Read_Property(
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
else { else {
present_value = Binary_Output_Level[object_index][i]; present_value = Binary_Output_Level[object_index][i];
len = len = encode_application_enumerated(&apdu[apdu_len],
encode_application_enumerated(&apdu[apdu_len],
present_value); present_value);
} }
/* add it if we have room */ /* add it if we have room */
@@ -311,11 +290,11 @@ int Binary_Output_Read_Property(
1] == BINARY_NULL) 1] == BINARY_NULL)
apdu_len = encode_application_null(&apdu[apdu_len]); apdu_len = encode_application_null(&apdu[apdu_len]);
else { else {
present_value = Binary_Output_Level[object_index] present_value =
Binary_Output_Level[object_index]
[rpdata->array_index - 1]; [rpdata->array_index - 1];
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len], present_value);
present_value);
} }
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -357,8 +336,7 @@ int Binary_Output_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Output_Write_Property( bool Binary_Output_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -368,8 +346,7 @@ bool Binary_Output_Write_Property(
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -396,16 +373,16 @@ bool Binary_Output_Write_Property(
(priority != 6 /* reserved */) && (priority != 6 /* reserved */) &&
(value.type.Enumerated <= MAX_BINARY_PV)) { (value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV)value.type.Enumerated; level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index = object_index = Binary_Output_Instance_To_Index(
Binary_Output_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
Binary_Output_Level[object_index][priority] = level; Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we /* Note: you could set the physical output here if we
are the highest priority. are the highest priority.
However, if Out of Service is TRUE, then don't set the However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
status = true; status = true;
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
@@ -418,24 +395,24 @@ bool Binary_Output_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, &wp_data->error_class,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_code);
if (status) { if (status) {
level = BINARY_NULL; level = BINARY_NULL;
object_index = object_index = Binary_Output_Instance_To_Index(
Binary_Output_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority = wp_data->priority; priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) { if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--; priority--;
Binary_Output_Level[object_index][priority] = level; Binary_Output_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next /* Note: you could set the physical output here to the
highest priority, or to the relinquish default if no next highest priority, or to the relinquish default
priorities are set. if no priorities are set. However, if Out of Service
However, if Out of Service is TRUE, then don't set the is TRUE, then don't set the physical output. This
physical output. This comment may apply to the comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
} else { } else {
status = false; status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -451,8 +428,7 @@ bool Binary_Output_Write_Property(
if (status) { if (status) {
object_index = object_index =
Binary_Output_Instance_To_Index(wp_data->object_instance); Binary_Output_Instance_To_Index(wp_data->object_instance);
Out_Of_Service[object_index] = Out_Of_Service[object_index] = value.type.Boolean;
value.type.Boolean;
} }
break; break;
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
@@ -478,16 +454,13 @@ bool Binary_Output_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -498,8 +471,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testBinaryOutput( void testBinaryOutput(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -528,8 +500,7 @@ void testBinaryOutput(
} }
#ifdef TEST_BINARY_OUTPUT #ifdef TEST_BINARY_OUTPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+49 -84
View File
@@ -46,38 +46,25 @@
/* the Relinquish Default value */ /* the Relinquish Default value */
#define RELINQUISH_DEFAULT BINARY_INACTIVE #define RELINQUISH_DEFAULT BINARY_INACTIVE
/* Here is our Priority Array.*/ /* Here is our Priority Array.*/
static BACNET_BINARY_PV static BACNET_BINARY_PV Binary_Value_Level[MAX_BINARY_VALUES]
Binary_Value_Level[MAX_BINARY_VALUES][BACNET_MAX_PRIORITY]; [BACNET_MAX_PRIORITY];
/* Writable out-of-service allows others to play with our Present Value */ /* Writable out-of-service allows others to play with our Present Value */
/* without changing the physical output */ /* without changing the physical output */
static bool Out_Of_Service[MAX_BINARY_VALUES]; static bool Out_Of_Service[MAX_BINARY_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* 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_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
PROP_OBJECT_TYPE, PROP_STATUS_FLAGS, PROP_EVENT_STATE,
PROP_PRESENT_VALUE, PROP_OUT_OF_SERVICE, -1};
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
-1
};
static const int Binary_Value_Properties_Optional[] = { static const int Binary_Value_Properties_Optional[] = {
PROP_DESCRIPTION, PROP_DESCRIPTION, PROP_PRIORITY_ARRAY, PROP_RELINQUISH_DEFAULT, -1};
PROP_PRIORITY_ARRAY,
PROP_RELINQUISH_DEFAULT,
-1
};
static const int Binary_Value_Properties_Proprietary[] = { static const int Binary_Value_Properties_Proprietary[] = {-1};
-1
};
void Binary_Value_Property_Lists( void Binary_Value_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -90,8 +77,7 @@ void Binary_Value_Property_Lists(
return; return;
} }
void Binary_Value_Init( void Binary_Value_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
static bool initialized = false; static bool initialized = false;
@@ -113,8 +99,7 @@ void Binary_Value_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Binary_Value_Valid_Instance( bool Binary_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_BINARY_VALUES) if (object_instance < MAX_BINARY_VALUES)
return true; return true;
@@ -124,8 +109,7 @@ bool Binary_Value_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Binary_Value_Count( unsigned Binary_Value_Count(void)
void)
{ {
return MAX_BINARY_VALUES; return MAX_BINARY_VALUES;
} }
@@ -133,8 +117,7 @@ unsigned Binary_Value_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Binary_Value_Index_To_Instance( uint32_t Binary_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -142,8 +125,7 @@ uint32_t Binary_Value_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Binary_Value_Instance_To_Index( unsigned Binary_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_BINARY_VALUES; unsigned index = MAX_BINARY_VALUES;
@@ -153,8 +135,7 @@ unsigned Binary_Value_Instance_To_Index(
return index; return index;
} }
BACNET_BINARY_PV Binary_Value_Present_Value( BACNET_BINARY_PV Binary_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_BINARY_PV value = RELINQUISH_DEFAULT; BACNET_BINARY_PV value = RELINQUISH_DEFAULT;
unsigned index = 0; unsigned index = 0;
@@ -174,8 +155,7 @@ BACNET_BINARY_PV Binary_Value_Present_Value(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Binary_Value_Object_Name( bool Binary_Value_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -190,8 +170,7 @@ bool Binary_Value_Object_Name(
return status; return status;
} }
bool Binary_Value_Out_Of_Service( bool Binary_Value_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned index = 0; unsigned index = 0;
bool oos_flag = false; bool oos_flag = false;
@@ -204,9 +183,7 @@ bool Binary_Value_Out_Of_Service(
return oos_flag; return oos_flag;
} }
void Binary_Value_Out_Of_Service_Set( void Binary_Value_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
uint32_t instance,
bool oos_flag)
{ {
unsigned index = 0; unsigned index = 0;
@@ -217,8 +194,7 @@ void Binary_Value_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Binary_Value_Read_Property( int Binary_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -237,9 +213,8 @@ int Binary_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_BINARY_VALUE, &apdu[0], OBJECT_BINARY_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
@@ -254,8 +229,7 @@ int Binary_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE); encode_application_enumerated(&apdu[0], OBJECT_BINARY_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
present_value = present_value = Binary_Value_Present_Value(rpdata->object_instance);
Binary_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_enumerated(&apdu[0], present_value); apdu_len = encode_application_enumerated(&apdu[0], present_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -293,8 +267,7 @@ int Binary_Value_Read_Property(
len = encode_application_null(&apdu[apdu_len]); len = encode_application_null(&apdu[apdu_len]);
else { else {
present_value = Binary_Value_Level[object_index][i]; present_value = Binary_Value_Level[object_index][i];
len = len = encode_application_enumerated(&apdu[apdu_len],
encode_application_enumerated(&apdu[apdu_len],
present_value); present_value);
} }
/* add it if we have room */ /* add it if we have room */
@@ -311,15 +284,14 @@ int Binary_Value_Read_Property(
object_index = object_index =
Binary_Value_Instance_To_Index(rpdata->object_instance); Binary_Value_Instance_To_Index(rpdata->object_instance);
if (rpdata->array_index <= BACNET_MAX_PRIORITY) { if (rpdata->array_index <= BACNET_MAX_PRIORITY) {
if (Binary_Value_Level[object_index][rpdata->array_index] if (Binary_Value_Level[object_index][rpdata->array_index] ==
== BINARY_NULL) BINARY_NULL)
apdu_len = encode_application_null(&apdu[apdu_len]); apdu_len = encode_application_null(&apdu[apdu_len]);
else { else {
present_value = Binary_Value_Level[object_index] present_value = Binary_Value_Level[object_index]
[rpdata->array_index]; [rpdata->array_index];
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[apdu_len], &apdu[apdu_len], present_value);
present_value);
} }
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -350,8 +322,7 @@ int Binary_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Binary_Value_Write_Property( bool Binary_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
@@ -361,8 +332,7 @@ bool Binary_Value_Write_Property(
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -389,16 +359,16 @@ bool Binary_Value_Write_Property(
(priority != 6 /* reserved */) && (priority != 6 /* reserved */) &&
(value.type.Enumerated <= MAX_BINARY_PV)) { (value.type.Enumerated <= MAX_BINARY_PV)) {
level = (BACNET_BINARY_PV)value.type.Enumerated; level = (BACNET_BINARY_PV)value.type.Enumerated;
object_index = object_index = Binary_Value_Instance_To_Index(
Binary_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority--; priority--;
Binary_Value_Level[object_index][priority] = level; Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here if we /* Note: you could set the physical output here if we
are the highest priority. are the highest priority.
However, if Out of Service is TRUE, then don't set the However, if Out of Service is TRUE, then don't set the
physical output. This comment may apply to the physical output. This comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
status = true; status = true;
} else if (priority == 6) { } else if (priority == 6) {
/* Command priority 6 is reserved for use by Minimum On/Off /* Command priority 6 is reserved for use by Minimum On/Off
@@ -411,24 +381,24 @@ bool Binary_Value_Write_Property(
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} }
} else { } else {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_NULL, &wp_data->error_class,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_code);
if (status) { if (status) {
level = BINARY_NULL; level = BINARY_NULL;
object_index = object_index = Binary_Value_Instance_To_Index(
Binary_Value_Instance_To_Index wp_data->object_instance);
(wp_data->object_instance);
priority = wp_data->priority; priority = wp_data->priority;
if (priority && (priority <= BACNET_MAX_PRIORITY)) { if (priority && (priority <= BACNET_MAX_PRIORITY)) {
priority--; priority--;
Binary_Value_Level[object_index][priority] = level; Binary_Value_Level[object_index][priority] = level;
/* Note: you could set the physical output here to the next /* Note: you could set the physical output here to the
highest priority, or to the relinquish default if no next highest priority, or to the relinquish default
priorities are set. if no priorities are set. However, if Out of Service
However, if Out of Service is TRUE, then don't set the is TRUE, then don't set the physical output. This
physical output. This comment may apply to the comment may apply to the
main loop (i.e. check out of service before changing output) */ main loop (i.e. check out of service before changing
output) */
} else { } else {
status = false; status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -466,16 +436,13 @@ bool Binary_Value_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -486,8 +453,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testBinary_Value( void testBinary_Value(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -516,8 +482,7 @@ void testBinary_Value(
} }
#ifdef TEST_BINARY_VALUE #ifdef TEST_BINARY_VALUE
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+152 -209
View File
@@ -7,8 +7,8 @@
* @section DESCRIPTION * @section DESCRIPTION
* *
* The Channel object is a command object without a priority array, and the * The Channel object is a command object without a priority array, and the
* present-value property uses a priority array and a single precision floating point * present-value property uses a priority array and a single precision floating
* data type. * point data type.
* *
* @section LICENSE * @section LICENSE
* *
@@ -89,16 +89,11 @@ static const int Channel_Properties_Required[] = {
PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES, PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES,
PROP_CHANNEL_NUMBER, PROP_CHANNEL_NUMBER,
PROP_CONTROL_GROUPS, PROP_CONTROL_GROUPS,
-1 -1};
};
static const int Channel_Properties_Optional[] = { static const int Channel_Properties_Optional[] = {-1};
-1
};
static const int Channel_Properties_Proprietary[] = { static const int Channel_Properties_Proprietary[] = {-1};
-1
};
/** /**
* Returns the list of required, optional, and proprietary properties. * Returns the list of required, optional, and proprietary properties.
@@ -111,8 +106,7 @@ static const int Channel_Properties_Proprietary[] = {
* @param pProprietary - pointer to list of int terminated by -1, of * @param pProprietary - pointer to list of int terminated by -1, of
* BACnet proprietary properties for this object. * BACnet proprietary properties for this object.
*/ */
void Channel_Property_Lists(const int **pRequired, void Channel_Property_Lists(const int **pRequired, const int **pOptional,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -352,9 +346,8 @@ unsigned Channel_Reference_List_Member_Count(uint32_t object_instance)
* *
* @return pointer to member element or NULL if not found * @return pointer to member element or NULL if not found
*/ */
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE * BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *Channel_Reference_List_Member_Element(
Channel_Reference_List_Member_Element(uint32_t object_instance, uint32_t object_instance, unsigned array_index)
unsigned array_index)
{ {
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL;
unsigned count = 0; unsigned count = 0;
@@ -385,8 +378,8 @@ Channel_Reference_List_Member_Element(uint32_t object_instance,
* *
* @return pointer to member element or NULL if not found * @return pointer to member element or NULL if not found
*/ */
bool Channel_Reference_List_Member_Element_Set(uint32_t object_instance, bool Channel_Reference_List_Member_Element_Set(
unsigned array_index, uint32_t object_instance, unsigned array_index,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMemberSrc) BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMemberSrc)
{ {
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL;
@@ -423,7 +416,8 @@ bool Channel_Reference_List_Member_Element_Set(uint32_t object_instance,
* @return array_index - 1-based array index value for added element, or * @return array_index - 1-based array index value for added element, or
* zero if not added * zero if not added
*/ */
unsigned Channel_Reference_List_Member_Element_Add(uint32_t object_instance, unsigned Channel_Reference_List_Member_Element_Add(
uint32_t object_instance,
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMemberSrc) BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMemberSrc)
{ {
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE *pMember = NULL;
@@ -463,11 +457,8 @@ unsigned Channel_Reference_List_Member_Element_Add(uint32_t object_instance,
* zero if not added * zero if not added
*/ */
unsigned Channel_Reference_List_Member_Local_Add( unsigned Channel_Reference_List_Member_Local_Add(
uint32_t object_instance, uint32_t object_instance, uint16_t type, uint32_t instance,
uint16_t type, BACNET_PROPERTY_ID propertyIdentifier, uint32_t arrayIndex)
uint32_t instance,
BACNET_PROPERTY_ID propertyIdentifier,
uint32_t arrayIndex)
{ {
BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE member = {{0}}; BACNET_DEVICE_OBJECT_PROPERTY_REFERENCE member = {{0}};
@@ -478,9 +469,7 @@ unsigned Channel_Reference_List_Member_Local_Add(
member.deviceIdentifier.type = OBJECT_DEVICE; member.deviceIdentifier.type = OBJECT_DEVICE;
member.deviceIdentifier.instance = Device_Object_Instance_Number(); member.deviceIdentifier.instance = Device_Object_Instance_Number();
return Channel_Reference_List_Member_Element_Add( return Channel_Reference_List_Member_Element_Add(object_instance, &member);
object_instance,
&member);
} }
/** /**
@@ -491,16 +480,14 @@ unsigned Channel_Reference_List_Member_Local_Add(
* *
* @return group number in the array * @return group number in the array
*/ */
uint16_t Channel_Control_Groups_Element( uint16_t Channel_Control_Groups_Element(uint32_t object_instance,
uint32_t object_instance,
int32_t array_index) int32_t array_index)
{ {
unsigned index = 0; unsigned index = 0;
uint16_t value = 0; uint16_t value = 0;
index = Channel_Instance_To_Index(object_instance); index = Channel_Instance_To_Index(object_instance);
if ((index < BACNET_CHANNELS_MAX) && if ((index < BACNET_CHANNELS_MAX) && (array_index > 0) &&
(array_index > 0) &&
(array_index <= CONTROL_GROUPS_MAX)) { (array_index <= CONTROL_GROUPS_MAX)) {
array_index--; array_index--;
value = Channel[index].Control_Groups[array_index]; value = Channel[index].Control_Groups[array_index];
@@ -518,17 +505,14 @@ uint16_t Channel_Control_Groups_Element(
* *
* @return true if parameters are value and control group is set * @return true if parameters are value and control group is set
*/ */
bool Channel_Control_Groups_Element_Set( bool Channel_Control_Groups_Element_Set(uint32_t object_instance,
uint32_t object_instance, int32_t array_index, uint16_t value)
int32_t array_index,
uint16_t value)
{ {
bool status = false; bool status = false;
unsigned index = 0; unsigned index = 0;
index = Channel_Instance_To_Index(object_instance); index = Channel_Instance_To_Index(object_instance);
if ((index < BACNET_CHANNELS_MAX) && if ((index < BACNET_CHANNELS_MAX) && (array_index > 0) &&
(array_index > 0) &&
(array_index <= CONTROL_GROUPS_MAX)) { (array_index <= CONTROL_GROUPS_MAX)) {
array_index--; array_index--;
Channel[index].Control_Groups[array_index] = value; Channel[index].Control_Groups[array_index] = value;
@@ -599,8 +583,7 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE * cvalue,
#if defined(BACAPP_OCTET_STRING) && defined(CHANNEL_OCTET_STRING) #if defined(BACAPP_OCTET_STRING) && defined(CHANNEL_OCTET_STRING)
case BACNET_APPLICATION_TAG_OCTET_STRING: case BACNET_APPLICATION_TAG_OCTET_STRING:
cvalue->tag = value->tag; cvalue->tag = value->tag;
octetstring_copy( octetstring_copy(&cvalue->type.Octet_String,
&cvalue->type.Octet_String,
&value->type.Octet_String); &value->type.Octet_String);
status = true; status = true;
break; break;
@@ -608,8 +591,7 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE * cvalue,
#if defined(BACAPP_CHARACTER_STRING) && defined(CHANNEL_CHARACTER_STRING) #if defined(BACAPP_CHARACTER_STRING) && defined(CHANNEL_CHARACTER_STRING)
case BACNET_APPLICATION_TAG_CHARACTER_STRING: case BACNET_APPLICATION_TAG_CHARACTER_STRING:
cvalue->tag = value->tag; cvalue->tag = value->tag;
characterstring_copy( characterstring_copy(&cvalue->type.Character_String,
&cvalue->type.Character_String,
&value->type.Character_String); &value->type.Character_String);
status = true; status = true;
break; break;
@@ -617,9 +599,7 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE * cvalue,
#if defined(BACAPP_BIT_STRING) && defined(CHANNEL_BIT_STRING) #if defined(BACAPP_BIT_STRING) && defined(CHANNEL_BIT_STRING)
case BACNET_APPLICATION_TAG_BIT_STRING: case BACNET_APPLICATION_TAG_BIT_STRING:
cvalue->tag = value->tag; cvalue->tag = value->tag;
bitstring_copy( bitstring_copy(&cvalue->type.Bit_String, &value->type.Bit_String);
&cvalue->type.Bit_String,
&value->type.Bit_String);
status = true; status = true;
break; break;
#endif #endif
@@ -633,9 +613,7 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE * cvalue,
#if defined(BACAPP_DATE) && defined(CHANNEL_DATE) #if defined(BACAPP_DATE) && defined(CHANNEL_DATE)
case BACNET_APPLICATION_TAG_DATE: case BACNET_APPLICATION_TAG_DATE:
cvalue->tag = value->tag; cvalue->tag = value->tag;
datetime_date_copy( datetime_date_copy(&cvalue->type.Date, &value->type.Date);
&cvalue->type.Date,
&value->type.Date);
apdu_len = encode_application_date(&apdu[0], &value->type.Date); apdu_len = encode_application_date(&apdu[0], &value->type.Date);
status = true; status = true;
break; break;
@@ -643,9 +621,7 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE * cvalue,
#if defined(BACAPP_TIME) && defined(CHANNEL_TIME) #if defined(BACAPP_TIME) && defined(CHANNEL_TIME)
case BACNET_APPLICATION_TAG_TIME: case BACNET_APPLICATION_TAG_TIME:
cvalue->tag = value->tag; cvalue->tag = value->tag;
datetime_time_copy( datetime_time_copy(&cvalue->type.Time, &value->type.Time);
&cvalue->type.Time,
&value->type.Time);
break; break;
#endif #endif
#if defined(BACAPP_OBJECT_ID) && defined(CHANNEL_OBJECT_ID) #if defined(BACAPP_OBJECT_ID) && defined(CHANNEL_OBJECT_ID)
@@ -659,8 +635,7 @@ bool Channel_Value_Copy(BACNET_CHANNEL_VALUE * cvalue,
#if defined(BACAPP_LIGHTING_COMMAND) && defined(CHANNEL_LIGHTING_COMMAND) #if defined(BACAPP_LIGHTING_COMMAND) && defined(CHANNEL_LIGHTING_COMMAND)
case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: case BACNET_APPLICATION_TAG_LIGHTING_COMMAND:
cvalue->tag = value->tag; cvalue->tag = value->tag;
lighting_command_copy( lighting_command_copy(&cvalue->type.Lighting_Command,
&cvalue->type.Lighting_Command,
&value->type.Lighting_Command); &value->type.Lighting_Command);
status = true; status = true;
break; break;
@@ -695,22 +670,20 @@ int Channel_Value_Encode(uint8_t *apdu, int apdu_max,
break; break;
#if defined(CHANNEL_BOOLEAN) #if defined(CHANNEL_BOOLEAN)
case BACNET_APPLICATION_TAG_BOOLEAN: case BACNET_APPLICATION_TAG_BOOLEAN:
apdu_len = encode_application_boolean(&apdu[0], apdu_len =
value->type.Boolean); encode_application_boolean(&apdu[0], value->type.Boolean);
break; break;
#endif #endif
#if defined(CHANNEL_UNSIGNED) #if defined(CHANNEL_UNSIGNED)
case BACNET_APPLICATION_TAG_UNSIGNED_INT: case BACNET_APPLICATION_TAG_UNSIGNED_INT:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], value->type.Unsigned_Int);
value->type.Unsigned_Int);
break; break;
#endif #endif
#if defined(CHANNEL_SIGNED) #if defined(CHANNEL_SIGNED)
case BACNET_APPLICATION_TAG_SIGNED_INT: case BACNET_APPLICATION_TAG_SIGNED_INT:
apdu_len = apdu_len =
encode_application_signed(&apdu[0], encode_application_signed(&apdu[0], value->type.Signed_Int);
value->type.Signed_Int);
break; break;
#endif #endif
#if defined(CHANNEL_REAL) #if defined(CHANNEL_REAL)
@@ -720,62 +693,53 @@ int Channel_Value_Encode(uint8_t *apdu, int apdu_max,
#endif #endif
#if defined(CHANNEL_DOUBLE) #if defined(CHANNEL_DOUBLE)
case BACNET_APPLICATION_TAG_DOUBLE: case BACNET_APPLICATION_TAG_DOUBLE:
apdu_len = apdu_len = encode_application_double(&apdu[0], value->type.Double);
encode_application_double(&apdu[0], value->type.Double);
break; break;
#endif #endif
#if defined(CHANNEL_OCTET_STRING) #if defined(CHANNEL_OCTET_STRING)
case BACNET_APPLICATION_TAG_OCTET_STRING: case BACNET_APPLICATION_TAG_OCTET_STRING:
apdu_len = apdu_len = encode_application_octet_string(
encode_application_octet_string(&apdu[0], &apdu[0], &value->type.Octet_String);
&value->type.Octet_String);
break; break;
#endif #endif
#if defined(CHANNEL_CHARACTER_STRING) #if defined(CHANNEL_CHARACTER_STRING)
case BACNET_APPLICATION_TAG_CHARACTER_STRING: case BACNET_APPLICATION_TAG_CHARACTER_STRING:
apdu_len = apdu_len = encode_application_character_string(
encode_application_character_string(&apdu[0], &apdu[0], &value->type.Character_String);
&value->type.Character_String);
break; break;
#endif #endif
#if defined(CHANNEL_BIT_STRING) #if defined(CHANNEL_BIT_STRING)
case BACNET_APPLICATION_TAG_BIT_STRING: case BACNET_APPLICATION_TAG_BIT_STRING:
apdu_len = apdu_len =
encode_application_bitstring(&apdu[0], encode_application_bitstring(&apdu[0], &value->type.Bit_String);
&value->type.Bit_String);
break; break;
#endif #endif
#if defined(CHANNEL_ENUMERATED) #if defined(CHANNEL_ENUMERATED)
case BACNET_APPLICATION_TAG_ENUMERATED: case BACNET_APPLICATION_TAG_ENUMERATED:
apdu_len = apdu_len =
encode_application_enumerated(&apdu[0], encode_application_enumerated(&apdu[0], value->type.Enumerated);
value->type.Enumerated);
break; break;
#endif #endif
#if defined(CHANNEL_DATE) #if defined(CHANNEL_DATE)
case BACNET_APPLICATION_TAG_DATE: case BACNET_APPLICATION_TAG_DATE:
apdu_len = apdu_len = encode_application_date(&apdu[0], &value->type.Date);
encode_application_date(&apdu[0], &value->type.Date);
break; break;
#endif #endif
#if defined(CHANNEL_TIME) #if defined(CHANNEL_TIME)
case BACNET_APPLICATION_TAG_TIME: case BACNET_APPLICATION_TAG_TIME:
apdu_len = apdu_len = encode_application_time(&apdu[0], &value->type.Time);
encode_application_time(&apdu[0], &value->type.Time);
break; break;
#endif #endif
#if defined(CHANNEL_OBJECT_ID) #if defined(CHANNEL_OBJECT_ID)
case BACNET_APPLICATION_TAG_OBJECT_ID: case BACNET_APPLICATION_TAG_OBJECT_ID:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], &apdu[0], (int)value->type.Object_Id.type,
(int) value->type.Object_Id.type,
value->type.Object_Id.instance); value->type.Object_Id.instance);
break; break;
#endif #endif
#if defined(CHANNEL_LIGHTING_COMMAND) #if defined(CHANNEL_LIGHTING_COMMAND)
case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: case BACNET_APPLICATION_TAG_LIGHTING_COMMAND:
apdu_len = apdu_len = lighting_command_encode(&apdu[0],
lighting_command_encode(&apdu[0],
&value->type.Lighting_Command); &value->type.Lighting_Command);
break; break;
#endif #endif
@@ -796,9 +760,7 @@ int Channel_Value_Encode(uint8_t *apdu, int apdu_max,
* *
* @return number of bytes in the APDU, or BACNET_STATUS_ERROR if error. * @return number of bytes in the APDU, or BACNET_STATUS_ERROR if error.
*/ */
int Channel_Coerce_Data_Encode( int Channel_Coerce_Data_Encode(uint8_t *apdu, unsigned max_apdu,
uint8_t * apdu,
unsigned max_apdu,
BACNET_APPLICATION_DATA_VALUE *value, BACNET_APPLICATION_DATA_VALUE *value,
BACNET_APPLICATION_TAG tag) BACNET_APPLICATION_TAG tag)
{ {
@@ -826,18 +788,20 @@ int Channel_Coerce_Data_Encode(
#if defined(BACAPP_BOOLEAN) #if defined(BACAPP_BOOLEAN)
case BACNET_APPLICATION_TAG_BOOLEAN: case BACNET_APPLICATION_TAG_BOOLEAN:
if (tag == BACNET_APPLICATION_TAG_BOOLEAN) { if (tag == BACNET_APPLICATION_TAG_BOOLEAN) {
apdu_len = apdu_len = encode_application_boolean(&apdu[0],
encode_application_boolean(&apdu[0], value->type.Boolean); value->type.Boolean);
} else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
if (value->type.Boolean) { if (value->type.Boolean) {
unsigned_value = 1; unsigned_value = 1;
} }
apdu_len = encode_application_unsigned(&apdu[0], unsigned_value); apdu_len =
encode_application_unsigned(&apdu[0], unsigned_value);
} else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) {
if (value->type.Boolean) { if (value->type.Boolean) {
signed_value = 1; signed_value = 1;
} }
apdu_len = encode_application_signed(&apdu[0], signed_value); apdu_len =
encode_application_signed(&apdu[0], signed_value);
} else if (tag == BACNET_APPLICATION_TAG_REAL) { } else if (tag == BACNET_APPLICATION_TAG_REAL) {
if (value->type.Boolean) { if (value->type.Boolean) {
float_value = 1; float_value = 1;
@@ -847,7 +811,8 @@ int Channel_Coerce_Data_Encode(
if (value->type.Boolean) { if (value->type.Boolean) {
double_value = 1; double_value = 1;
} }
apdu_len = encode_application_double(&apdu[0], double_value); apdu_len =
encode_application_double(&apdu[0], double_value);
} else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) { } else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if (value->type.Boolean) { if (value->type.Boolean) {
unsigned_value = 1; unsigned_value = 1;
@@ -869,32 +834,32 @@ int Channel_Coerce_Data_Encode(
encode_application_boolean(&apdu[0], boolean_value); encode_application_boolean(&apdu[0], boolean_value);
} else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
unsigned_value = value->type.Unsigned_Int; unsigned_value = value->type.Unsigned_Int;
apdu_len = encode_application_unsigned(&apdu[0], apdu_len =
unsigned_value); encode_application_unsigned(&apdu[0], unsigned_value);
} else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) {
if (value->type.Unsigned_Int <= 2147483647) { if (value->type.Unsigned_Int <= 2147483647) {
signed_value = value->type.Unsigned_Int; signed_value = value->type.Unsigned_Int;
apdu_len = encode_application_signed(&apdu[0], apdu_len =
signed_value); encode_application_signed(&apdu[0], signed_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_REAL) { } else if (tag == BACNET_APPLICATION_TAG_REAL) {
if (value->type.Unsigned_Int <= 9999999) { if (value->type.Unsigned_Int <= 9999999) {
float_value = (float)value->type.Unsigned_Int; float_value = (float)value->type.Unsigned_Int;
apdu_len = encode_application_real(&apdu[0], apdu_len =
float_value); encode_application_real(&apdu[0], float_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_DOUBLE) { } else if (tag == BACNET_APPLICATION_TAG_DOUBLE) {
double_value = value->type.Unsigned_Int; double_value = value->type.Unsigned_Int;
apdu_len = encode_application_double(&apdu[0], apdu_len =
double_value); encode_application_double(&apdu[0], double_value);
} else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) { } else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) {
unsigned_value = value->type.Unsigned_Int; unsigned_value = value->type.Unsigned_Int;
apdu_len = encode_application_enumerated(&apdu[0], apdu_len =
unsigned_value); encode_application_enumerated(&apdu[0], unsigned_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -919,24 +884,24 @@ int Channel_Coerce_Data_Encode(
} }
} else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) {
signed_value = value->type.Signed_Int; signed_value = value->type.Signed_Int;
apdu_len = encode_application_signed(&apdu[0], apdu_len =
signed_value); encode_application_signed(&apdu[0], signed_value);
} else if (tag == BACNET_APPLICATION_TAG_REAL) { } else if (tag == BACNET_APPLICATION_TAG_REAL) {
if (value->type.Signed_Int <= 9999999) { if (value->type.Signed_Int <= 9999999) {
float_value = (float)value->type.Signed_Int; float_value = (float)value->type.Signed_Int;
apdu_len = encode_application_real(&apdu[0], apdu_len =
float_value); encode_application_real(&apdu[0], float_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_DOUBLE) { } else if (tag == BACNET_APPLICATION_TAG_DOUBLE) {
double_value = value->type.Signed_Int; double_value = value->type.Signed_Int;
apdu_len = encode_application_double(&apdu[0], apdu_len =
double_value); encode_application_double(&apdu[0], double_value);
} else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) { } else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) {
unsigned_value = value->type.Signed_Int; unsigned_value = value->type.Signed_Int;
apdu_len = encode_application_enumerated(&apdu[0], apdu_len =
unsigned_value); encode_application_enumerated(&apdu[0], unsigned_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -963,25 +928,24 @@ int Channel_Coerce_Data_Encode(
if ((value->type.Real >= -2147483000.0) && if ((value->type.Real >= -2147483000.0) &&
(value->type.Real <= 214783000.0)) { (value->type.Real <= 214783000.0)) {
signed_value = (int32_t)value->type.Real; signed_value = (int32_t)value->type.Real;
apdu_len = encode_application_signed(&apdu[0], apdu_len =
signed_value); encode_application_signed(&apdu[0], signed_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_REAL) { } else if (tag == BACNET_APPLICATION_TAG_REAL) {
float_value = value->type.Real; float_value = value->type.Real;
apdu_len = encode_application_real(&apdu[0], apdu_len = encode_application_real(&apdu[0], float_value);
float_value);
} else if (tag == BACNET_APPLICATION_TAG_DOUBLE) { } else if (tag == BACNET_APPLICATION_TAG_DOUBLE) {
double_value = value->type.Real; double_value = value->type.Real;
apdu_len = encode_application_double(&apdu[0], apdu_len =
double_value); encode_application_double(&apdu[0], double_value);
} else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) { } else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value->type.Real >= 0.0) && if ((value->type.Real >= 0.0) &&
(value->type.Real <= 2147483000.0)) { (value->type.Real <= 2147483000.0)) {
unsigned_value = (uint32_t)value->type.Real; unsigned_value = (uint32_t)value->type.Real;
apdu_len = encode_application_enumerated(&apdu[0], apdu_len = encode_application_enumerated(
unsigned_value); &apdu[0], unsigned_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -1011,8 +975,8 @@ int Channel_Coerce_Data_Encode(
if ((value->type.Double >= -2147483000.0) && if ((value->type.Double >= -2147483000.0) &&
(value->type.Double <= 214783000.0)) { (value->type.Double <= 214783000.0)) {
signed_value = (int32_t)value->type.Double; signed_value = (int32_t)value->type.Double;
apdu_len = encode_application_signed(&apdu[0], apdu_len =
signed_value); encode_application_signed(&apdu[0], signed_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -1020,21 +984,21 @@ int Channel_Coerce_Data_Encode(
if ((value->type.Double >= 3.4E-38) && if ((value->type.Double >= 3.4E-38) &&
(value->type.Double <= 3.4E+38)) { (value->type.Double <= 3.4E+38)) {
float_value = (float)value->type.Double; float_value = (float)value->type.Double;
apdu_len = encode_application_real(&apdu[0], apdu_len =
float_value); encode_application_real(&apdu[0], float_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_DOUBLE) { } else if (tag == BACNET_APPLICATION_TAG_DOUBLE) {
double_value = value->type.Double; double_value = value->type.Double;
apdu_len = encode_application_double(&apdu[0], apdu_len =
double_value); encode_application_double(&apdu[0], double_value);
} else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) { } else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) {
if ((value->type.Double >= 0.0) && if ((value->type.Double >= 0.0) &&
(value->type.Double <= 2147483000.0)) { (value->type.Double <= 2147483000.0)) {
unsigned_value = (uint32_t)value->type.Double; unsigned_value = (uint32_t)value->type.Double;
apdu_len = encode_application_enumerated(&apdu[0], apdu_len = encode_application_enumerated(
unsigned_value); &apdu[0], unsigned_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -1053,32 +1017,32 @@ int Channel_Coerce_Data_Encode(
encode_application_boolean(&apdu[0], boolean_value); encode_application_boolean(&apdu[0], boolean_value);
} else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
unsigned_value = value->type.Enumerated; unsigned_value = value->type.Enumerated;
apdu_len = encode_application_unsigned(&apdu[0], apdu_len =
unsigned_value); encode_application_unsigned(&apdu[0], unsigned_value);
} else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) { } else if (tag == BACNET_APPLICATION_TAG_SIGNED_INT) {
if (value->type.Enumerated <= 2147483647) { if (value->type.Enumerated <= 2147483647) {
signed_value = value->type.Enumerated; signed_value = value->type.Enumerated;
apdu_len = encode_application_signed(&apdu[0], apdu_len =
signed_value); encode_application_signed(&apdu[0], signed_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_REAL) { } else if (tag == BACNET_APPLICATION_TAG_REAL) {
if (value->type.Enumerated <= 9999999) { if (value->type.Enumerated <= 9999999) {
float_value = (float)value->type.Enumerated; float_value = (float)value->type.Enumerated;
apdu_len = encode_application_real(&apdu[0], apdu_len =
float_value); encode_application_real(&apdu[0], float_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
} else if (tag == BACNET_APPLICATION_TAG_DOUBLE) { } else if (tag == BACNET_APPLICATION_TAG_DOUBLE) {
double_value = value->type.Enumerated; double_value = value->type.Enumerated;
apdu_len = encode_application_double(&apdu[0], apdu_len =
double_value); encode_application_double(&apdu[0], double_value);
} else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) { } else if (tag == BACNET_APPLICATION_TAG_ENUMERATED) {
unsigned_value = value->type.Enumerated; unsigned_value = value->type.Enumerated;
apdu_len = encode_application_enumerated(&apdu[0], apdu_len =
unsigned_value); encode_application_enumerated(&apdu[0], unsigned_value);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -1087,9 +1051,8 @@ int Channel_Coerce_Data_Encode(
#if defined(BACAPP_LIGHTING_COMMAND) #if defined(BACAPP_LIGHTING_COMMAND)
case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: case BACNET_APPLICATION_TAG_LIGHTING_COMMAND:
if (tag == BACNET_APPLICATION_TAG_LIGHTING_COMMAND) { if (tag == BACNET_APPLICATION_TAG_LIGHTING_COMMAND) {
apdu_len = apdu_len = lighting_command_encode(
lighting_command_encode(&apdu[0], &apdu[0], &value->type.Lighting_Command);
&value->type.Lighting_Command);
} else { } else {
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
} }
@@ -1112,8 +1075,7 @@ int Channel_Coerce_Data_Encode(
* *
* @return true if values are within range and present-value is sent. * @return true if values are within range and present-value is sent.
*/ */
bool Channel_Write_Member_Value( bool Channel_Write_Member_Value(BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_APPLICATION_DATA_VALUE *value) BACNET_APPLICATION_DATA_VALUE *value)
{ {
bool status = false; bool status = false;
@@ -1126,9 +1088,7 @@ bool Channel_Write_Member_Value(
(wp_data->object_property == PROP_PRESENT_VALUE) && (wp_data->object_property == PROP_PRESENT_VALUE) &&
(wp_data->array_index == BACNET_ARRAY_ALL)) { (wp_data->array_index == BACNET_ARRAY_ALL)) {
apdu_len = Channel_Coerce_Data_Encode( apdu_len = Channel_Coerce_Data_Encode(
wp_data->application_data, wp_data->application_data, wp_data->application_data_len, value,
wp_data->application_data_len,
value,
BACNET_APPLICATION_TAG_REAL); BACNET_APPLICATION_TAG_REAL);
if (apdu_len != BACNET_STATUS_ERROR) { if (apdu_len != BACNET_STATUS_ERROR) {
wp_data->application_data_len = apdu_len; wp_data->application_data_len = apdu_len;
@@ -1140,9 +1100,7 @@ bool Channel_Write_Member_Value(
(wp_data->object_property == PROP_PRESENT_VALUE) && (wp_data->object_property == PROP_PRESENT_VALUE) &&
(wp_data->array_index == BACNET_ARRAY_ALL)) { (wp_data->array_index == BACNET_ARRAY_ALL)) {
apdu_len = Channel_Coerce_Data_Encode( apdu_len = Channel_Coerce_Data_Encode(
wp_data->application_data, wp_data->application_data, wp_data->application_data_len, value,
wp_data->application_data_len,
value,
BACNET_APPLICATION_TAG_ENUMERATED); BACNET_APPLICATION_TAG_ENUMERATED);
if (apdu_len != BACNET_STATUS_ERROR) { if (apdu_len != BACNET_STATUS_ERROR) {
wp_data->application_data_len = apdu_len; wp_data->application_data_len = apdu_len;
@@ -1154,9 +1112,7 @@ bool Channel_Write_Member_Value(
(wp_data->object_property == PROP_PRESENT_VALUE) && (wp_data->object_property == PROP_PRESENT_VALUE) &&
(wp_data->array_index == BACNET_ARRAY_ALL)) { (wp_data->array_index == BACNET_ARRAY_ALL)) {
apdu_len = Channel_Coerce_Data_Encode( apdu_len = Channel_Coerce_Data_Encode(
wp_data->application_data, wp_data->application_data, wp_data->application_data_len, value,
wp_data->application_data_len,
value,
BACNET_APPLICATION_TAG_UNSIGNED_INT); BACNET_APPLICATION_TAG_UNSIGNED_INT);
if (apdu_len != BACNET_STATUS_ERROR) { if (apdu_len != BACNET_STATUS_ERROR) {
wp_data->application_data_len = apdu_len; wp_data->application_data_len = apdu_len;
@@ -1166,10 +1122,8 @@ bool Channel_Write_Member_Value(
if ((wp_data->object_property == PROP_PRESENT_VALUE) && if ((wp_data->object_property == PROP_PRESENT_VALUE) &&
(wp_data->array_index == BACNET_ARRAY_ALL)) { (wp_data->array_index == BACNET_ARRAY_ALL)) {
apdu_len = Channel_Coerce_Data_Encode( apdu_len = Channel_Coerce_Data_Encode(
wp_data->application_data, wp_data->application_data, wp_data->application_data_len,
wp_data->application_data_len, value, BACNET_APPLICATION_TAG_REAL);
value,
BACNET_APPLICATION_TAG_REAL);
if (apdu_len != BACNET_STATUS_ERROR) { if (apdu_len != BACNET_STATUS_ERROR) {
wp_data->application_data_len = apdu_len; wp_data->application_data_len = apdu_len;
status = true; status = true;
@@ -1177,10 +1131,8 @@ bool Channel_Write_Member_Value(
} else if ((wp_data->object_property == PROP_LIGHTING_COMMAND) && } else if ((wp_data->object_property == PROP_LIGHTING_COMMAND) &&
(wp_data->array_index == BACNET_ARRAY_ALL)) { (wp_data->array_index == BACNET_ARRAY_ALL)) {
apdu_len = Channel_Coerce_Data_Encode( apdu_len = Channel_Coerce_Data_Encode(
wp_data->application_data, wp_data->application_data, wp_data->application_data_len,
wp_data->application_data_len, value, BACNET_APPLICATION_TAG_LIGHTING_COMMAND);
value,
BACNET_APPLICATION_TAG_LIGHTING_COMMAND);
if (apdu_len != BACNET_STATUS_ERROR) { if (apdu_len != BACNET_STATUS_ERROR) {
wp_data->application_data_len = apdu_len; wp_data->application_data_len = apdu_len;
status = true; status = true;
@@ -1200,8 +1152,7 @@ bool Channel_Write_Member_Value(
* *
* @return true if values are within range and present-value is sent. * @return true if values are within range and present-value is sent.
*/ */
static bool Channel_Write_Members( static bool Channel_Write_Members(struct bacnet_channel_object *pChannel,
struct bacnet_channel_object * pChannel,
BACNET_APPLICATION_DATA_VALUE *value, BACNET_APPLICATION_DATA_VALUE *value,
uint8_t priority) uint8_t priority)
{ {
@@ -1227,8 +1178,7 @@ static bool Channel_Write_Members(
wp_data.object_property = pMember->propertyIdentifier; wp_data.object_property = pMember->propertyIdentifier;
wp_data.array_index = pMember->arrayIndex; wp_data.array_index = pMember->arrayIndex;
wp_data.priority = priority; wp_data.priority = priority;
wp_data.application_data_len = wp_data.application_data_len = sizeof(wp_data.application_data);
sizeof(wp_data.application_data);
status = Channel_Write_Member_Value(&wp_data, value); status = Channel_Write_Member_Value(&wp_data, value);
if (status) { if (status) {
status = Device_Write_Property(&wp_data); status = Device_Write_Property(&wp_data);
@@ -1253,8 +1203,7 @@ static bool Channel_Write_Members(
* *
* @return true if values are within range and present-value is sent. * @return true if values are within range and present-value is sent.
*/ */
bool Channel_Present_Value_Set( bool Channel_Present_Value_Set(BACNET_WRITE_PROPERTY_DATA *wp_data,
BACNET_WRITE_PROPERTY_DATA * wp_data,
BACNET_APPLICATION_DATA_VALUE *value) BACNET_APPLICATION_DATA_VALUE *value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -1265,8 +1214,8 @@ bool Channel_Present_Value_Set(
if ((wp_data->priority > 0) && if ((wp_data->priority > 0) &&
(wp_data->priority <= BACNET_MAX_PRIORITY)) { (wp_data->priority <= BACNET_MAX_PRIORITY)) {
if (wp_data->priority != 6 /* reserved */) { if (wp_data->priority != 6 /* reserved */) {
status = Channel_Value_Copy(&Channel[index].Present_Value, status =
value); Channel_Value_Copy(&Channel[index].Present_Value, value);
status = Channel_Write_Members(&Channel[index], value, status = Channel_Write_Members(&Channel[index], value,
wp_data->priority); wp_data->priority);
status = true; status = true;
@@ -1305,8 +1254,7 @@ bool Channel_Object_Name(uint32_t object_instance,
index = Channel_Instance_To_Index(object_instance); index = Channel_Instance_To_Index(object_instance);
if (index < BACNET_CHANNELS_MAX) { if (index < BACNET_CHANNELS_MAX) {
sprintf(text_string, "CHANNEL %lu", sprintf(text_string, "CHANNEL %lu", (unsigned long)object_instance);
(unsigned long) object_instance);
status = characterstring_init_ansi(object_name, text_string); status = characterstring_init_ansi(object_name, text_string);
} }
@@ -1342,8 +1290,7 @@ bool Channel_Out_Of_Service(uint32_t instance)
* *
* @return true if the out-of-service property value was set * @return true if the out-of-service property value was set
*/ */
void Channel_Out_Of_Service_Set(uint32_t instance, void Channel_Out_Of_Service_Set(uint32_t instance, bool value)
bool value)
{ {
unsigned int index = 0; unsigned int index = 0;
@@ -1384,8 +1331,7 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(&apdu[0], OBJECT_CHANNEL,
encode_application_object_id(&apdu[0], OBJECT_CHANNEL,
rpdata->object_instance); rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -1394,8 +1340,7 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len = encode_application_enumerated(&apdu[0], OBJECT_CHANNEL);
encode_application_enumerated(&apdu[0], OBJECT_CHANNEL);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
cvalue = Channel_Present_Value(rpdata->object_instance); cvalue = Channel_Present_Value(rpdata->object_instance);
@@ -1406,15 +1351,12 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
break; break;
case PROP_LAST_PRIORITY: case PROP_LAST_PRIORITY:
unsigned_value = Channel_Last_Priority(rpdata->object_instance); unsigned_value = Channel_Last_Priority(rpdata->object_instance);
apdu_len = apdu_len = encode_application_unsigned(&apdu[0], unsigned_value);
encode_application_unsigned(&apdu[0], unsigned_value);
break; break;
case PROP_WRITE_STATUS: case PROP_WRITE_STATUS:
unsigned_value = unsigned_value = (BACNET_WRITE_STATUS)Channel_Write_Status(
(BACNET_WRITE_STATUS)Channel_Write_Status(
rpdata->object_instance); rpdata->object_instance);
apdu_len = apdu_len = encode_application_enumerated(&apdu[0], unsigned_value);
encode_application_enumerated(&apdu[0], unsigned_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -1432,17 +1374,19 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
case PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES: case PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
count = Channel_Reference_List_Member_Count(rpdata->object_instance); count = Channel_Reference_List_Member_Count(
rpdata->object_instance);
apdu_len = encode_application_unsigned(&apdu[0], count); apdu_len = encode_application_unsigned(&apdu[0], count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list
*/
/* into one packet. */ /* into one packet. */
count = Channel_Reference_List_Member_Count(rpdata->object_instance); count = Channel_Reference_List_Member_Count(
rpdata->object_instance);
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
pMember = Channel_Reference_List_Member_Element( pMember = Channel_Reference_List_Member_Element(
rpdata->object_instance, i); rpdata->object_instance, i);
len = len = bacapp_encode_device_obj_property_ref(&apdu[apdu_len],
bacapp_encode_device_obj_property_ref(&apdu[apdu_len],
pMember); pMember);
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) { if ((apdu_len + len) < MAX_APDU) {
@@ -1456,12 +1400,12 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
} }
} else { } else {
/* a specific element was requested */ /* a specific element was requested */
count = Channel_Reference_List_Member_Count(rpdata->object_instance); count = Channel_Reference_List_Member_Count(
rpdata->object_instance);
if (rpdata->array_index <= count) { if (rpdata->array_index <= count) {
pMember = Channel_Reference_List_Member_Element( pMember = Channel_Reference_List_Member_Element(
rpdata->object_instance, rpdata->array_index); rpdata->object_instance, rpdata->array_index);
apdu_len += apdu_len += bacapp_encode_device_obj_property_ref(&apdu[0],
bacapp_encode_device_obj_property_ref(&apdu[0],
pMember); pMember);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -1472,22 +1416,21 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
break; break;
case PROP_CHANNEL_NUMBER: case PROP_CHANNEL_NUMBER:
unsigned_value = Channel_Number(rpdata->object_instance); unsigned_value = Channel_Number(rpdata->object_instance);
apdu_len = apdu_len = encode_application_unsigned(&apdu[0], unsigned_value);
encode_application_unsigned(&apdu[0], unsigned_value);
break; break;
case PROP_CONTROL_GROUPS: case PROP_CONTROL_GROUPS:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array */
apdu_len = encode_application_unsigned(&apdu[0], apdu_len =
CONTROL_GROUPS_MAX); encode_application_unsigned(&apdu[0], CONTROL_GROUPS_MAX);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
/* if no index was specified, then try to encode the entire list */ /* if no index was specified, then try to encode the entire list
*/
/* into one packet. */ /* into one packet. */
for (i = 1; i <= CONTROL_GROUPS_MAX; i++) { for (i = 1; i <= CONTROL_GROUPS_MAX; i++) {
unsigned_value = Channel_Control_Groups_Element( unsigned_value = Channel_Control_Groups_Element(
rpdata->object_instance, i); rpdata->object_instance, i);
len = len = encode_application_unsigned(&apdu[apdu_len],
encode_application_unsigned(&apdu[apdu_len],
unsigned_value); unsigned_value);
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) { if ((apdu_len + len) < MAX_APDU) {
@@ -1504,8 +1447,7 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
if (rpdata->array_index <= CONTROL_GROUPS_MAX) { if (rpdata->array_index <= CONTROL_GROUPS_MAX) {
unsigned_value = Channel_Control_Groups_Element( unsigned_value = Channel_Control_Groups_Element(
rpdata->object_instance, rpdata->array_index); rpdata->object_instance, rpdata->array_index);
apdu_len = apdu_len = encode_application_unsigned(&apdu[apdu_len],
encode_application_unsigned(&apdu[apdu_len],
unsigned_value); unsigned_value);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -1521,10 +1463,9 @@ int Channel_Read_Property(BACNET_READ_PROPERTY_DATA * rpdata)
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) if ((apdu_len >= 0) && (rpdata->object_property != PROP_PRIORITY_ARRAY) &&
&& (rpdata->object_property != PROP_PRIORITY_ARRAY) (rpdata->object_property != PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES) &&
&& (rpdata->object_property != PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES) (rpdata->array_index != BACNET_ARRAY_ALL)) {
&& (rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -1552,8 +1493,7 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
uint32_t array_index = 0; uint32_t array_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -1584,11 +1524,13 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
break; break;
case PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES: case PROP_LIST_OF_OBJECT_PROPERTY_REFERENCES:
// FIXME: add property handling // FIXME: add property handling
// status = Channel_List_Of_Object_Property_References_Set( // status =
// Channel_List_Of_Object_Property_References_Set(
// wp_data, // wp_data,
// &value); // &value);
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED; wp_data->error_code =
ERROR_CODE_OPTIONAL_FUNCTIONALITY_NOT_SUPPORTED;
break; break;
case PROP_CHANNEL_NUMBER: case PROP_CHANNEL_NUMBER:
status = status =
@@ -1602,7 +1544,8 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
case PROP_CONTROL_GROUPS: case PROP_CONTROL_GROUPS:
if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) { if (value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT) {
if (wp_data->array_index == 0) { if (wp_data->array_index == 0) {
/* Array element zero is the number of elements in the array */ /* Array element zero is the number of elements in the array
*/
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else if (wp_data->array_index == BACNET_ARRAY_ALL) { } else if (wp_data->array_index == BACNET_ARRAY_ALL) {
@@ -1612,7 +1555,8 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
element_len = len; element_len = len;
do { do {
if ((element_len > 0) && if ((element_len > 0) &&
(value.tag == BACNET_APPLICATION_TAG_UNSIGNED_INT)) { (value.tag ==
BACNET_APPLICATION_TAG_UNSIGNED_INT)) {
if ((wp_data->array_index <= CONTROL_GROUPS_MAX) && if ((wp_data->array_index <= CONTROL_GROUPS_MAX) &&
(value.type.Unsigned_Int <= 65535)) { (value.type.Unsigned_Int <= 65535)) {
status = Channel_Control_Groups_Element_Set( status = Channel_Control_Groups_Element_Set(
@@ -1622,7 +1566,8 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
} }
if (!status) { if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code =
ERROR_CODE_VALUE_OUT_OF_RANGE;
break; break;
} }
} }
@@ -1631,11 +1576,11 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
if (count) { if (count) {
element_len = bacapp_decode_application_data( element_len = bacapp_decode_application_data(
&wp_data->application_data[len], &wp_data->application_data[len],
wp_data->application_data_len-len, wp_data->application_data_len - len, &value);
&value);
if (element_len < 0) { if (element_len < 0) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code =
ERROR_CODE_VALUE_OUT_OF_RANGE;
break; break;
} }
len += element_len; len += element_len;
@@ -1645,8 +1590,7 @@ bool Channel_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data)
if ((wp_data->array_index <= CONTROL_GROUPS_MAX) && if ((wp_data->array_index <= CONTROL_GROUPS_MAX) &&
(value.type.Unsigned_Int <= 65535)) { (value.type.Unsigned_Int <= 65535)) {
status = Channel_Control_Groups_Element_Set( status = Channel_Control_Groups_Element_Set(
wp_data->object_instance, wp_data->object_instance, wp_data->array_index,
wp_data->array_index,
value.type.Unsigned_Int); value.type.Unsigned_Int);
} }
if (!status) { if (!status) {
@@ -1695,8 +1639,7 @@ void Channel_Init(void)
Channel[i].Members[m].objectIdentifier.instance = i + 1; Channel[i].Members[m].objectIdentifier.instance = i + 1;
Channel[i].Members[m].propertyIdentifier = PROP_LIGHTING_COMMAND; Channel[i].Members[m].propertyIdentifier = PROP_LIGHTING_COMMAND;
Channel[i].Members[m].arrayIndex = BACNET_ARRAY_ALL; Channel[i].Members[m].arrayIndex = BACNET_ARRAY_ALL;
Channel[i].Members[m].deviceIdentifier.type = Channel[i].Members[m].deviceIdentifier.type = OBJECT_DEVICE;
OBJECT_DEVICE;
Channel[i].Members[m].deviceIdentifier.instance = 0; Channel[i].Members[m].deviceIdentifier.instance = 0;
} }
Channel[i].Number = 0; Channel[i].Number = 0;
+78 -148
View File
@@ -66,39 +66,32 @@
writeSuccessful [8] BOOLEAN writeSuccessful [8] BOOLEAN
}*/ }*/
int cl_encode_apdu(uint8_t *apdu, BACNET_ACTION_LIST *bcl)
int cl_encode_apdu(
uint8_t * apdu,
BACNET_ACTION_LIST * bcl)
{ {
int len = 0; int len = 0;
int apdu_len = 0; int apdu_len = 0;
if (bcl->Device_Id.instance >= 0 && if (bcl->Device_Id.instance >= 0 &&
bcl->Device_Id.instance <= BACNET_MAX_INSTANCE) { bcl->Device_Id.instance <= BACNET_MAX_INSTANCE) {
len = len = encode_context_object_id(&apdu[apdu_len], 0, bcl->Device_Id.type,
encode_context_object_id(&apdu[apdu_len], 0, bcl->Device_Id.type,
bcl->Device_Id.instance); bcl->Device_Id.instance);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
apdu_len += len; apdu_len += len;
} }
/* TODO: Check for object type and instance limits */ /* TODO: Check for object type and instance limits */
len = len = encode_context_object_id(&apdu[apdu_len], 1, bcl->Object_Id.type,
encode_context_object_id(&apdu[apdu_len], 1, bcl->Object_Id.type,
bcl->Object_Id.instance); bcl->Object_Id.instance);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
apdu_len += len; apdu_len += len;
len = len =
encode_context_enumerated(&apdu[apdu_len], 2, encode_context_enumerated(&apdu[apdu_len], 2, bcl->Property_Identifier);
bcl->Property_Identifier);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
apdu_len += len; apdu_len += len;
if (bcl->Property_Array_Index != BACNET_ARRAY_ALL) { if (bcl->Property_Array_Index != BACNET_ARRAY_ALL) {
len = len = encode_context_unsigned(&apdu[apdu_len], 3,
encode_context_unsigned(&apdu[apdu_len], 3,
bcl->Property_Array_Index); bcl->Property_Array_Index);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
@@ -107,13 +100,12 @@ int cl_encode_apdu(
/* BACnet Testing Observed Incident oi00108 /* BACnet Testing Observed Incident oi00108
Command Action not correctly formatted Command Action not correctly formatted
Revealed by BACnet Test Client v1.8.16 ( www.bac-test.com/bacnet-test-client-download ) Revealed by BACnet Test Client v1.8.16 (
BITS: BIT00031 www.bac-test.com/bacnet-test-client-download ) BITS: BIT00031 BC
BC 135.1: 9.20.1.7 135.1: 9.20.1.7 BC 135.1: 9.20.1.9 Any discussions can be directed to
BC 135.1: 9.20.1.9 edward@bac-test.com Please feel free to remove this comment when my
Any discussions can be directed to edward@bac-test.com changes have been reviewed by all interested parties. Say 6 months ->
Please feel free to remove this comment when my changes have been reviewed September 2016 */
by all interested parties. Say 6 months -> September 2016 */
len = encode_opening_tag(&apdu[apdu_len], 4); len = encode_opening_tag(&apdu[apdu_len], 4);
if (len < 0) if (len < 0)
@@ -128,7 +120,6 @@ int cl_encode_apdu(
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
apdu_len += len; apdu_len += len;
if (bcl->Priority != BACNET_NO_PRIORITY) { if (bcl->Priority != BACNET_NO_PRIORITY) {
len = encode_context_unsigned(&apdu[apdu_len], 5, bcl->Priority); len = encode_context_unsigned(&apdu[apdu_len], 5, bcl->Priority);
if (len < 0) if (len < 0)
@@ -153,10 +144,7 @@ int cl_encode_apdu(
return apdu_len; return apdu_len;
} }
int cl_decode_apdu( int cl_decode_apdu(uint8_t *apdu, unsigned apdu_len, BACNET_APPLICATION_TAG tag,
uint8_t * apdu,
unsigned apdu_len,
BACNET_APPLICATION_TAG tag,
BACNET_ACTION_LIST *bcl) BACNET_ACTION_LIST *bcl)
{ {
int len = 0; int len = 0;
@@ -167,8 +155,7 @@ int cl_decode_apdu(
if (decode_is_context_tag(&apdu[dec_len], 0)) { if (decode_is_context_tag(&apdu[dec_len], 0)) {
/* Tag 0: Device ID */ /* Tag 0: Device ID */
dec_len++; dec_len++;
len = len = decode_object_id(&apdu[dec_len], &bcl->Device_Id.type,
decode_object_id(&apdu[dec_len], &bcl->Device_Id.type,
&bcl->Device_Id.instance); &bcl->Device_Id.instance);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
@@ -176,33 +163,28 @@ int cl_decode_apdu(
} }
if (!decode_is_context_tag(&apdu[dec_len++], 1)) if (!decode_is_context_tag(&apdu[dec_len++], 1))
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
len = len = decode_object_id(&apdu[dec_len], &bcl->Object_Id.type,
decode_object_id(&apdu[dec_len], &bcl->Object_Id.type,
&bcl->Object_Id.instance); &bcl->Object_Id.instance);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
dec_len += len; dec_len += len;
len = len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type); &len_value_type);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
dec_len += len; dec_len += len;
if (tag_number != 2) if (tag_number != 2)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
len = len = decode_enumerated(&apdu[dec_len], len_value_type,
decode_enumerated(&apdu[dec_len], len_value_type,
&bcl->Property_Identifier); &bcl->Property_Identifier);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
dec_len += len; dec_len += len;
if (decode_is_context_tag(&apdu[dec_len], 3)) { if (decode_is_context_tag(&apdu[dec_len], 3)) {
len = len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type); &len_value_type);
dec_len += len; dec_len += len;
len = len = decode_unsigned(&apdu[dec_len], len_value_type,
decode_unsigned(&apdu[dec_len], len_value_type,
&bcl->Property_Array_Index); &bcl->Property_Array_Index);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
@@ -220,67 +202,54 @@ int cl_decode_apdu(
len = 1; len = 1;
break; break;
case BACNET_APPLICATION_TAG_BOOLEAN: case BACNET_APPLICATION_TAG_BOOLEAN:
len = len = decode_context_boolean2(&apdu[dec_len], 4,
decode_context_boolean2(&apdu[dec_len], 4,
&bcl->Value.type.Boolean); &bcl->Value.type.Boolean);
break; break;
case BACNET_APPLICATION_TAG_UNSIGNED_INT: case BACNET_APPLICATION_TAG_UNSIGNED_INT:
len = len = decode_context_unsigned(&apdu[dec_len], 4,
decode_context_unsigned(&apdu[dec_len], 4,
&bcl->Value.type.Unsigned_Int); &bcl->Value.type.Unsigned_Int);
break; break;
case BACNET_APPLICATION_TAG_SIGNED_INT: case BACNET_APPLICATION_TAG_SIGNED_INT:
len = len = decode_context_signed(&apdu[dec_len], 4,
decode_context_signed(&apdu[dec_len], 4,
&bcl->Value.type.Signed_Int); &bcl->Value.type.Signed_Int);
break; break;
case BACNET_APPLICATION_TAG_REAL: case BACNET_APPLICATION_TAG_REAL:
len = len = decode_context_real(&apdu[dec_len], 4, &bcl->Value.type.Real);
decode_context_real(&apdu[dec_len], 4, &bcl->Value.type.Real);
break; break;
case BACNET_APPLICATION_TAG_DOUBLE: case BACNET_APPLICATION_TAG_DOUBLE:
len = len = decode_context_double(&apdu[dec_len], 4,
decode_context_double(&apdu[dec_len], 4,
&bcl->Value.type.Double); &bcl->Value.type.Double);
break; break;
case BACNET_APPLICATION_TAG_OCTET_STRING: case BACNET_APPLICATION_TAG_OCTET_STRING:
len = len = decode_context_octet_string(&apdu[dec_len], 4,
decode_context_octet_string(&apdu[dec_len], 4,
&bcl->Value.type.Octet_String); &bcl->Value.type.Octet_String);
break; break;
case BACNET_APPLICATION_TAG_CHARACTER_STRING: case BACNET_APPLICATION_TAG_CHARACTER_STRING:
len = len = decode_context_character_string(
decode_context_character_string(&apdu[dec_len], 4, &apdu[dec_len], 4, &bcl->Value.type.Character_String);
&bcl->Value.type.Character_String);
break; break;
case BACNET_APPLICATION_TAG_BIT_STRING: case BACNET_APPLICATION_TAG_BIT_STRING:
len = len = decode_context_bitstring(&apdu[dec_len], 4,
decode_context_bitstring(&apdu[dec_len], 4,
&bcl->Value.type.Bit_String); &bcl->Value.type.Bit_String);
break; break;
case BACNET_APPLICATION_TAG_ENUMERATED: case BACNET_APPLICATION_TAG_ENUMERATED:
len = len = decode_context_enumerated(&apdu[dec_len], 4,
decode_context_enumerated(&apdu[dec_len], 4,
&bcl->Value.type.Enumerated); &bcl->Value.type.Enumerated);
break; break;
case BACNET_APPLICATION_TAG_DATE: case BACNET_APPLICATION_TAG_DATE:
len = len = decode_context_date(&apdu[dec_len], 4, &bcl->Value.type.Date);
decode_context_date(&apdu[dec_len], 4, &bcl->Value.type.Date);
break; break;
case BACNET_APPLICATION_TAG_TIME: case BACNET_APPLICATION_TAG_TIME:
len = len = decode_context_bacnet_time(&apdu[dec_len], 4,
decode_context_bacnet_time(&apdu[dec_len], 4,
&bcl->Value.type.Time); &bcl->Value.type.Time);
break; break;
case BACNET_APPLICATION_TAG_OBJECT_ID: case BACNET_APPLICATION_TAG_OBJECT_ID:
len = len = decode_context_object_id(&apdu[dec_len], 4,
decode_context_object_id(&apdu[dec_len], 4,
&bcl->Value.type.Object_Id.type, &bcl->Value.type.Object_Id.type,
&bcl->Value.type.Object_Id.instance); &bcl->Value.type.Object_Id.instance);
break; break;
case BACNET_APPLICATION_TAG_LIGHTING_COMMAND: case BACNET_APPLICATION_TAG_LIGHTING_COMMAND:
len = len = lighting_command_decode(&apdu[dec_len], apdu_len - dec_len,
lighting_command_decode(&apdu[dec_len], apdu_len - dec_len,
&bcl->Value.type.Lighting_Command); &bcl->Value.type.Lighting_Command);
break; break;
default: default:
@@ -291,8 +260,7 @@ int cl_decode_apdu(
dec_len += len; dec_len += len;
if (decode_is_context_tag(&apdu[dec_len], 5)) { if (decode_is_context_tag(&apdu[dec_len], 5)) {
uint32_t priority_dec; uint32_t priority_dec;
len = len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type); &len_value_type);
dec_len += len; dec_len += len;
len = decode_unsigned(&apdu[dec_len], len_value_type, &priority_dec); len = decode_unsigned(&apdu[dec_len], len_value_type, &priority_dec);
@@ -304,12 +272,10 @@ int cl_decode_apdu(
bcl->Priority = BACNET_NO_PRIORITY; bcl->Priority = BACNET_NO_PRIORITY;
} }
if (decode_is_context_tag(&apdu[dec_len], 6)) { if (decode_is_context_tag(&apdu[dec_len], 6)) {
len = len = decode_tag_number_and_value(&apdu[dec_len], &tag_number,
decode_tag_number_and_value(&apdu[dec_len], &tag_number,
&len_value_type); &len_value_type);
dec_len += len; dec_len += len;
len = len = decode_unsigned(&apdu[dec_len], len_value_type, &bcl->Post_Delay);
decode_unsigned(&apdu[dec_len], len_value_type, &bcl->Post_Delay);
if (len < 0) if (len < 0)
return BACNET_STATUS_REJECT; return BACNET_STATUS_REJECT;
dec_len += len; dec_len += len;
@@ -340,25 +306,18 @@ int cl_decode_apdu(
COMMAND_DESCR Command_Descr[MAX_COMMANDS]; COMMAND_DESCR Command_Descr[MAX_COMMANDS];
/* These arrays are used by the ReadPropertyMultiple handler */ /* These arrays are used by the ReadPropertyMultiple handler */
static const int Command_Properties_Required[] = { static const int Command_Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
PROP_IN_PROCESS, PROP_IN_PROCESS,
PROP_ALL_WRITES_SUCCESSFUL, PROP_ALL_WRITES_SUCCESSFUL,
PROP_ACTION, PROP_ACTION,
-1 -1};
};
static const int Command_Properties_Optional[] = { static const int Command_Properties_Optional[] = {PROP_DESCRIPTION, -1};
PROP_DESCRIPTION,
-1
};
static const int Command_Properties_Proprietary[] = { static const int Command_Properties_Proprietary[] = {-1};
-1
};
/** /**
* Returns the list of required, optional, and proprietary properties. * Returns the list of required, optional, and proprietary properties.
@@ -371,9 +330,7 @@ static const int Command_Properties_Proprietary[] = {
* @param pProprietary - pointer to list of int terminated by -1, of * @param pProprietary - pointer to list of int terminated by -1, of
* BACnet proprietary properties for this object. * BACnet proprietary properties for this object.
*/ */
void Command_Property_Lists( void Command_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -386,12 +343,10 @@ void Command_Property_Lists(
return; return;
} }
/** /**
* Initializes the Command object data * Initializes the Command object data
*/ */
void Command_Init( void Command_Init(void)
void)
{ {
unsigned i; unsigned i;
for (i = 0; i < MAX_COMMANDS; i++) { for (i = 0; i < MAX_COMMANDS; i++) {
@@ -408,8 +363,7 @@ void Command_Init(
* *
* @return true if the instance is valid, and false if not * @return true if the instance is valid, and false if not
*/ */
bool Command_Valid_Instance( bool Command_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned int index; unsigned int index;
@@ -425,8 +379,7 @@ bool Command_Valid_Instance(
* *
* @return Number of objects * @return Number of objects
*/ */
unsigned Command_Count( unsigned Command_Count(void)
void)
{ {
return MAX_COMMANDS; return MAX_COMMANDS;
} }
@@ -439,8 +392,7 @@ unsigned Command_Count(
* *
* @return object instance-number for the given index * @return object instance-number for the given index
*/ */
uint32_t Command_Index_To_Instance( uint32_t Command_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -454,8 +406,7 @@ uint32_t Command_Index_To_Instance(
* @return index for the given instance-number, or * @return index for the given instance-number, or
* the total number of this object instances if not valid. * the total number of this object instances if not valid.
*/ */
unsigned Command_Instance_To_Index( unsigned Command_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_COMMANDS; unsigned index = MAX_COMMANDS;
@@ -472,8 +423,7 @@ unsigned Command_Instance_To_Index(
* *
* @return present-value of the object * @return present-value of the object
*/ */
uint32_t Command_Present_Value( uint32_t Command_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
uint32_t value = 0; uint32_t value = 0;
unsigned int index; unsigned int index;
@@ -494,9 +444,7 @@ uint32_t Command_Present_Value(
* *
* @return true if values are within range and present-value is set. * @return true if values are within range and present-value is set.
*/ */
bool Command_Present_Value_Set( bool Command_Present_Value_Set(uint32_t object_instance, uint32_t value)
uint32_t object_instance,
uint32_t value)
{ {
bool status = false; bool status = false;
unsigned int index; unsigned int index;
@@ -521,8 +469,7 @@ bool Command_Present_Value_Set(
* *
* @return true if this object-instance is in-process. * @return true if this object-instance is in-process.
*/ */
bool Command_In_Process( bool Command_In_Process(uint32_t object_instance)
uint32_t object_instance)
{ {
bool value = false; bool value = false;
unsigned int index; unsigned int index;
@@ -543,9 +490,7 @@ bool Command_In_Process(
* *
* @return true if values are within range and in-process flag is set. * @return true if values are within range and in-process flag is set.
*/ */
bool Command_In_Process_Set( bool Command_In_Process_Set(uint32_t object_instance, bool value)
uint32_t object_instance,
bool value)
{ {
bool status = false; bool status = false;
unsigned int index; unsigned int index;
@@ -568,8 +513,7 @@ bool Command_In_Process_Set(
* *
* @return true if all writes were successful for this object-instance * @return true if all writes were successful for this object-instance
*/ */
bool Command_All_Writes_Successful( bool Command_All_Writes_Successful(uint32_t object_instance)
uint32_t object_instance)
{ {
bool value = false; bool value = false;
unsigned int index; unsigned int index;
@@ -590,9 +534,7 @@ bool Command_All_Writes_Successful(
* *
* @return true if values are within range and all-writes-succcessful is set. * @return true if values are within range and all-writes-succcessful is set.
*/ */
bool Command_All_Writes_Successful_Set( bool Command_All_Writes_Successful_Set(uint32_t object_instance, bool value)
uint32_t object_instance,
bool value)
{ {
bool status = false; bool status = false;
unsigned int index; unsigned int index;
@@ -615,8 +557,7 @@ bool Command_All_Writes_Successful_Set(
* *
* @return true if object-name was retrieved * @return true if object-name was retrieved
*/ */
bool Command_Object_Name( bool Command_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -642,8 +583,7 @@ bool Command_Object_Name(
* @return number of APDU bytes in the response, or * @return number of APDU bytes in the response, or
* BACNET_STATUS_ERROR on error. * BACNET_STATUS_ERROR on error.
*/ */
int Command_Read_Property( int Command_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
int len = 0; int len = 0;
@@ -668,8 +608,7 @@ int Command_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch ((int)rpdata->object_property) { switch ((int)rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(&apdu[0], OBJECT_COMMAND,
encode_application_object_id(&apdu[0], OBJECT_COMMAND,
rpdata->object_instance); rpdata->object_instance);
break; break;
@@ -685,24 +624,23 @@ int Command_Read_Property(
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], Command_Present_Value(rpdata->object_instance));
Command_Present_Value(rpdata->object_instance));
break; break;
case PROP_IN_PROCESS: case PROP_IN_PROCESS:
apdu_len = apdu_len = encode_application_boolean(
encode_application_boolean(&apdu[0], &apdu[0], Command_In_Process(rpdata->object_instance));
Command_In_Process(rpdata->object_instance));
break; break;
case PROP_ALL_WRITES_SUCCESSFUL: case PROP_ALL_WRITES_SUCCESSFUL:
apdu_len = apdu_len = encode_application_boolean(
encode_application_boolean(&apdu[0], &apdu[0],
Command_All_Writes_Successful(rpdata->object_instance)); Command_All_Writes_Successful(rpdata->object_instance));
break; break;
case PROP_ACTION: case PROP_ACTION:
/* TODO */ /* TODO */
if (rpdata->array_index == 0) if (rpdata->array_index == 0)
apdu_len = encode_application_unsigned(&apdu[0], MAX_COMMAND_ACTIONS); apdu_len =
encode_application_unsigned(&apdu[0], MAX_COMMAND_ACTIONS);
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
int i; int i;
for (i = 0; i < MAX_COMMAND_ACTIONS; i++) { for (i = 0; i < MAX_COMMAND_ACTIONS; i++) {
@@ -711,11 +649,11 @@ int Command_Read_Property(
/* another loop, for aditional actions in the list */ /* another loop, for aditional actions in the list */
for (; Curr_CL_Member != NULL; for (; Curr_CL_Member != NULL;
Curr_CL_Member = Curr_CL_Member->next) { Curr_CL_Member = Curr_CL_Member->next) {
len = len = cl_encode_apdu(&apdu[apdu_len],
cl_encode_apdu(&apdu[apdu_len],
&CurrentCommand->Action[0]); &CurrentCommand->Action[0]);
apdu_len += len; apdu_len += len;
/* assume the next one is of the same length, which need not be the case */ /* assume the next one is of the same length, which need
* not be the case */
if ((i != MAX_COMMAND_ACTIONS - 1) && if ((i != MAX_COMMAND_ACTIONS - 1) &&
(apdu_len + len) >= apdu_max) { (apdu_len + len) >= apdu_max) {
rpdata->error_code = rpdata->error_code =
@@ -732,11 +670,11 @@ int Command_Read_Property(
/* another loop, for aditional actions in the list */ /* another loop, for aditional actions in the list */
for (; Curr_CL_Member != NULL; for (; Curr_CL_Member != NULL;
Curr_CL_Member = Curr_CL_Member->next) { Curr_CL_Member = Curr_CL_Member->next) {
len = len = cl_encode_apdu(&apdu[apdu_len],
cl_encode_apdu(&apdu[apdu_len],
&CurrentCommand->Action[0]); &CurrentCommand->Action[0]);
apdu_len += len; apdu_len += len;
/* assume the next one is of the same length, which need not be the case */ /* assume the next one is of the same length, which need
* not be the case */
if ((apdu_len + len) >= apdu_max) { if ((apdu_len + len) >= apdu_max) {
rpdata->error_code = rpdata->error_code =
ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED; ERROR_CODE_ABORT_SEGMENTATION_NOT_SUPPORTED;
@@ -758,8 +696,8 @@ int Command_Read_Property(
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->object_property != PROP_ACTION) if ((apdu_len >= 0) && (rpdata->object_property != PROP_ACTION) &&
&& (rpdata->array_index != BACNET_ARRAY_ALL)) { (rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -777,16 +715,14 @@ int Command_Read_Property(
* *
* @return false if an error is loaded, true if no errors * @return false if an error is loaded, true if no errors
*/ */
bool Command_Write_Property( bool Command_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -846,8 +782,7 @@ bool Command_Write_Property(
return status; return status;
} }
void Command_Intrinsic_Reporting( void Command_Intrinsic_Reporting(uint32_t object_instance)
uint32_t object_instance)
{ {
} }
@@ -856,10 +791,8 @@ void Command_Intrinsic_Reporting(
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
bool bResult; bool bResult;
@@ -878,8 +811,7 @@ bool WPValidateArgType(
return (bResult); return (bResult);
} }
void testCommand( void testCommand(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -926,8 +858,7 @@ void testCommand(
ct_test(pTest, clist.Device_Id.instance == clist_test.Device_Id.instance); ct_test(pTest, clist.Device_Id.instance == clist_test.Device_Id.instance);
ct_test(pTest, clist.Object_Id.type == clist_test.Object_Id.type); ct_test(pTest, clist.Object_Id.type == clist_test.Object_Id.type);
ct_test(pTest, clist.Object_Id.instance == clist_test.Object_Id.instance); ct_test(pTest, clist.Object_Id.instance == clist_test.Object_Id.instance);
ct_test(pTest, ct_test(pTest, clist.Property_Identifier == clist_test.Property_Identifier);
clist.Property_Identifier == clist_test.Property_Identifier);
ct_test(pTest, ct_test(pTest,
clist.Property_Array_Index == clist_test.Property_Array_Index); clist.Property_Array_Index == clist_test.Property_Array_Index);
ct_test(pTest, clist.Value.tag == clist_test.Value.tag); ct_test(pTest, clist.Value.tag == clist_test.Value.tag);
@@ -940,8 +871,7 @@ void testCommand(
} }
#ifdef TEST_COMMAND #ifdef TEST_COMMAND
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+57 -89
View File
@@ -44,28 +44,17 @@ static CREDENTIAL_DATA_INPUT_DESCR cdi_descr[MAX_CREDENTIAL_DATA_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_NAME, PROP_OBJECT_TYPE, PROP_PRESENT_VALUE,
PROP_OBJECT_TYPE, PROP_STATUS_FLAGS, PROP_RELIABILITY,
PROP_PRESENT_VALUE, PROP_OUT_OF_SERVICE, PROP_SUPPORTED_FORMATS,
PROP_STATUS_FLAGS, PROP_UPDATE_TIME, -1};
PROP_RELIABILITY,
PROP_OUT_OF_SERVICE,
PROP_SUPPORTED_FORMATS,
PROP_UPDATE_TIME,
-1
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {-1};
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void Credential_Data_Input_Property_Lists( void Credential_Data_Input_Property_Lists(const int **pRequired,
const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
@@ -79,8 +68,7 @@ void Credential_Data_Input_Property_Lists(
return; return;
} }
void Credential_Data_Input_Init( void Credential_Data_Input_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -107,8 +95,7 @@ void Credential_Data_Input_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Credential_Data_Input_Valid_Instance( bool Credential_Data_Input_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_CREDENTIAL_DATA_INPUTS) if (object_instance < MAX_CREDENTIAL_DATA_INPUTS)
return true; return true;
@@ -118,8 +105,7 @@ bool Credential_Data_Input_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Credential_Data_Input_Count( unsigned Credential_Data_Input_Count(void)
void)
{ {
return MAX_CREDENTIAL_DATA_INPUTS; return MAX_CREDENTIAL_DATA_INPUTS;
} }
@@ -127,8 +113,7 @@ unsigned Credential_Data_Input_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Credential_Data_Input_Index_To_Instance( uint32_t Credential_Data_Input_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -136,8 +121,7 @@ uint32_t Credential_Data_Input_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Credential_Data_Input_Instance_To_Index( unsigned Credential_Data_Input_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_CREDENTIAL_DATA_INPUTS; unsigned index = MAX_CREDENTIAL_DATA_INPUTS;
@@ -148,8 +132,7 @@ unsigned Credential_Data_Input_Instance_To_Index(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Credential_Data_Input_Object_Name( bool Credential_Data_Input_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -164,8 +147,7 @@ bool Credential_Data_Input_Object_Name(
return status; return status;
} }
bool Credential_Data_Input_Out_Of_Service( bool Credential_Data_Input_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned index = 0; unsigned index = 0;
bool oos_flag = false; bool oos_flag = false;
@@ -178,9 +160,7 @@ bool Credential_Data_Input_Out_Of_Service(
return oos_flag; return oos_flag;
} }
void Credential_Data_Input_Out_Of_Service_Set( void Credential_Data_Input_Out_Of_Service_Set(uint32_t instance, bool oos_flag)
uint32_t instance,
bool oos_flag)
{ {
unsigned index = 0; unsigned index = 0;
@@ -191,8 +171,7 @@ void Credential_Data_Input_Out_Of_Service_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Credential_Data_Input_Read_Property( int Credential_Data_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -212,9 +191,9 @@ int Credential_Data_Input_Read_Property(
Credential_Data_Input_Instance_To_Index(rpdata->object_instance); Credential_Data_Input_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], &apdu[0], OBJECT_CREDENTIAL_DATA_INPUT,
OBJECT_CREDENTIAL_DATA_INPUT, rpdata->object_instance); rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Credential_Data_Input_Object_Name(rpdata->object_instance, Credential_Data_Input_Object_Name(rpdata->object_instance,
@@ -223,14 +202,12 @@ int Credential_Data_Input_Read_Property(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], OBJECT_CREDENTIAL_DATA_INPUT);
OBJECT_CREDENTIAL_DATA_INPUT);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
apdu_len = apdu_len = bacapp_encode_authentication_factor(
bacapp_encode_authentication_factor(&apdu[apdu_len], &apdu[apdu_len], &cdi_descr[object_index].present_value);
&cdi_descr[object_index].present_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
bitstring_init(&bit_string); bitstring_init(&bit_string);
@@ -243,9 +220,8 @@ int Credential_Data_Input_Read_Property(
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], cdi_descr[object_index].reliability);
cdi_descr[object_index].reliability);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
state = state =
@@ -254,14 +230,13 @@ int Credential_Data_Input_Read_Property(
break; break;
case PROP_SUPPORTED_FORMATS: case PROP_SUPPORTED_FORMATS:
if (rpdata->array_index == 0) { if (rpdata->array_index == 0) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0], cdi_descr[object_index].supported_formats_count);
cdi_descr[object_index].supported_formats_count);
} else if (rpdata->array_index == BACNET_ARRAY_ALL) { } else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 0; i < cdi_descr[object_index].supported_formats_count; for (i = 0; i < cdi_descr[object_index].supported_formats_count;
i++) { i++) {
len = len = bacapp_encode_authentication_factor_format(
bacapp_encode_authentication_factor_format(&apdu[0], &apdu[0],
&cdi_descr[object_index].supported_formats[i]); &cdi_descr[object_index].supported_formats[i]);
if (apdu_len + len < MAX_APDU) if (apdu_len + len < MAX_APDU)
apdu_len += len; apdu_len += len;
@@ -275,10 +250,10 @@ int Credential_Data_Input_Read_Property(
} else { } else {
if (rpdata->array_index <= if (rpdata->array_index <=
cdi_descr[object_index].supported_formats_count) { cdi_descr[object_index].supported_formats_count) {
apdu_len = apdu_len = bacapp_encode_authentication_factor_format(
bacapp_encode_authentication_factor_format(&apdu[0], &apdu[0],
&cdi_descr[object_index]. &cdi_descr[object_index]
supported_formats[rpdata->array_index - 1]); .supported_formats[rpdata->array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -288,9 +263,8 @@ int Credential_Data_Input_Read_Property(
break; break;
case PROP_UPDATE_TIME: case PROP_UPDATE_TIME:
apdu_len = apdu_len = bacapp_encode_timestamp(
bacapp_encode_timestamp(&apdu[0], &apdu[0], &cdi_descr[object_index].timestamp);
&cdi_descr[object_index].timestamp);
break; break;
default: default:
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -299,8 +273,9 @@ int Credential_Data_Input_Read_Property(
break; break;
} }
/* only array properties can have array options */ /* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->object_property != PROP_SUPPORTED_FORMATS) if ((apdu_len >= 0) &&
&& (rpdata->array_index != BACNET_ARRAY_ALL)) { (rpdata->object_property != PROP_SUPPORTED_FORMATS) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR; apdu_len = BACNET_STATUS_ERROR;
@@ -310,8 +285,7 @@ int Credential_Data_Input_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Credential_Data_Input_Write_Property( bool Credential_Data_Input_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
@@ -319,8 +293,7 @@ bool Credential_Data_Input_Write_Property(
unsigned object_index = 0; unsigned object_index = 0;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -336,14 +309,15 @@ bool Credential_Data_Input_Write_Property(
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY; wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false; return false;
} }
object_index = Credential_Data_Input_Instance_To_Index(wp_data->object_instance); object_index =
Credential_Data_Input_Instance_To_Index(wp_data->object_instance);
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
if (Credential_Data_Input_Out_Of_Service(wp_data->object_instance)) { if (Credential_Data_Input_Out_Of_Service(
wp_data->object_instance)) {
BACNET_AUTHENTICATION_FACTOR tmp; BACNET_AUTHENTICATION_FACTOR tmp;
len = len = bacapp_decode_authentication_factor(
bacapp_decode_authentication_factor(wp_data-> wp_data->application_data, &tmp);
application_data, &tmp);
if (len > 0) { if (len > 0) {
memcpy(&cdi_descr[object_index].present_value, &tmp, memcpy(&cdi_descr[object_index].present_value, &tmp,
sizeof(BACNET_AUTHENTICATION_FACTOR)); sizeof(BACNET_AUTHENTICATION_FACTOR));
@@ -357,14 +331,13 @@ bool Credential_Data_Input_Write_Property(
} }
break; break;
case PROP_RELIABILITY: case PROP_RELIABILITY:
if (Credential_Data_Input_Out_Of_Service(wp_data->object_instance)) { if (Credential_Data_Input_Out_Of_Service(
status = wp_data->object_instance)) {
WPValidateArgType(&value, status = WPValidateArgType(
BACNET_APPLICATION_TAG_ENUMERATED, &wp_data->error_class, &value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
cdi_descr[object_index].reliability = cdi_descr[object_index].reliability = value.type.Enumerated;
value.type.Enumerated;
} }
} else { } else {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -390,16 +363,13 @@ bool Credential_Data_Input_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -410,8 +380,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testCredentialDataInput( void testCredentialDataInput(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -440,8 +409,7 @@ void testCredentialDataInput(
} }
#ifdef TEST_CREDENTIAL_DATA_INPUT #ifdef TEST_CREDENTIAL_DATA_INPUT
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+42 -79
View File
@@ -52,27 +52,15 @@ static char Object_Description[MAX_CHARACTERSTRING_VALUES][64];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Properties_Required[] = { static const int Properties_Required[] = {
PROP_OBJECT_IDENTIFIER, PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME, PROP_OBJECT_TYPE,
PROP_OBJECT_NAME, PROP_PRESENT_VALUE, PROP_STATUS_FLAGS, -1};
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
-1
};
static const int Properties_Optional[] = { static const int Properties_Optional[] = {PROP_EVENT_STATE, PROP_OUT_OF_SERVICE,
PROP_EVENT_STATE, PROP_DESCRIPTION, -1};
PROP_OUT_OF_SERVICE,
PROP_DESCRIPTION,
-1
};
static const int Properties_Proprietary[] = { static const int Properties_Proprietary[] = {-1};
-1
};
void CharacterString_Value_Property_Lists( void CharacterString_Value_Property_Lists(const int **pRequired,
const int **pRequired,
const int **pOptional, const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
@@ -86,8 +74,7 @@ void CharacterString_Value_Property_Lists(
return; return;
} }
void CharacterString_Value_Init( void CharacterString_Value_Init(void)
void)
{ {
unsigned i; unsigned i;
@@ -106,8 +93,7 @@ void CharacterString_Value_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned CharacterString_Value_Instance_To_Index( unsigned CharacterString_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_CHARACTERSTRING_VALUES; unsigned index = MAX_CHARACTERSTRING_VALUES;
@@ -121,22 +107,19 @@ unsigned CharacterString_Value_Instance_To_Index(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t CharacterString_Value_Index_To_Instance( uint32_t CharacterString_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned CharacterString_Value_Count( unsigned CharacterString_Value_Count(void)
void)
{ {
return MAX_CHARACTERSTRING_VALUES; return MAX_CHARACTERSTRING_VALUES;
} }
bool CharacterString_Value_Valid_Instance( bool CharacterString_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
@@ -148,8 +131,7 @@ bool CharacterString_Value_Valid_Instance(
return false; return false;
} }
bool CharacterString_Value_Present_Value( bool CharacterString_Value_Present_Value(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
bool status = false; bool status = false;
@@ -164,8 +146,7 @@ bool CharacterString_Value_Present_Value(
} }
bool CharacterString_Value_Present_Value_Set( bool CharacterString_Value_Present_Value_Set(
uint32_t object_instance, uint32_t object_instance, BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
bool status = false; bool status = false;
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
@@ -178,8 +159,7 @@ bool CharacterString_Value_Present_Value_Set(
return status; return status;
} }
bool CharacterString_Value_Out_Of_Service( bool CharacterString_Value_Out_Of_Service(uint32_t object_instance)
uint32_t object_instance)
{ {
bool value = false; bool value = false;
unsigned index = 0; unsigned index = 0;
@@ -192,8 +172,7 @@ bool CharacterString_Value_Out_Of_Service(
return value; return value;
} }
static void CharacterString_Value_Out_Of_Service_Set( static void CharacterString_Value_Out_Of_Service_Set(uint32_t object_instance,
uint32_t object_instance,
bool value) bool value)
{ {
unsigned index = 0; unsigned index = 0;
@@ -206,8 +185,7 @@ static void CharacterString_Value_Out_Of_Service_Set(
return; return;
} }
static char *CharacterString_Value_Description( static char *CharacterString_Value_Description(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
char *pName = NULL; /* return value */ char *pName = NULL; /* return value */
@@ -220,8 +198,7 @@ static char *CharacterString_Value_Description(
return pName; return pName;
} }
bool CharacterString_Value_Description_Set( bool CharacterString_Value_Description_Set(uint32_t object_instance,
uint32_t object_instance,
char *new_name) char *new_name)
{ {
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
@@ -248,8 +225,7 @@ bool CharacterString_Value_Description_Set(
return status; return status;
} }
bool CharacterString_Value_Object_Name( bool CharacterString_Value_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
@@ -264,9 +240,7 @@ bool CharacterString_Value_Object_Name(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool CharacterString_Value_Name_Set( bool CharacterString_Value_Name_Set(uint32_t object_instance, char *new_name)
uint32_t object_instance,
char *new_name)
{ {
unsigned index = 0; /* offset from instance lookup */ unsigned index = 0; /* offset from instance lookup */
size_t i = 0; /* loop counter */ size_t i = 0; /* loop counter */
@@ -294,8 +268,7 @@ bool CharacterString_Value_Name_Set(
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int CharacterString_Value_Read_Property( int CharacterString_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -311,9 +284,9 @@ int CharacterString_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], &apdu[0], OBJECT_CHARACTERSTRING_VALUE,
OBJECT_CHARACTERSTRING_VALUE, rpdata->object_instance); rpdata->object_instance);
break; break;
/* note: Name and Description don't have to be the same. /* note: Name and Description don't have to be the same.
You could make Description writable and different */ You could make Description writable and different */
@@ -324,15 +297,15 @@ int CharacterString_Value_Read_Property(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
characterstring_init_ansi(&char_string, characterstring_init_ansi(
&char_string,
CharacterString_Value_Description(rpdata->object_instance)); CharacterString_Value_Description(rpdata->object_instance));
apdu_len = apdu_len =
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_OBJECT_TYPE: case PROP_OBJECT_TYPE:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], OBJECT_CHARACTERSTRING_VALUE);
OBJECT_CHARACTERSTRING_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
CharacterString_Value_Present_Value(rpdata->object_instance, CharacterString_Value_Present_Value(rpdata->object_instance,
@@ -361,9 +334,8 @@ int CharacterString_Value_Read_Property(
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL); encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
object_index = object_index = CharacterString_Value_Instance_To_Index(
CharacterString_Value_Instance_To_Index rpdata->object_instance);
(rpdata->object_instance);
state = Out_Of_Service[object_index]; state = Out_Of_Service[object_index];
apdu_len = encode_application_boolean(&apdu[0], state); apdu_len = encode_application_boolean(&apdu[0], state);
break; break;
@@ -385,16 +357,14 @@ int CharacterString_Value_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool CharacterString_Value_Write_Property( bool CharacterString_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -405,14 +375,12 @@ bool CharacterString_Value_Write_Property(
} }
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
status = status = WPValidateArgType(
WPValidateArgType(&value, &value, BACNET_APPLICATION_TAG_CHARACTER_STRING,
BACNET_APPLICATION_TAG_CHARACTER_STRING, &wp_data->error_class, &wp_data->error_class, &wp_data->error_code);
&wp_data->error_code);
if (status) { if (status) {
status = status = CharacterString_Value_Present_Value_Set(
CharacterString_Value_Present_Value_Set wp_data->object_instance, &value.type.Character_String);
(wp_data->object_instance, &value.type.Character_String);
if (!status) { if (!status) {
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
@@ -424,8 +392,8 @@ bool CharacterString_Value_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
CharacterString_Value_Out_Of_Service_Set CharacterString_Value_Out_Of_Service_Set(
(wp_data->object_instance, value.type.Boolean); wp_data->object_instance, value.type.Boolean);
} }
break; break;
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
@@ -446,16 +414,13 @@ bool CharacterString_Value_Write_Property(
return status; return status;
} }
#ifdef TEST #ifdef TEST
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "ctest.h" #include "ctest.h"
bool WPValidateArgType( bool WPValidateArgType(BACNET_APPLICATION_DATA_VALUE *pValue,
BACNET_APPLICATION_DATA_VALUE * pValue, uint8_t ucExpectedTag, BACNET_ERROR_CLASS *pErrorClass,
uint8_t ucExpectedTag,
BACNET_ERROR_CLASS * pErrorClass,
BACNET_ERROR_CODE *pErrorCode) BACNET_ERROR_CODE *pErrorCode)
{ {
pValue = pValue; pValue = pValue;
@@ -466,8 +431,7 @@ bool WPValidateArgType(
return false; return false;
} }
void testCharacterStringValue( void testCharacterStringValue(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -496,8 +460,7 @@ void testCharacterStringValue(
} }
#ifdef TEST_CHARACTERSTRING_VALUE #ifdef TEST_CHARACTERSTRING_VALUE
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;
+91 -168
View File
@@ -112,68 +112,40 @@ static uint32_t Database_Revision = 0;
/* Profile_Name */ /* Profile_Name */
/* local forward (semi-private) and external prototypes */ /* local forward (semi-private) and external prototypes */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
BACNET_READ_PROPERTY_DATA * rpdata); extern int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
extern int Routed_Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata);
extern bool Routed_Device_Write_Property_Local( extern bool Routed_Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA *wp_data); BACNET_WRITE_PROPERTY_DATA *wp_data);
/* All included BACnet objects */ /* All included BACnet objects */
static object_functions_t Object_Table[] = { static object_functions_t Object_Table[] = {
{OBJECT_DEVICE, {OBJECT_DEVICE, NULL /* Init - don't init Device or it will recourse! */,
NULL /* Init - don't init Device or it will recourse! */ , Device_Count, Device_Index_To_Instance,
Device_Count, Device_Valid_Object_Instance_Number, Device_Object_Name,
Device_Index_To_Instance, Device_Read_Property_Local, NULL /* Write_Property */,
Device_Valid_Object_Instance_Number, NULL /* Property_Lists */, NULL /* ReadRangeInfo */, NULL /* Iterator */,
Device_Object_Name, NULL /* Value_Lists */, NULL /* COV */, NULL /* COV Clear */,
Device_Read_Property_Local,
NULL /* Write_Property */ ,
NULL /* Property_Lists */ ,
NULL /* ReadRangeInfo */ ,
NULL /* Iterator */ ,
NULL /* Value_Lists */ ,
NULL /* COV */ ,
NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */}, NULL /* Intrinsic Reporting */},
#if (BACNET_PROTOCOL_REVISION >= 17) #if (BACNET_PROTOCOL_REVISION >= 17)
{OBJECT_NETWORK_PORT, {OBJECT_NETWORK_PORT, Network_Port_Init, Network_Port_Count,
Network_Port_Init, Network_Port_Index_To_Instance, Network_Port_Valid_Instance,
Network_Port_Count, Network_Port_Object_Name, Network_Port_Read_Property,
Network_Port_Index_To_Instance, Network_Port_Write_Property, Network_Port_Property_Lists,
Network_Port_Valid_Instance, NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
Network_Port_Object_Name, NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */},
Network_Port_Read_Property,
Network_Port_Write_Property,
Network_Port_Property_Lists,
NULL /* ReadRangeInfo */ ,
NULL /* Iterator */ ,
NULL /* Value_Lists */ ,
NULL /* COV */ ,
NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ },
#endif #endif
{MAX_BACNET_OBJECT_TYPE, {MAX_BACNET_OBJECT_TYPE, NULL /* Init */, NULL /* Count */,
NULL /* Init */ , NULL /* Index_To_Instance */, NULL /* Valid_Instance */,
NULL /* Count */ , NULL /* Object_Name */, NULL /* Read_Property */,
NULL /* Index_To_Instance */ , NULL /* Write_Property */, NULL /* Property_Lists */,
NULL /* Valid_Instance */ , NULL /* ReadRangeInfo */, NULL /* Iterator */, NULL /* Value_Lists */,
NULL /* Object_Name */ , NULL /* COV */, NULL /* COV Clear */, NULL /* Intrinsic Reporting */}};
NULL /* Read_Property */ ,
NULL /* Write_Property */ ,
NULL /* Property_Lists */ ,
NULL /* ReadRangeInfo */ ,
NULL /* Iterator */ ,
NULL /* Value_Lists */ ,
NULL /* COV */ ,
NULL /* COV Clear */ ,
NULL /* Intrinsic Reporting */ }
};
/** Glue function to let the Device object, when called by a handler, /** Glue function to let the Device object, when called by a handler,
* lookup which Object type needs to be invoked. * lookup which Object type needs to be invoked.
* @ingroup ObjHelpers * @ingroup ObjHelpers
* @param Object_Type [in] The type of BACnet Object the handler wants to access. * @param Object_Type [in] The type of BACnet Object the handler wants to
* access.
* @return Pointer to the group of object helper functions that implement this * @return Pointer to the group of object helper functions that implement this
* type of Object. * type of Object.
*/ */
@@ -195,14 +167,12 @@ static struct object_functions *Device_Objects_Find_Functions(
return (NULL); return (NULL);
} }
unsigned Device_Count( unsigned Device_Count(void)
void)
{ {
return 1; return 1;
} }
uint32_t Device_Index_To_Instance( uint32_t Device_Index_To_Instance(unsigned index)
unsigned index)
{ {
index = index; index = index;
return Object_Instance_Number; return Object_Instance_Number;
@@ -216,8 +186,7 @@ uint32_t Device_Index_To_Instance(
* @ingroup ObjIntf * @ingroup ObjIntf
* @return The Instance number used in the BACNET_OBJECT_ID for the Device. * @return The Instance number used in the BACNET_OBJECT_ID for the Device.
*/ */
uint32_t Device_Object_Instance_Number( uint32_t Device_Object_Instance_Number(void)
void)
{ {
#ifdef BAC_ROUTING #ifdef BAC_ROUTING
return Routed_Device_Object_Instance_Number(); return Routed_Device_Object_Instance_Number();
@@ -226,8 +195,7 @@ uint32_t Device_Object_Instance_Number(
#endif #endif
} }
bool Device_Set_Object_Instance_Number( bool Device_Set_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
@@ -241,14 +209,12 @@ bool Device_Set_Object_Instance_Number(
return status; return status;
} }
bool Device_Valid_Object_Instance_Number( bool Device_Valid_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
return (Object_Instance_Number == object_id); return (Object_Instance_Number == object_id);
} }
bool Device_Object_Name( bool Device_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
bool status = false; bool status = false;
@@ -260,8 +226,7 @@ bool Device_Object_Name(
return status; return status;
} }
bool Device_Set_Object_Name( bool Device_Set_Object_Name(BACNET_CHARACTER_STRING *object_name)
BACNET_CHARACTER_STRING * object_name)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -274,15 +239,12 @@ bool Device_Set_Object_Name(
return status; return status;
} }
BACNET_DEVICE_STATUS Device_System_Status( BACNET_DEVICE_STATUS Device_System_Status(void)
void)
{ {
return System_Status; return System_Status;
} }
int Device_Set_System_Status( int Device_Set_System_Status(BACNET_DEVICE_STATUS status, bool local)
BACNET_DEVICE_STATUS status,
bool local)
{ {
int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */ int result = 0; /*return value - 0 = ok, -1 = bad value, -2 = not allowed */
@@ -345,37 +307,32 @@ int Device_Set_System_Status(
return (result); return (result);
} }
const char *Device_Vendor_Name( const char *Device_Vendor_Name(void)
void)
{ {
return Vendor_Name; return Vendor_Name;
} }
/** Returns the Vendor ID for this Device. /** Returns the Vendor ID for this Device.
* See the assignments at http://www.bacnet.org/VendorID/BACnet%20Vendor%20IDs.htm * See the assignments at
* http://www.bacnet.org/VendorID/BACnet%20Vendor%20IDs.htm
* @return The Vendor ID of this Device. * @return The Vendor ID of this Device.
*/ */
uint16_t Device_Vendor_Identifier( uint16_t Device_Vendor_Identifier(void)
void)
{ {
return Vendor_Identifier; return Vendor_Identifier;
} }
void Device_Set_Vendor_Identifier( void Device_Set_Vendor_Identifier(uint16_t vendor_id)
uint16_t vendor_id)
{ {
Vendor_Identifier = vendor_id; Vendor_Identifier = vendor_id;
} }
const char *Device_Model_Name( const char *Device_Model_Name(void)
void)
{ {
return Model_Name; return Model_Name;
} }
bool Device_Set_Model_Name( bool Device_Set_Model_Name(const char *name, size_t length)
const char *name,
size_t length)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -388,21 +345,17 @@ bool Device_Set_Model_Name(
return status; return status;
} }
const char *Device_Firmware_Revision( const char *Device_Firmware_Revision(void)
void)
{ {
return BACnet_Version; return BACnet_Version;
} }
const char *Device_Application_Software_Version( const char *Device_Application_Software_Version(void)
void)
{ {
return Application_Software_Version; return Application_Software_Version;
} }
bool Device_Set_Application_Software_Version( bool Device_Set_Application_Software_Version(const char *name, size_t length)
const char *name,
size_t length)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -415,15 +368,12 @@ bool Device_Set_Application_Software_Version(
return status; return status;
} }
const char *Device_Description( const char *Device_Description(void)
void)
{ {
return Description; return Description;
} }
bool Device_Set_Description( bool Device_Set_Description(const char *name, size_t length)
const char *name,
size_t length)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -436,15 +386,12 @@ bool Device_Set_Description(
return status; return status;
} }
const char *Device_Location( const char *Device_Location(void)
void)
{ {
return Location; return Location;
} }
bool Device_Set_Location( bool Device_Set_Location(const char *name, size_t length)
const char *name,
size_t length)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -457,32 +404,27 @@ bool Device_Set_Location(
return status; return status;
} }
uint8_t Device_Protocol_Version( uint8_t Device_Protocol_Version(void)
void)
{ {
return BACNET_PROTOCOL_VERSION; return BACNET_PROTOCOL_VERSION;
} }
uint8_t Device_Protocol_Revision( uint8_t Device_Protocol_Revision(void)
void)
{ {
return BACNET_PROTOCOL_REVISION; return BACNET_PROTOCOL_REVISION;
} }
BACNET_SEGMENTATION Device_Segmentation_Supported( BACNET_SEGMENTATION Device_Segmentation_Supported(void)
void)
{ {
return SEGMENTATION_NONE; return SEGMENTATION_NONE;
} }
uint32_t Device_Database_Revision( uint32_t Device_Database_Revision(void)
void)
{ {
return Database_Revision; return Database_Revision;
} }
void Device_Set_Database_Revision( void Device_Set_Database_Revision(uint32_t revision)
uint32_t revision)
{ {
Database_Revision = revision; Database_Revision = revision;
} }
@@ -492,8 +434,7 @@ void Device_Set_Database_Revision(
* the most common operation if changing object names and ids is * the most common operation if changing object names and ids is
* implemented. * implemented.
*/ */
void Device_Inc_Database_Revision( void Device_Inc_Database_Revision(void)
void)
{ {
Database_Revision++; Database_Revision++;
} }
@@ -503,8 +444,7 @@ void Device_Inc_Database_Revision(
* for discovery, it must be consistent! * for discovery, it must be consistent!
* @return The count of objects, for all supported Object types. * @return The count of objects, for all supported Object types.
*/ */
unsigned Device_Object_List_Count( unsigned Device_Object_List_Count(void)
void)
{ {
unsigned count = 0; /* number of objects */ unsigned count = 0; /* number of objects */
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
@@ -531,9 +471,7 @@ unsigned Device_Object_List_Count(
* @param instance [out] The object's instance number, if found. * @param instance [out] The object's instance number, if found.
* @return True if found, else false. * @return True if found, else false.
*/ */
bool Device_Object_List_Identifier( bool Device_Object_List_Identifier(uint32_t array_index, int *object_type,
uint32_t array_index,
int *object_type,
uint32_t *instance) uint32_t *instance)
{ {
bool status = false; bool status = false;
@@ -564,13 +502,13 @@ bool Device_Object_List_Identifier(
temp_index = pObject->Object_Iterator(temp_index); temp_index = pObject->Object_Iterator(temp_index);
object_index--; object_index--;
} }
/* set the object_index up before falling through to next bit */ /* set the object_index up before falling through to next
* bit */
object_index = temp_index; object_index = temp_index;
} }
if (pObject->Object_Index_To_Instance) { if (pObject->Object_Index_To_Instance) {
*object_type = pObject->Object_Type; *object_type = pObject->Object_Type;
*instance = *instance = pObject->Object_Index_To_Instance(object_index);
pObject->Object_Index_To_Instance(object_index);
status = true; status = true;
break; break;
} }
@@ -587,13 +525,12 @@ bool Device_Object_List_Identifier(
* and the lookup succeeds, they will be given the resulting values. * and the lookup succeeds, they will be given the resulting values.
* @param object_name [in] The desired Object Name to look for. * @param object_name [in] The desired Object Name to look for.
* @param object_type [out] The BACNET_OBJECT_TYPE of the matching Object. * @param object_type [out] The BACNET_OBJECT_TYPE of the matching Object.
* @param object_instance [out] The object instance number of the matching Object. * @param object_instance [out] The object instance number of the matching
* Object.
* @return True on success or else False if not found. * @return True on success or else False if not found.
*/ */
bool Device_Valid_Object_Name( bool Device_Valid_Object_Name(BACNET_CHARACTER_STRING *object_name1,
BACNET_CHARACTER_STRING * object_name1, int *object_type, uint32_t *object_instance)
int *object_type,
uint32_t * object_instance)
{ {
bool found = false; bool found = false;
int type = 0; int type = 0;
@@ -631,9 +568,7 @@ bool Device_Valid_Object_Name(
* @param object_instance [in] The object instance number to be looked up. * @param object_instance [in] The object instance number to be looked up.
* @return True if found, else False if no such Object in this device. * @return True if found, else False if no such Object in this device.
*/ */
bool Device_Valid_Object_Id( bool Device_Valid_Object_Id(int object_type, uint32_t object_instance)
int object_type,
uint32_t object_instance)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
@@ -652,8 +587,7 @@ bool Device_Valid_Object_Id(
* @param object_name [out] The Object Name found for this child Object. * @param object_name [out] The Object Name found for this child Object.
* @return True on success or else False if not found. * @return True on success or else False if not found.
*/ */
bool Device_Object_Name_Copy( bool Device_Object_Name_Copy(BACNET_OBJECT_TYPE object_type,
BACNET_OBJECT_TYPE object_type,
uint32_t object_instance, uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
@@ -668,8 +602,7 @@ bool Device_Object_Name_Copy(
return found; return found;
} }
static void Update_Current_Time( static void Update_Current_Time(void)
void)
{ {
struct tm *tblock = NULL; struct tm *tblock = NULL;
#if defined(_MSC_VER) #if defined(_MSC_VER)
@@ -701,7 +634,8 @@ int tm_isdst Daylight Savings flag.
if (tblock) { if (tblock) {
datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900, datetime_set_date(&Local_Date, (uint16_t)tblock->tm_year + 1900,
(uint8_t) tblock->tm_mon + 1, (uint8_t) tblock->tm_mday); (uint8_t)tblock->tm_mon + 1,
(uint8_t)tblock->tm_mday);
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour, datetime_set_time(&Local_Time, (uint8_t)tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, (uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
@@ -724,8 +658,7 @@ int tm_isdst Daylight Savings flag.
} }
} }
void Device_getCurrentDateTime( void Device_getCurrentDateTime(BACNET_DATE_TIME *DateTime)
BACNET_DATE_TIME * DateTime)
{ {
Update_Current_Time(); Update_Current_Time();
@@ -821,8 +754,7 @@ uint32_t Device_Interval_Offset(void)
/* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or /* return the length of the apdu encoded or BACNET_STATUS_ERROR for error or
BACNET_STATUS_ABORT for abort message */ BACNET_STATUS_ABORT for abort message */
int Device_Read_Property_Local( int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
int len = 0; /* apdu len intermediate value */ int len = 0; /* apdu len intermediate value */
@@ -843,8 +775,7 @@ int Device_Read_Property_Local(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(&apdu[0], OBJECT_DEVICE,
encode_application_object_id(&apdu[0], OBJECT_DEVICE,
Object_Instance_Number); Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
@@ -868,8 +799,7 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_VENDOR_IDENTIFIER: case PROP_VENDOR_IDENTIFIER:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0], Vendor_Identifier);
encode_application_unsigned(&apdu[0], Vendor_Identifier);
break; break;
case PROP_MODEL_NAME: case PROP_MODEL_NAME:
characterstring_init_ansi(&char_string, Model_Name); characterstring_init_ansi(&char_string, Model_Name);
@@ -893,13 +823,11 @@ int Device_Read_Property_Local(
encode_application_character_string(&apdu[0], &char_string); encode_application_character_string(&apdu[0], &char_string);
break; break;
case PROP_PROTOCOL_VERSION: case PROP_PROTOCOL_VERSION:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0],
encode_application_unsigned(&apdu[0],
Device_Protocol_Version()); Device_Protocol_Version());
break; break;
case PROP_PROTOCOL_REVISION: case PROP_PROTOCOL_REVISION:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0],
encode_application_unsigned(&apdu[0],
Device_Protocol_Revision()); Device_Protocol_Revision());
break; break;
case PROP_PROTOCOL_SERVICES_SUPPORTED: case PROP_PROTOCOL_SERVICES_SUPPORTED:
@@ -907,7 +835,8 @@ int Device_Read_Property_Local(
bitstring_init(&bit_string); bitstring_init(&bit_string);
for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) { for (i = 0; i < MAX_BACNET_SERVICES_SUPPORTED; i++) {
/* automatic lookup based on handlers set */ /* automatic lookup based on handlers set */
bitstring_set_bit(&bit_string, (uint8_t) i, bitstring_set_bit(
&bit_string, (uint8_t)i,
apdu_service_supported((BACNET_SERVICES_SUPPORTED)i)); apdu_service_supported((BACNET_SERVICES_SUPPORTED)i));
} }
apdu_len = encode_application_bitstring(&apdu[0], &bit_string); apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
@@ -942,16 +871,15 @@ int Device_Read_Property_Local(
/* your maximum APDU size. */ /* your maximum APDU size. */
else if (rpdata->array_index == BACNET_ARRAY_ALL) { else if (rpdata->array_index == BACNET_ARRAY_ALL) {
for (i = 1; i <= count; i++) { for (i = 1; i <= count; i++) {
found = found = Device_Object_List_Identifier(i, &object_type,
Device_Object_List_Identifier(i, &object_type,
&instance); &instance);
if (found) { if (found) {
len = len = encode_application_object_id(
encode_application_object_id(&apdu[apdu_len], &apdu[apdu_len], object_type, instance);
object_type, instance);
apdu_len += len; apdu_len += len;
/* assume next one is the same size as this one */ /* assume next one is the same size as this one */
/* can we all fit into the APDU? Don't check for last entry */ /* can we all fit into the APDU? Don't check for last
* entry */
if ((i != count) && (apdu_len + len) >= MAX_APDU) { if ((i != count) && (apdu_len + len) >= MAX_APDU) {
/* Abort response */ /* Abort response */
rpdata->error_code = rpdata->error_code =
@@ -968,13 +896,11 @@ int Device_Read_Property_Local(
} }
} }
} else { } else {
found = found = Device_Object_List_Identifier(rpdata->array_index,
Device_Object_List_Identifier(rpdata->array_index,
&object_type, &instance); &object_type, &instance);
if (found) { if (found) {
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], object_type, &apdu[0], object_type, instance);
instance);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -986,9 +912,8 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU); apdu_len = encode_application_unsigned(&apdu[0], MAX_APDU);
break; break;
case PROP_SEGMENTATION_SUPPORTED: case PROP_SEGMENTATION_SUPPORTED:
apdu_len = apdu_len = encode_application_enumerated(
encode_application_enumerated(&apdu[0], &apdu[0], Device_Segmentation_Supported());
Device_Segmentation_Supported());
break; break;
case PROP_APDU_TIMEOUT: case PROP_APDU_TIMEOUT:
apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout()); apdu_len = encode_application_unsigned(&apdu[0], apdu_timeout());
@@ -997,18 +922,17 @@ int Device_Read_Property_Local(
apdu_len = encode_application_unsigned(&apdu[0], apdu_retries()); apdu_len = encode_application_unsigned(&apdu[0], apdu_retries());
break; break;
case PROP_DEVICE_ADDRESS_BINDING: case PROP_DEVICE_ADDRESS_BINDING:
/* FIXME: the real max apdu remaining should be passed into function */ /* FIXME: the real max apdu remaining should be passed into function
*/
apdu_len = address_list_encode(&apdu[0], MAX_APDU); apdu_len = address_list_encode(&apdu[0], MAX_APDU);
break; break;
case PROP_DATABASE_REVISION: case PROP_DATABASE_REVISION:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0], Database_Revision);
encode_application_unsigned(&apdu[0], Database_Revision);
break; break;
#if defined(BACDL_MSTP) #if defined(BACDL_MSTP)
case PROP_MAX_INFO_FRAMES: case PROP_MAX_INFO_FRAMES:
apdu_len = apdu_len =
encode_application_unsigned(&apdu[0], encode_application_unsigned(&apdu[0], dlmstp_max_info_frames());
dlmstp_max_info_frames());
break; break;
case PROP_MAX_MASTER: case PROP_MAX_MASTER:
apdu_len = apdu_len =
@@ -1034,7 +958,8 @@ int Device_Read_Property_Local(
return apdu_len; return apdu_len;
} }
/** Looks up the requested Object and Property, and encodes its Value in an APDU. /** Looks up the requested Object and Property, and encodes its Value in an
* APDU.
* @ingroup ObjIntf * @ingroup ObjIntf
* If the Object or Property can't be found, sets the error class and code. * If the Object or Property can't be found, sets the error class and code.
* *
@@ -1042,8 +967,7 @@ int Device_Read_Property_Local(
* on entry, and APDU message on return. * on entry, and APDU message on return.
* @return The length of the APDU on success, else BACNET_STATUS_ERROR * @return The length of the APDU on success, else BACNET_STATUS_ERROR
*/ */
int Device_Read_Property( int Device_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = BACNET_STATUS_ERROR; int apdu_len = BACNET_STATUS_ERROR;
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
@@ -1078,8 +1002,7 @@ int Device_Read_Property(
* Each Child Object must provide some implementation of each of these * Each Child Object must provide some implementation of each of these
* functions in order to properly support the default handlers. * functions in order to properly support the default handlers.
*/ */
void Device_Init( void Device_Init(object_functions_t *object_table)
object_functions_t * object_table)
{ {
struct object_functions *pObject = NULL; struct object_functions *pObject = NULL;
+286 -593
View File
File diff suppressed because it is too large Load Diff
+61 -100
View File
@@ -23,7 +23,8 @@
* *
*********************************************************************/ *********************************************************************/
/** @file gw_device.c Functions that extend the Device object to support routing. */ /** @file gw_device.c Functions that extend the Device object to support
* routing. */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
@@ -68,19 +69,15 @@ long int timezone;
#endif #endif
/* local forward and external prototypes */ /* local forward and external prototypes */
extern int Device_Read_Property_Local( extern int Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
BACNET_READ_PROPERTY_DATA * rpdata); extern bool Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
extern bool Device_Write_Property_Local( int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata);
BACNET_WRITE_PROPERTY_DATA * wp_data); bool Routed_Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data);
int Routed_Device_Read_Property_Local(
BACNET_READ_PROPERTY_DATA * rpdata);
bool Routed_Device_Write_Property_Local(
BACNET_WRITE_PROPERTY_DATA * wp_data);
#if !defined(BAC_ROUTING) #if !defined(BAC_ROUTING)
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma message This file should not be included in the build unless BAC_ROUTING is enabled. #pragma message This file should not be included in the build unless \
BAC_ROUTING is enabled.
#else #else
#warning This file should not be included in the build unless BAC_ROUTING is enabled. #warning This file should not be included in the build unless BAC_ROUTING is enabled.
#endif #endif
@@ -118,8 +115,7 @@ uint16_t iCurrent_Device_Idx = 0;
* @return The index of this instance in the Devices[] array, * @return The index of this instance in the Devices[] array,
* or -1 if there isn't enough room to add this Device. * or -1 if there isn't enough room to add this Device.
*/ */
uint16_t Add_Routed_Device( uint16_t Add_Routed_Device(uint32_t Object_Instance,
uint32_t Object_Instance,
BACNET_CHARACTER_STRING *sObject_Name, BACNET_CHARACTER_STRING *sObject_Name,
const char *sDescription) const char *sDescription)
{ {
@@ -132,7 +128,8 @@ uint16_t Add_Routed_Device(
pDev->bacObj.Object_Instance_Number = Object_Instance; pDev->bacObj.Object_Instance_Number = Object_Instance;
if (sObject_Name != NULL) if (sObject_Name != NULL)
Routed_Device_Set_Object_Name(sObject_Name->encoding, Routed_Device_Set_Object_Name(sObject_Name->encoding,
sObject_Name->value, sObject_Name->length); sObject_Name->value,
sObject_Name->length);
else else
Routed_Device_Set_Object_Name(CHARACTER_UTF8, "No Name", Routed_Device_Set_Object_Name(CHARACTER_UTF8, "No Name",
strlen("No Name")); strlen("No Name"));
@@ -146,7 +143,6 @@ uint16_t Add_Routed_Device(
return -1; return -1;
} }
/** Return the Device Object descriptive data for the indicated entry. /** Return the Device Object descriptive data for the indicated entry.
* @param idx [in] Index into Devices[] array being requested. * @param idx [in] Index into Devices[] array being requested.
* 0 is for the main, gateway Device entry. * 0 is for the main, gateway Device entry.
@@ -156,8 +152,7 @@ uint16_t Add_Routed_Device(
* @return Pointer to the requested Device Object data, or NULL if the idx * @return Pointer to the requested Device Object data, or NULL if the idx
* is for an invalid row entry (eg, after the last good Device). * is for an invalid row entry (eg, after the last good Device).
*/ */
DEVICE_OBJECT_DATA *Get_Routed_Device_Object( DEVICE_OBJECT_DATA *Get_Routed_Device_Object(int idx)
int idx)
{ {
if (idx == -1) if (idx == -1)
return &Devices[iCurrent_Device_Idx]; return &Devices[iCurrent_Device_Idx];
@@ -174,11 +169,10 @@ DEVICE_OBJECT_DATA *Get_Routed_Device_Object(
* -1 is a special case meaning "whichever iCurrent_Device_Idx * -1 is a special case meaning "whichever iCurrent_Device_Idx
* is currently set to" * is currently set to"
* If valid idx, will set iCurrent_Device_Idx with the idx * If valid idx, will set iCurrent_Device_Idx with the idx
* @return Pointer to the requested Device Object BACnet address, or NULL if the idx * @return Pointer to the requested Device Object BACnet address, or NULL if the
* is for an invalid row entry (eg, after the last good Device). * idx is for an invalid row entry (eg, after the last good Device).
*/ */
BACNET_ADDRESS *Get_Routed_Device_Address( BACNET_ADDRESS *Get_Routed_Device_Address(int idx)
int idx)
{ {
if (idx == -1) if (idx == -1)
return &Devices[iCurrent_Device_Idx].bacDevAddr; return &Devices[iCurrent_Device_Idx].bacDevAddr;
@@ -189,8 +183,6 @@ BACNET_ADDRESS *Get_Routed_Device_Address(
return NULL; return NULL;
} }
/** Get the currently active BACnet address. /** Get the currently active BACnet address.
* This is an implementation of the datalink_get_my_address() template for * This is an implementation of the datalink_get_my_address() template for
* devices with routing. * devices with routing.
@@ -198,8 +190,7 @@ BACNET_ADDRESS *Get_Routed_Device_Address(
* @param my_address [out] Points to the currently active Device Object's * @param my_address [out] Points to the currently active Device Object's
* BACnet address. * BACnet address.
*/ */
void routed_get_my_address( void routed_get_my_address(BACNET_ADDRESS *my_address)
BACNET_ADDRESS * my_address)
{ {
if (my_address) { if (my_address) {
memcpy(my_address, &Devices[iCurrent_Device_Idx].bacDevAddr, memcpy(my_address, &Devices[iCurrent_Device_Idx].bacDevAddr,
@@ -207,7 +198,6 @@ void routed_get_my_address(
} }
} }
/** See if the Gateway or Routed Device at the given idx matches /** See if the Gateway or Routed Device at the given idx matches
* the given MAC address. * the given MAC address.
* Has the desirable side-effect of setting iCurrent_Device_Idx to the * Has the desirable side-effect of setting iCurrent_Device_Idx to the
@@ -225,9 +215,7 @@ void routed_get_my_address(
* meaning MAC broadcast, so it's an automatic match). * meaning MAC broadcast, so it's an automatic match).
* Else False if no match or invalid idx is given. * Else False if no match or invalid idx is given.
*/ */
bool Routed_Device_Address_Lookup( bool Routed_Device_Address_Lookup(int idx, uint8_t address_len,
int idx,
uint8_t address_len,
uint8_t *mac_adress) uint8_t *mac_adress)
{ {
bool result = false; bool result = false;
@@ -253,7 +241,6 @@ bool Routed_Device_Address_Lookup(
return result; return result;
} }
/** Find the next Gateway or Routed Device at the given MAC address, /** Find the next Gateway or Routed Device at the given MAC address,
* starting the search at the "cursor". * starting the search at the "cursor".
* Has the desirable side-effect of setting internal iCurrent_Device_Idx * Has the desirable side-effect of setting internal iCurrent_Device_Idx
@@ -261,29 +248,25 @@ bool Routed_Device_Address_Lookup(
* functions. * functions.
* *
* @param dest [in] The BACNET_ADDRESS of the message's destination. * @param dest [in] The BACNET_ADDRESS of the message's destination.
* If the Length of the mac_adress[] field is 0, then this is a MAC * If the Length of the mac_adress[] field is 0, then this is a
* broadcast. Otherwise, size is determined * MAC broadcast. Otherwise, size is determined by the DLL type (eg, 6 for BIP
* by the DLL type (eg, 6 for BIP and 2 for MSTP). * and 2 for MSTP).
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers. * @param DNET_list [in] List of our reachable downstream BACnet Network
* Normally just one valid entry; terminated with a -1 value. * numbers. Normally just one valid entry; terminated with a -1 value.
* @param cursor [in,out] The concept of the cursor is that it is a starting * @param cursor [in,out] The concept of the cursor is that it is a starting
* "hint" for the search; on return, it is updated to provide the * "hint" for the search; on return, it is updated to provide
* cursor value to use with a subsequent GetNext call, or it * the cursor value to use with a subsequent GetNext call, or it equals -1 if
* equals -1 if there are no further matches. * there are no further matches. Set it to 0 on entry to access the main,
* Set it to 0 on entry to access the main, gateway Device entry, or * gateway Device entry, or to start looping through the routed devices.
* to start looping through the routed devices.
* Otherwise, its returned value is implementation-dependent and the * Otherwise, its returned value is implementation-dependent and the
* calling function should not alter or interpret it. * calling function should not alter or interpret it.
* *
* @return True if the MAC addresses match (or if BACNET_BROADCAST_NETWORK and * @return True if the MAC addresses match (or if BACNET_BROADCAST_NETWORK and
* the dest->len is 0, meaning MAC bcast, so it's an automatic match). * the dest->len is 0, meaning MAC bcast, so it's an automatic
* Else False if no match or invalid idx is given; the cursor will * match). Else False if no match or invalid idx is given; the cursor will be
* be returned as -1 in these cases. * returned as -1 in these cases.
*/ */
bool Routed_Device_GetNext( bool Routed_Device_GetNext(BACNET_ADDRESS *dest, int *DNET_list, int *cursor)
BACNET_ADDRESS * dest,
int *DNET_list,
int *cursor)
{ {
int dnet = DNET_list[0]; /* Get the DNET of our virtual network */ int dnet = DNET_list[0]; /* Get the DNET of our virtual network */
int idx = *cursor; int idx = *cursor;
@@ -338,23 +321,19 @@ bool Routed_Device_GetNext(
return bSuccess; return bSuccess;
} }
/** Check if the destination network is reachable - is it our virtual network, /** Check if the destination network is reachable - is it our virtual network,
* or local or else broadcast. * or local or else broadcast.
* *
* @param dest_net [in] The BACnet network number of a message's destination. * @param dest_net [in] The BACnet network number of a message's destination.
* Success if it is our virtual network number, or 0 (local for the * Success if it is our virtual network number, or 0 (local for
* gateway, or 0xFFFF for a broadcast network number. * the gateway, or 0xFFFF for a broadcast network number.
* @param DNET_list [in] List of our reachable downstream BACnet Network numbers. * @param DNET_list [in] List of our reachable downstream BACnet Network
* Normally just one valid entry; terminated with a -1 value. * numbers. Normally just one valid entry; terminated with a -1 value.
* @return True if matches our virtual network, or is for the local network * @return True if matches our virtual network, or is for the local network
* Device (the gateway), or is BACNET_BROADCAST_NETWORK, which is * Device (the gateway), or is BACNET_BROADCAST_NETWORK,
* an automatic match. * which is an automatic match. Else False if not a reachable network.
* Else False if not a reachable network.
*/ */
bool Routed_Device_Is_Valid_Network( bool Routed_Device_Is_Valid_Network(uint16_t dest_net, int *DNET_list)
uint16_t dest_net,
int *DNET_list)
{ {
int dnet = DNET_list[0]; /* Get the DNET of our virtual network */ int dnet = DNET_list[0]; /* Get the DNET of our virtual network */
bool bSuccess = false; bool bSuccess = false;
@@ -374,11 +353,9 @@ bool Routed_Device_Is_Valid_Network(
return bSuccess; return bSuccess;
} }
/* methods to override the normal Device objection functions */ /* methods to override the normal Device objection functions */
uint32_t Routed_Device_Index_To_Instance( uint32_t Routed_Device_Index_To_Instance(unsigned index)
unsigned index)
{ {
index = index; index = index;
return Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number; return Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number;
@@ -389,11 +366,11 @@ uint32_t Routed_Device_Index_To_Instance(
* iCurrent_Device_Idx must have been set to point to this Device Object * iCurrent_Device_Idx must have been set to point to this Device Object
* before this function is called. * before this function is called.
* @param object_id [in] Object ID of the desired Device object. * @param object_id [in] Object ID of the desired Device object.
* If the wildcard value (BACNET_MAX_INSTANCE), always matches. * If the wildcard value (BACNET_MAX_INSTANCE), always
* matches.
* @return True if Object ID matches the present Device, else False. * @return True if Object ID matches the present Device, else False.
*/ */
bool Routed_Device_Valid_Object_Instance_Number( bool Routed_Device_Valid_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool bResult = false; bool bResult = false;
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
@@ -404,14 +381,12 @@ bool Routed_Device_Valid_Object_Instance_Number(
return bResult; return bResult;
} }
bool Routed_Device_Name( bool Routed_Device_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
if (object_instance == pDev->bacObj.Object_Instance_Number) { if (object_instance == pDev->bacObj.Object_Instance_Number) {
return characterstring_init_ansi(object_name, return characterstring_init_ansi(object_name, pDev->bacObj.Object_Name);
pDev->bacObj.Object_Name);
} }
return false; return false;
@@ -423,8 +398,7 @@ bool Routed_Device_Name(
* @return The length of the apdu encoded, or BACNET_STATUS_ERROR for error or * @return The length of the apdu encoded, or BACNET_STATUS_ERROR for error or
* BACNET_STATUS_ABORT for abort message. * BACNET_STATUS_ABORT for abort message.
*/ */
int Routed_Device_Read_Property_Local( int Routed_Device_Read_Property_Local(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_CHARACTER_STRING char_string; BACNET_CHARACTER_STRING char_string;
@@ -438,9 +412,8 @@ int Routed_Device_Read_Property_Local(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_DEVICE, &apdu[0], OBJECT_DEVICE, pDev->bacObj.Object_Instance_Number);
pDev->bacObj.Object_Instance_Number);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
characterstring_init_ansi(&char_string, pDev->bacObj.Object_Name); characterstring_init_ansi(&char_string, pDev->bacObj.Object_Name);
@@ -464,16 +437,14 @@ int Routed_Device_Read_Property_Local(
return (apdu_len); return (apdu_len);
} }
bool Routed_Device_Write_Property_Local( bool Routed_Device_Write_Property_Local(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
if (len < 0) { if (len < 0) {
/* error while decoding - a value larger than we can handle */ /* error while decoding - a value larger than we can handle */
@@ -496,9 +467,10 @@ bool Routed_Device_Write_Property_Local(
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
if ((value.type.Object_Id.type == OBJECT_DEVICE) && if ((value.type.Object_Id.type == OBJECT_DEVICE) &&
(Routed_Device_Set_Object_Instance_Number(value.type. (Routed_Device_Set_Object_Instance_Number(
Object_Id.instance))) { value.type.Object_Id.instance))) {
/* FIXME: we could send an I-Am broadcast to let the world know */ /* FIXME: we could send an I-Am broadcast to let the world
* know */
} else { } else {
status = false; status = false;
wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_class = ERROR_CLASS_PROPERTY;
@@ -511,8 +483,8 @@ bool Routed_Device_Write_Property_Local(
WPValidateString(&value, MAX_DEV_NAME_LEN, false, WPValidateString(&value, MAX_DEV_NAME_LEN, false,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
Routed_Device_Set_Object_Name(characterstring_encoding(&value. Routed_Device_Set_Object_Name(
type.Character_String), characterstring_encoding(&value.type.Character_String),
characterstring_value(&value.type.Character_String), characterstring_value(&value.type.Character_String),
characterstring_length(&value.type.Character_String)); characterstring_length(&value.type.Character_String));
} }
@@ -532,14 +504,12 @@ bool Routed_Device_Write_Property_Local(
* *
* @return The Instance number of the currently active Device. * @return The Instance number of the currently active Device.
*/ */
uint32_t Routed_Device_Object_Instance_Number( uint32_t Routed_Device_Object_Instance_Number(void)
void)
{ {
return Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number; return Devices[iCurrent_Device_Idx].bacObj.Object_Instance_Number;
} }
bool Routed_Device_Set_Object_Instance_Number( bool Routed_Device_Set_Object_Instance_Number(uint32_t object_id)
uint32_t object_id)
{ {
bool status = true; /* return value */ bool status = true; /* return value */
@@ -559,9 +529,7 @@ bool Routed_Device_Set_Object_Instance_Number(
* @param object_name [in] Character String for the new Object Name. * @param object_name [in] Character String for the new Object Name.
* @return True if succeed in updating Object Name, else False. * @return True if succeed in updating Object Name, else False.
*/ */
bool Routed_Device_Set_Object_Name( bool Routed_Device_Set_Object_Name(uint8_t encoding, const char *value,
uint8_t encoding,
const char *value,
size_t length) size_t length)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
@@ -578,9 +546,7 @@ bool Routed_Device_Set_Object_Name(
return status; return status;
} }
bool Routed_Device_Set_Description( bool Routed_Device_Set_Description(const char *name, size_t length)
const char *name,
size_t length)
{ {
bool status = false; /*return value */ bool status = false; /*return value */
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
@@ -594,20 +560,17 @@ bool Routed_Device_Set_Description(
return status; return status;
} }
/* /*
* Shortcut for incrementing database revision as this is potentially * Shortcut for incrementing database revision as this is potentially
* the most common operation if changing object names and ids is * the most common operation if changing object names and ids is
* implemented. * implemented.
*/ */
void Routed_Device_Inc_Database_Revision( void Routed_Device_Inc_Database_Revision(void)
void)
{ {
DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx]; DEVICE_OBJECT_DATA *pDev = &Devices[iCurrent_Device_Idx];
pDev->Database_Revision++; pDev->Database_Revision++;
} }
/** Check to see if the current Device supports this service. /** Check to see if the current Device supports this service.
* Presently checks for RD and DCC and only allows them if the current * Presently checks for RD and DCC and only allows them if the current
* device is the gateway device. * device is the gateway device.
@@ -621,10 +584,8 @@ void Routed_Device_Inc_Database_Revision(
* just 1 if no apdu_buff was supplied and service is not supported, * just 1 if no apdu_buff was supplied and service is not supported,
* else 0 if service is approved for the current device. * else 0 if service is approved for the current device.
*/ */
int Routed_Device_Service_Approval( int Routed_Device_Service_Approval(BACNET_CONFIRMED_SERVICE service,
BACNET_CONFIRMED_SERVICE service, int service_argument, uint8_t *apdu_buff,
int service_argument,
uint8_t * apdu_buff,
uint8_t invoke_id) uint8_t invoke_id)
{ {
int len = 0; int len = 0;
+30 -55
View File
@@ -59,24 +59,18 @@ struct integer_object {
struct integer_object Integer_Value[MAX_INTEGER_VALUES]; struct integer_object Integer_Value[MAX_INTEGER_VALUES];
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Integer_Value_Properties_Required[] = { static const int Integer_Value_Properties_Required[] = {PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE, PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS, PROP_STATUS_FLAGS,
PROP_UNITS, PROP_UNITS,
-1 -1};
};
static const int Integer_Value_Properties_Optional[] = { static const int Integer_Value_Properties_Optional[] = {PROP_OUT_OF_SERVICE,
PROP_OUT_OF_SERVICE, -1};
-1
};
static const int Integer_Value_Properties_Proprietary[] = { static const int Integer_Value_Properties_Proprietary[] = {-1};
-1
};
/** /**
* Returns the list of required, optional, and proprietary properties. * Returns the list of required, optional, and proprietary properties.
@@ -89,9 +83,7 @@ static const int Integer_Value_Properties_Proprietary[] = {
* @param pProprietary - pointer to list of int terminated by -1, of * @param pProprietary - pointer to list of int terminated by -1, of
* BACnet proprietary properties for this object. * BACnet proprietary properties for this object.
*/ */
void Integer_Value_Property_Lists( void Integer_Value_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -111,8 +103,7 @@ void Integer_Value_Property_Lists(
* *
* @return true if the instance is valid, and false if not * @return true if the instance is valid, and false if not
*/ */
bool Integer_Value_Valid_Instance( bool Integer_Value_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned int index; unsigned int index;
@@ -129,8 +120,7 @@ bool Integer_Value_Valid_Instance(
* *
* @return Number of Analog Value objects * @return Number of Analog Value objects
*/ */
unsigned Integer_Value_Count( unsigned Integer_Value_Count(void)
void)
{ {
return MAX_INTEGER_VALUES; return MAX_INTEGER_VALUES;
} }
@@ -143,8 +133,7 @@ unsigned Integer_Value_Count(
* *
* @return object instance-number for the given index * @return object instance-number for the given index
*/ */
uint32_t Integer_Value_Index_To_Instance( uint32_t Integer_Value_Index_To_Instance(unsigned index)
unsigned index)
{ {
uint32_t instance = 1; uint32_t instance = 1;
@@ -162,8 +151,7 @@ uint32_t Integer_Value_Index_To_Instance(
* @return index for the given instance-number, or MAX_INTEGER_VALUES * @return index for the given instance-number, or MAX_INTEGER_VALUES
* if not valid. * if not valid.
*/ */
unsigned Integer_Value_Instance_To_Index( unsigned Integer_Value_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_INTEGER_VALUES; unsigned index = MAX_INTEGER_VALUES;
@@ -184,8 +172,7 @@ unsigned Integer_Value_Instance_To_Index(
* *
* @return present-value of the object * @return present-value of the object
*/ */
int32_t Integer_Value_Present_Value( int32_t Integer_Value_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
int32_t value = 0; int32_t value = 0;
unsigned int index; unsigned int index;
@@ -206,9 +193,7 @@ int32_t Integer_Value_Present_Value(
* *
* @return true if values are within range and present-value is set. * @return true if values are within range and present-value is set.
*/ */
bool Integer_Value_Present_Value_Set( bool Integer_Value_Present_Value_Set(uint32_t object_instance, int32_t value,
uint32_t object_instance,
int32_t value,
uint8_t priority) uint8_t priority)
{ {
bool status = false; bool status = false;
@@ -234,8 +219,7 @@ bool Integer_Value_Present_Value_Set(
* *
* @return true if object-name was retrieved * @return true if object-name was retrieved
*/ */
bool Integer_Value_Object_Name( bool Integer_Value_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
char text_string[32] = ""; char text_string[32] = "";
@@ -244,7 +228,8 @@ bool Integer_Value_Object_Name(
index = Integer_Value_Instance_To_Index(object_instance); index = Integer_Value_Instance_To_Index(object_instance);
if (index < MAX_INTEGER_VALUES) { if (index < MAX_INTEGER_VALUES) {
sprintf(text_string, "ANALOG VALUE %lu", (unsigned long) object_instance); sprintf(text_string, "ANALOG VALUE %lu",
(unsigned long)object_instance);
status = characterstring_init_ansi(object_name, text_string); status = characterstring_init_ansi(object_name, text_string);
} }
@@ -258,8 +243,7 @@ bool Integer_Value_Object_Name(
* *
* @return units property value * @return units property value
*/ */
uint16_t Integer_Value_Units( uint16_t Integer_Value_Units(uint32_t instance)
uint32_t instance)
{ {
unsigned int index; unsigned int index;
uint16_t units = UNITS_NO_UNITS; uint16_t units = UNITS_NO_UNITS;
@@ -280,9 +264,7 @@ uint16_t Integer_Value_Units(
* *
* @return true if the units property value was set * @return true if the units property value was set
*/ */
bool Integer_Value_Units_Set( bool Integer_Value_Units_Set(uint32_t instance, uint16_t units)
uint32_t instance,
uint16_t units)
{ {
unsigned int index = 0; unsigned int index = 0;
bool status = false; bool status = false;
@@ -304,8 +286,7 @@ bool Integer_Value_Units_Set(
* *
* @return out-of-service property value * @return out-of-service property value
*/ */
bool Integer_Value_Out_Of_Service( bool Integer_Value_Out_Of_Service(uint32_t instance)
uint32_t instance)
{ {
unsigned int index = 0; unsigned int index = 0;
bool value = false; bool value = false;
@@ -326,9 +307,7 @@ bool Integer_Value_Out_Of_Service(
* *
* @return true if the out-of-service property value was set * @return true if the out-of-service property value was set
*/ */
void Integer_Value_Out_Of_Service_Set( void Integer_Value_Out_Of_Service_Set(uint32_t instance, bool value)
uint32_t instance,
bool value)
{ {
unsigned int index = 0; unsigned int index = 0;
@@ -348,8 +327,7 @@ void Integer_Value_Out_Of_Service_Set(
* @return number of APDU bytes in the response, or * @return number of APDU bytes in the response, or
* BACNET_STATUS_ERROR on error. * BACNET_STATUS_ERROR on error.
*/ */
int Integer_Value_Read_Property( int Integer_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
BACNET_BIT_STRING bit_string; BACNET_BIT_STRING bit_string;
@@ -367,9 +345,8 @@ int Integer_Value_Read_Property(
apdu = rpdata->application_data; apdu = rpdata->application_data;
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_INTEGER_VALUE, &apdu[0], OBJECT_INTEGER_VALUE, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
Integer_Value_Object_Name(rpdata->object_instance, &char_string); Integer_Value_Object_Name(rpdata->object_instance, &char_string);
@@ -381,7 +358,8 @@ int Integer_Value_Read_Property(
encode_application_enumerated(&apdu[0], OBJECT_INTEGER_VALUE); encode_application_enumerated(&apdu[0], OBJECT_INTEGER_VALUE);
break; break;
case PROP_PRESENT_VALUE: case PROP_PRESENT_VALUE:
integer_value = Integer_Value_Present_Value(rpdata->object_instance); integer_value =
Integer_Value_Present_Value(rpdata->object_instance);
apdu_len = encode_application_signed(&apdu[0], integer_value); apdu_len = encode_application_signed(&apdu[0], integer_value);
break; break;
case PROP_STATUS_FLAGS: case PROP_STATUS_FLAGS:
@@ -428,16 +406,14 @@ int Integer_Value_Read_Property(
* *
* @return false if an error is loaded, true if no errors * @return false if an error is loaded, true if no errors
*/ */
bool Integer_Value_Write_Property( bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -461,7 +437,8 @@ bool Integer_Value_Write_Property(
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
Integer_Value_Present_Value_Set(wp_data->object_instance, Integer_Value_Present_Value_Set(wp_data->object_instance,
value.type.Signed_Int, wp_data->priority); value.type.Signed_Int,
wp_data->priority);
} }
break; break;
case PROP_OUT_OF_SERVICE: case PROP_OUT_OF_SERVICE:
@@ -469,8 +446,7 @@ bool Integer_Value_Write_Property(
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN, WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_class, &wp_data->error_code);
if (status) { if (status) {
Integer_Value_Out_Of_Service_Set( Integer_Value_Out_Of_Service_Set(wp_data->object_instance,
wp_data->object_instance,
value.type.Boolean); value.type.Boolean);
} }
break; break;
@@ -494,8 +470,7 @@ bool Integer_Value_Write_Property(
/** /**
* Initializes the Integer Value object data * Initializes the Integer Value object data
*/ */
void Integer_Value_Init( void Integer_Value_Init(void)
void)
{ {
unsigned index = 0; unsigned index = 0;
+105 -163
View File
@@ -126,17 +126,9 @@ static unsigned Shed_Levels[MAX_LOAD_CONTROLS][MAX_SHED_LEVELS];
Load Control object can take on. It is the same for Load Control object can take on. It is the same for
all the load control objects in this example device. */ all the load control objects in this example device. */
static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = { static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
"dim lights 10%", "dim lights 10%", "dim lights 20%", "dim lights 30%"};
"dim lights 20%",
"dim lights 30%"
};
static float Shed_Level_Values[MAX_SHED_LEVELS] = {
90.0,
80.0,
70.0
};
static float Shed_Level_Values[MAX_SHED_LEVELS] = {90.0, 80.0, 70.0};
/* These three arrays are used by the ReadPropertyMultiple handler */ /* These three arrays are used by the ReadPropertyMultiple handler */
static const int Load_Control_Properties_Required[] = { static const int Load_Control_Properties_Required[] = {
@@ -155,22 +147,14 @@ static const int Load_Control_Properties_Required[] = {
PROP_ACTUAL_SHED_LEVEL, PROP_ACTUAL_SHED_LEVEL,
PROP_SHED_LEVELS, PROP_SHED_LEVELS,
PROP_SHED_LEVEL_DESCRIPTIONS, PROP_SHED_LEVEL_DESCRIPTIONS,
-1 -1};
};
static const int Load_Control_Properties_Optional[] = { static const int Load_Control_Properties_Optional[] = {
PROP_DESCRIPTION, PROP_DESCRIPTION, PROP_FULL_DUTY_BASELINE, -1};
PROP_FULL_DUTY_BASELINE,
-1
};
static const int Load_Control_Properties_Proprietary[] = { static const int Load_Control_Properties_Proprietary[] = {-1};
-1
};
void Load_Control_Property_Lists( void Load_Control_Property_Lists(const int **pRequired, const int **pOptional,
const int **pRequired,
const int **pOptional,
const int **pProprietary) const int **pProprietary)
{ {
if (pRequired) if (pRequired)
@@ -183,8 +167,7 @@ void Load_Control_Property_Lists(
return; return;
} }
void Load_Control_Init( void Load_Control_Init(void)
void)
{ {
unsigned i, j; unsigned i, j;
@@ -217,8 +200,7 @@ void Load_Control_Init(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */ /* more complex, and then you need validate that the */
/* given instance exists */ /* given instance exists */
bool Load_Control_Valid_Instance( bool Load_Control_Valid_Instance(uint32_t object_instance)
uint32_t object_instance)
{ {
if (object_instance < MAX_LOAD_CONTROLS) if (object_instance < MAX_LOAD_CONTROLS)
return true; return true;
@@ -228,8 +210,7 @@ bool Load_Control_Valid_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then count how many you have */ /* more complex, and then count how many you have */
unsigned Load_Control_Count( unsigned Load_Control_Count(void)
void)
{ {
return MAX_LOAD_CONTROLS; return MAX_LOAD_CONTROLS;
} }
@@ -237,8 +218,7 @@ unsigned Load_Control_Count(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the instance */ /* more complex, and then you need to return the instance */
/* that correlates to the correct index */ /* that correlates to the correct index */
uint32_t Load_Control_Index_To_Instance( uint32_t Load_Control_Index_To_Instance(unsigned index)
unsigned index)
{ {
return index; return index;
} }
@@ -246,8 +226,7 @@ uint32_t Load_Control_Index_To_Instance(
/* we simply have 0-n object instances. Yours might be */ /* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need to return the index */ /* more complex, and then you need to return the index */
/* that correlates to the correct instance number */ /* that correlates to the correct instance number */
unsigned Load_Control_Instance_To_Index( unsigned Load_Control_Instance_To_Index(uint32_t object_instance)
uint32_t object_instance)
{ {
unsigned index = MAX_LOAD_CONTROLS; unsigned index = MAX_LOAD_CONTROLS;
@@ -257,8 +236,7 @@ unsigned Load_Control_Instance_To_Index(
return index; return index;
} }
static BACNET_SHED_STATE Load_Control_Present_Value( static BACNET_SHED_STATE Load_Control_Present_Value(uint32_t object_instance)
uint32_t object_instance)
{ {
BACNET_SHED_STATE value = BACNET_SHED_INACTIVE; BACNET_SHED_STATE value = BACNET_SHED_INACTIVE;
unsigned index = 0; unsigned index = 0;
@@ -272,8 +250,7 @@ static BACNET_SHED_STATE Load_Control_Present_Value(
} }
/* note: the object name must be unique within this device */ /* note: the object name must be unique within this device */
bool Load_Control_Object_Name( bool Load_Control_Object_Name(uint32_t object_instance,
uint32_t object_instance,
BACNET_CHARACTER_STRING *object_name) BACNET_CHARACTER_STRING *object_name)
{ {
static char text_string[32] = ""; /* okay for single thread */ static char text_string[32] = ""; /* okay for single thread */
@@ -287,8 +264,7 @@ bool Load_Control_Object_Name(
return status; return status;
} }
static void Update_Current_Time( static void Update_Current_Time(BACNET_DATE_TIME *bdatetime)
BACNET_DATE_TIME * bdatetime)
{ {
time_t timer; time_t timer;
struct tm *tblock; struct tm *tblock;
@@ -316,8 +292,7 @@ struct tm {
} }
/* convert the shed level request into an Analog Output Present_Value */ /* convert the shed level request into an Analog Output Present_Value */
static float Requested_Shed_Level_Value( static float Requested_Shed_Level_Value(int object_index)
int object_index)
{ {
unsigned shed_level_index = 0; unsigned shed_level_index = 0;
unsigned i = 0; unsigned i = 0;
@@ -330,8 +305,7 @@ static float Requested_Shed_Level_Value(
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
/* Assumptions: wattage is linear with analog output level */ /* Assumptions: wattage is linear with analog output level */
requested_level = requested_level = Full_Duty_Baseline[object_index] -
Full_Duty_Baseline[object_index] -
Requested_Shed_Level[object_index].value.amount; Requested_Shed_Level[object_index].value.amount;
requested_level /= Full_Duty_Baseline[object_index]; requested_level /= Full_Duty_Baseline[object_index];
requested_level *= 100.0; requested_level *= 100.0;
@@ -350,9 +324,7 @@ static float Requested_Shed_Level_Value(
return requested_level; return requested_level;
} }
static void Shed_Level_Copy( static void Shed_Level_Copy(BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL *src)
BACNET_SHED_LEVEL * dest,
BACNET_SHED_LEVEL * src)
{ {
if (dest && src) { if (dest && src) {
dest->type = src->type; dest->type = src->type;
@@ -371,8 +343,7 @@ static void Shed_Level_Copy(
} }
} }
static void Shed_Level_Default_Set( static void Shed_Level_Default_Set(BACNET_SHED_LEVEL *dest,
BACNET_SHED_LEVEL * dest,
BACNET_SHED_LEVEL_TYPE type) BACNET_SHED_LEVEL_TYPE type)
{ {
if (dest) { if (dest) {
@@ -392,8 +363,7 @@ static void Shed_Level_Default_Set(
} }
} }
static bool Able_To_Meet_Shed_Request( static bool Able_To_Meet_Shed_Request(int object_index)
int object_index)
{ {
float level = 0.0; float level = 0.0;
float requested_level = 0.0; float requested_level = 0.0;
@@ -428,15 +398,11 @@ static LOAD_CONTROL_STATE Load_Control_State[MAX_LOAD_CONTROLS];
static LOAD_CONTROL_STATE Load_Control_State_Previously[MAX_LOAD_CONTROLS]; static LOAD_CONTROL_STATE Load_Control_State_Previously[MAX_LOAD_CONTROLS];
#if PRINT_ENABLED_DEBUG #if PRINT_ENABLED_DEBUG
static void Print_Load_Control_State( static void Print_Load_Control_State(int object_index)
int object_index)
{ {
char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = { char *Load_Control_State_Text[MAX_LOAD_CONTROLS] = {
"SHED_INACTIVE", "SHED_INACTIVE", "SHED_REQUEST_PENDING", "SHED_NON_COMPLIANT",
"SHED_REQUEST_PENDING", "SHED_COMPLIANT"};
"SHED_NON_COMPLIANT",
"SHED_COMPLIANT"
};
if (object_index < MAX_LOAD_CONTROLS) { if (object_index < MAX_LOAD_CONTROLS) {
if (Load_Control_State[object_index] < MAX_LOAD_CONTROL_STATE) { if (Load_Control_State[object_index] < MAX_LOAD_CONTROL_STATE) {
@@ -447,8 +413,7 @@ static void Print_Load_Control_State(
} }
#endif #endif
void Load_Control_State_Machine( void Load_Control_State_Machine(int object_index)
int object_index)
{ {
unsigned i = 0; /* loop counter */ unsigned i = 0; /* loop counter */
int diff = 0; /* used for datetime comparison */ int diff = 0; /* used for datetime comparison */
@@ -512,8 +477,10 @@ void Load_Control_State_Machine(
/* CancelShed */ /* CancelShed */
/* FIXME: stop shedding! i.e. relinquish */ /* FIXME: stop shedding! i.e. relinquish */
#if PRINT_ENABLED_DEBUG #if PRINT_ENABLED_DEBUG
printf("Load Control[%d]:Current Time" printf(
" is after Start Time + Duration\n", object_index); "Load Control[%d]:Current Time"
" is after Start Time + Duration\n",
object_index);
#endif #endif
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
break; break;
@@ -529,23 +496,28 @@ void Load_Control_State_Machine(
} else if (diff > 0) { } else if (diff > 0) {
/* current time after to start time */ /* current time after to start time */
#if PRINT_ENABLED_DEBUG #if PRINT_ENABLED_DEBUG
printf("Load Control[%d]:Current Time" printf(
" is after Start Time\n", object_index); "Load Control[%d]:Current Time"
" is after Start Time\n",
object_index);
#endif #endif
/* AbleToMeetShed */ /* AbleToMeetShed */
if (Able_To_Meet_Shed_Request(object_index)) { if (Able_To_Meet_Shed_Request(object_index)) {
Shed_Level_Copy(&Expected_Shed_Level[object_index], Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Analog_Output_Present_Value_Set(object_index, Analog_Output_Present_Value_Set(
Requested_Shed_Level_Value(object_index), 4); object_index, Requested_Shed_Level_Value(object_index),
4);
Shed_Level_Copy(&Actual_Shed_Level[object_index], Shed_Level_Copy(&Actual_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Load_Control_State[object_index] = SHED_COMPLIANT; Load_Control_State[object_index] = SHED_COMPLIANT;
} else { } else {
/* CannotMeetShed */ /* CannotMeetShed */
Shed_Level_Default_Set(&Expected_Shed_Level[object_index], Shed_Level_Default_Set(
&Expected_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Shed_Level_Default_Set(&Actual_Shed_Level[object_index], Shed_Level_Default_Set(
&Actual_Shed_Level[object_index],
Requested_Shed_Level[object_index].type); Requested_Shed_Level[object_index].type);
Load_Control_State[object_index] = SHED_NON_COMPLIANT; Load_Control_State[object_index] = SHED_NON_COMPLIANT;
} }
@@ -559,8 +531,9 @@ void Load_Control_State_Machine(
if (diff < 0) { if (diff < 0) {
/* FinishedUnsuccessfulShed */ /* FinishedUnsuccessfulShed */
#if PRINT_ENABLED_DEBUG #if PRINT_ENABLED_DEBUG
printf printf(
("Load Control[%d]:Current Time is after Start Time + Duration\n", "Load Control[%d]:Current Time is after Start Time + "
"Duration\n",
object_index); object_index);
#endif #endif
Load_Control_State[object_index] = SHED_INACTIVE; Load_Control_State[object_index] = SHED_INACTIVE;
@@ -585,8 +558,8 @@ void Load_Control_State_Machine(
#endif #endif
Shed_Level_Copy(&Expected_Shed_Level[object_index], Shed_Level_Copy(&Expected_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Analog_Output_Present_Value_Set(object_index, Analog_Output_Present_Value_Set(
Requested_Shed_Level_Value(object_index), 4); object_index, Requested_Shed_Level_Value(object_index), 4);
Shed_Level_Copy(&Actual_Shed_Level[object_index], Shed_Level_Copy(&Actual_Shed_Level[object_index],
&Requested_Shed_Level[object_index]); &Requested_Shed_Level[object_index]);
Load_Control_State[object_index] = SHED_COMPLIANT; Load_Control_State[object_index] = SHED_COMPLIANT;
@@ -600,8 +573,9 @@ void Load_Control_State_Machine(
if (diff < 0) { if (diff < 0) {
/* FinishedSuccessfulShed */ /* FinishedSuccessfulShed */
#if PRINT_ENABLED_DEBUG #if PRINT_ENABLED_DEBUG
printf printf(
("Load Control[%d]:Current Time is after Start Time + Duration\n", "Load Control[%d]:Current Time is after Start Time + "
"Duration\n",
object_index); object_index);
#endif #endif
datetime_wildcard_set(&Start_Time[i]); datetime_wildcard_set(&Start_Time[i]);
@@ -653,8 +627,7 @@ void Load_Control_State_Machine(
} }
/* call every second or so */ /* call every second or so */
void Load_Control_State_Machine_Handler( void Load_Control_State_Machine_Handler(void)
void)
{ {
unsigned i = 0; unsigned i = 0;
static bool initialized = false; static bool initialized = false;
@@ -675,14 +648,11 @@ void Load_Control_State_Machine_Handler(
#endif #endif
Load_Control_State_Previously[i] = Load_Control_State[i]; Load_Control_State_Previously[i] = Load_Control_State[i];
} }
} }
} }
/* return apdu len, or BACNET_STATUS_ERROR on error */ /* return apdu len, or BACNET_STATUS_ERROR on error */
int Load_Control_Read_Property( int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
BACNET_READ_PROPERTY_DATA * rpdata)
{ {
int len = 0; int len = 0;
int apdu_len = 0; /* return value */ int apdu_len = 0; /* return value */
@@ -702,9 +672,8 @@ int Load_Control_Read_Property(
object_index = Load_Control_Instance_To_Index(rpdata->object_instance); object_index = Load_Control_Instance_To_Index(rpdata->object_instance);
switch (rpdata->object_property) { switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER: case PROP_OBJECT_IDENTIFIER:
apdu_len = apdu_len = encode_application_object_id(
encode_application_object_id(&apdu[0], OBJECT_LOAD_CONTROL, &apdu[0], OBJECT_LOAD_CONTROL, rpdata->object_instance);
rpdata->object_instance);
break; break;
case PROP_OBJECT_NAME: case PROP_OBJECT_NAME:
case PROP_DESCRIPTION: case PROP_DESCRIPTION:
@@ -744,41 +713,37 @@ int Load_Control_Read_Property(
case PROP_REQUESTED_SHED_LEVEL: case PROP_REQUESTED_SHED_LEVEL:
switch (Requested_Shed_Level[object_index].type) { switch (Requested_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
apdu_len = apdu_len = encode_context_unsigned(
encode_context_unsigned(&apdu[0], 0, &apdu[0], 0,
Requested_Shed_Level[object_index].value.percent); Requested_Shed_Level[object_index].value.percent);
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
apdu_len = apdu_len = encode_context_real(
encode_context_real(&apdu[0], 2, &apdu[0], 2,
Requested_Shed_Level[object_index].value.amount); Requested_Shed_Level[object_index].value.amount);
break; break;
case BACNET_SHED_TYPE_LEVEL: case BACNET_SHED_TYPE_LEVEL:
default: default:
apdu_len = apdu_len = encode_context_unsigned(
encode_context_unsigned(&apdu[0], 1, &apdu[0], 1,
Requested_Shed_Level[object_index].value.level); Requested_Shed_Level[object_index].value.level);
break; break;
} }
break; break;
case PROP_START_TIME: case PROP_START_TIME:
len = len = encode_application_date(&apdu[0],
encode_application_date(&apdu[0],
&Start_Time[object_index].date); &Start_Time[object_index].date);
apdu_len = len; apdu_len = len;
len = len = encode_application_time(&apdu[apdu_len],
encode_application_time(&apdu[apdu_len],
&Start_Time[object_index].time); &Start_Time[object_index].time);
apdu_len += len; apdu_len += len;
break; break;
case PROP_SHED_DURATION: case PROP_SHED_DURATION:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0],
encode_application_unsigned(&apdu[0],
Shed_Duration[object_index]); Shed_Duration[object_index]);
break; break;
case PROP_DUTY_WINDOW: case PROP_DUTY_WINDOW:
apdu_len = apdu_len = encode_application_unsigned(&apdu[0],
encode_application_unsigned(&apdu[0],
Duty_Window[object_index]); Duty_Window[object_index]);
break; break;
case PROP_ENABLE: case PROP_ENABLE:
@@ -786,26 +751,25 @@ int Load_Control_Read_Property(
apdu_len = encode_application_boolean(&apdu[0], state); apdu_len = encode_application_boolean(&apdu[0], state);
break; break;
case PROP_FULL_DUTY_BASELINE: /* optional */ case PROP_FULL_DUTY_BASELINE: /* optional */
apdu_len = apdu_len = encode_application_real(
encode_application_real(&apdu[0], &apdu[0], Full_Duty_Baseline[object_index]);
Full_Duty_Baseline[object_index]);
break; break;
case PROP_EXPECTED_SHED_LEVEL: case PROP_EXPECTED_SHED_LEVEL:
switch (Expected_Shed_Level[object_index].type) { switch (Expected_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
apdu_len = apdu_len = encode_context_unsigned(
encode_context_unsigned(&apdu[0], 0, &apdu[0], 0,
Expected_Shed_Level[object_index].value.percent); Expected_Shed_Level[object_index].value.percent);
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
apdu_len = apdu_len = encode_context_real(
encode_context_real(&apdu[0], 2, &apdu[0], 2,
Expected_Shed_Level[object_index].value.amount); Expected_Shed_Level[object_index].value.amount);
break; break;
case BACNET_SHED_TYPE_LEVEL: case BACNET_SHED_TYPE_LEVEL:
default: default:
apdu_len = apdu_len = encode_context_unsigned(
encode_context_unsigned(&apdu[0], 1, &apdu[0], 1,
Expected_Shed_Level[object_index].value.level); Expected_Shed_Level[object_index].value.level);
break; break;
} }
@@ -813,19 +777,19 @@ int Load_Control_Read_Property(
case PROP_ACTUAL_SHED_LEVEL: case PROP_ACTUAL_SHED_LEVEL:
switch (Actual_Shed_Level[object_index].type) { switch (Actual_Shed_Level[object_index].type) {
case BACNET_SHED_TYPE_PERCENT: case BACNET_SHED_TYPE_PERCENT:
apdu_len = apdu_len = encode_context_unsigned(
encode_context_unsigned(&apdu[0], 0, &apdu[0], 0,
Actual_Shed_Level[object_index].value.percent); Actual_Shed_Level[object_index].value.percent);
break; break;
case BACNET_SHED_TYPE_AMOUNT: case BACNET_SHED_TYPE_AMOUNT:
apdu_len = apdu_len = encode_context_real(
encode_context_real(&apdu[0], 2, &apdu[0], 2,
Actual_Shed_Level[object_index].value.amount); Actual_Shed_Level[object_index].value.amount);
break; break;
case BACNET_SHED_TYPE_LEVEL: case BACNET_SHED_TYPE_LEVEL:
default: default:
apdu_len = apdu_len = encode_context_unsigned(
encode_context_unsigned(&apdu[0], 1, &apdu[0], 1,
Actual_Shed_Level[object_index].value.level); Actual_Shed_Level[object_index].value.level);
break; break;
} }
@@ -841,9 +805,8 @@ int Load_Control_Read_Property(
apdu_len = 0; apdu_len = 0;
for (i = 0; i < MAX_SHED_LEVELS; i++) { for (i = 0; i < MAX_SHED_LEVELS; i++) {
/* FIXME: check if we have room before adding it to APDU */ /* FIXME: check if we have room before adding it to APDU */
len = len = encode_application_unsigned(
encode_application_unsigned(&apdu[apdu_len], &apdu[apdu_len], Shed_Levels[object_index][i]);
Shed_Levels[object_index][i]);
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
apdu_len += len; apdu_len += len;
@@ -856,8 +819,8 @@ int Load_Control_Read_Property(
} }
} else { } else {
if (rpdata->array_index <= MAX_SHED_LEVELS) { if (rpdata->array_index <= MAX_SHED_LEVELS) {
apdu_len = apdu_len = encode_application_unsigned(
encode_application_unsigned(&apdu[0], &apdu[0],
Shed_Levels[object_index][rpdata->array_index - 1]); Shed_Levels[object_index][rpdata->array_index - 1]);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
@@ -879,8 +842,7 @@ int Load_Control_Read_Property(
/* FIXME: check if we have room before adding it to APDU */ /* FIXME: check if we have room before adding it to APDU */
characterstring_init_ansi(&char_string, characterstring_init_ansi(&char_string,
Shed_Level_Descriptions[i]); Shed_Level_Descriptions[i]);
len = len = encode_application_character_string(&apdu[apdu_len],
encode_application_character_string(&apdu[apdu_len],
&char_string); &char_string);
/* add it if we have room */ /* add it if we have room */
if ((apdu_len + len) < MAX_APDU) if ((apdu_len + len) < MAX_APDU)
@@ -894,11 +856,11 @@ int Load_Control_Read_Property(
} }
} else { } else {
if (rpdata->array_index <= MAX_SHED_LEVELS) { if (rpdata->array_index <= MAX_SHED_LEVELS) {
characterstring_init_ansi(&char_string, characterstring_init_ansi(
&char_string,
Shed_Level_Descriptions[rpdata->array_index - 1]); Shed_Level_Descriptions[rpdata->array_index - 1]);
apdu_len = apdu_len = encode_application_character_string(
encode_application_character_string(&apdu[0], &apdu[0], &char_string);
&char_string);
} else { } else {
rpdata->error_class = ERROR_CLASS_PROPERTY; rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX; rpdata->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
@@ -926,18 +888,17 @@ int Load_Control_Read_Property(
} }
/* returns true if successful */ /* returns true if successful */
bool Load_Control_Write_Property( bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
BACNET_WRITE_PROPERTY_DATA * wp_data)
{ {
bool status = false; /* return value */ bool status = false; /* return value */
unsigned int object_index = 0; unsigned int object_index = 0;
int len = 0; int len = 0;
BACNET_APPLICATION_DATA_VALUE value; BACNET_APPLICATION_DATA_VALUE value;
BACNET_DATE TempDate; /* build here in case of error in time half of datetime */ BACNET_DATE
TempDate; /* build here in case of error in time half of datetime */
/* decode the some of the request */ /* decode the some of the request */
len = len = bacapp_decode_application_data(wp_data->application_data,
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value); wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */ /* FIXME: len < application_data_len: more data? */
if (len < 0) { if (len < 0) {
@@ -956,10 +917,9 @@ bool Load_Control_Write_Property(
object_index = Load_Control_Instance_To_Index(wp_data->object_instance); object_index = Load_Control_Instance_To_Index(wp_data->object_instance);
switch (wp_data->object_property) { switch (wp_data->object_property) {
case PROP_REQUESTED_SHED_LEVEL: case PROP_REQUESTED_SHED_LEVEL:
len = len = bacapp_decode_context_data(wp_data->application_data,
bacapp_decode_context_data(wp_data->application_data, wp_data->application_data_len,
wp_data->application_data_len, &value, &value, PROP_REQUESTED_SHED_LEVEL);
PROP_REQUESTED_SHED_LEVEL);
if (value.context_tag == 0) { if (value.context_tag == 0) {
/* percent - Unsigned */ /* percent - Unsigned */
Requested_Shed_Level[object_index].type = Requested_Shed_Level[object_index].type =
@@ -1001,13 +961,13 @@ bool Load_Control_Write_Property(
} }
/* Hold the date until we are sure the time is also there */ /* Hold the date until we are sure the time is also there */
TempDate = value.type.Date; TempDate = value.type.Date;
len = len = bacapp_decode_application_data(
bacapp_decode_application_data(wp_data->application_data + len, wp_data->application_data + len,
wp_data->application_data_len - len, &value); wp_data->application_data_len - len, &value);
if (len) { if (len) {
status = status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME,
WPValidateArgType(&value, BACNET_APPLICATION_TAG_TIME, &wp_data->error_class,
&wp_data->error_class, &wp_data->error_code); &wp_data->error_code);
if (status) { if (status) {
/* Write time and date and set written flag */ /* Write time and date and set written flag */
Start_Time[object_index].date = TempDate; Start_Time[object_index].date = TempDate;
@@ -1117,8 +1077,7 @@ static void Load_Control_WriteProperty_Request_Shed_Percent(
} }
#endif #endif
static void Load_Control_WriteProperty_Request_Shed_Level( static void Load_Control_WriteProperty_Request_Shed_Level(Test *pTest,
Test * pTest,
int instance, int instance,
unsigned level) unsigned level)
{ {
@@ -1169,9 +1128,7 @@ static void Load_Control_WriteProperty_Request_Shed_Amount(
} }
#endif #endif
static void Load_Control_WriteProperty_Enable( static void Load_Control_WriteProperty_Enable(Test *pTest, int instance,
Test * pTest,
int instance,
bool enable) bool enable)
{ {
bool status = false; bool status = false;
@@ -1195,9 +1152,7 @@ static void Load_Control_WriteProperty_Enable(
ct_test(pTest, status == true); ct_test(pTest, status == true);
} }
static void Load_Control_WriteProperty_Shed_Duration( static void Load_Control_WriteProperty_Shed_Duration(Test *pTest, int instance,
Test * pTest,
int instance,
unsigned duration) unsigned duration)
{ {
bool status = false; bool status = false;
@@ -1220,9 +1175,7 @@ static void Load_Control_WriteProperty_Shed_Duration(
ct_test(pTest, status == true); ct_test(pTest, status == true);
} }
static void Load_Control_WriteProperty_Duty_Window( static void Load_Control_WriteProperty_Duty_Window(Test *pTest, int instance,
Test * pTest,
int instance,
unsigned duration) unsigned duration)
{ {
bool status = false; bool status = false;
@@ -1245,8 +1198,7 @@ static void Load_Control_WriteProperty_Duty_Window(
ct_test(pTest, status == true); ct_test(pTest, status == true);
} }
static void Load_Control_WriteProperty_Start_Time_Wildcards( static void Load_Control_WriteProperty_Start_Time_Wildcards(Test *pTest,
Test * pTest,
int instance) int instance)
{ {
int len = 0; int len = 0;
@@ -1278,15 +1230,8 @@ static void Load_Control_WriteProperty_Start_Time_Wildcards(
} }
static void Load_Control_WriteProperty_Start_Time( static void Load_Control_WriteProperty_Start_Time(
Test * pTest, Test *pTest, int instance, uint16_t year, uint8_t month, uint8_t day,
int instance, uint8_t hour, uint8_t minute, uint8_t seconds, uint8_t hundredths)
uint16_t year,
uint8_t month,
uint8_t day,
uint8_t hour,
uint8_t minute,
uint8_t seconds,
uint8_t hundredths)
{ {
int len = 0; int len = 0;
bool status = false; bool status = false;
@@ -1316,8 +1261,7 @@ static void Load_Control_WriteProperty_Start_Time(
ct_test(pTest, status == true); ct_test(pTest, status == true);
} }
void testLoadControlStateMachine( void testLoadControlStateMachine(Test *pTest)
Test * pTest)
{ {
unsigned i = 0, j = 0; unsigned i = 0, j = 0;
uint8_t level = 0; uint8_t level = 0;
@@ -1456,8 +1400,7 @@ void testLoadControlStateMachine(
ct_test(pTest, level == 100); ct_test(pTest, level == 100);
} }
void testLoadControl( void testLoadControl(Test *pTest)
Test * pTest)
{ {
uint8_t apdu[MAX_APDU] = {0}; uint8_t apdu[MAX_APDU] = {0};
int len = 0; int len = 0;
@@ -1487,8 +1430,7 @@ void testLoadControl(
} }
#ifdef TEST_LOAD_CONTROL #ifdef TEST_LOAD_CONTROL
int main( int main(void)
void)
{ {
Test *pTest; Test *pTest;
bool rc; bool rc;

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